Repository: llvm/llvm-project
File: llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp (C++)

Code before:
    // (extract_vector (insert_vector InsertTuple, InsertValue, InsertIdx),
    // ExtractIdx)
    unsigned ExtractIdx = cast<ConstantInt>(Idx)->getZExtValue();
    Value *InsertTuple, *InsertIdx, *InsertValue;
    if (match(Vec, m_Intrinsic<Intrinsic::vector_insert>(m_Value(InsertTuple),
                                                         m_Value(InsertValue),
                                                         m_Value(InsertIdx))) &&
        InsertValue->getType() == ReturnType) {
      unsigned Index = cast<ConstantInt>(InsertIdx)->getZExtValue();
      // Case where we get the same index right after setting it.
      // extract.vector(insert.vector(InsertTuple, InsertValue, Idx), Idx) -->
      // InsertValue
      if (ExtractIdx == Index)
        return replaceInstUsesWith(CI, InsertValue);
      // If we are getting a different index than what was set in the
      // insert.vector intrinsic. We can just set the input tuple to the one up
      // in the chain. extract.vector(insert.vector(InsertTuple, InsertValue,
      // InsertIndex), ExtractIndex)
      // --> extract.vector(InsertTuple, ExtractIndex)
      else
        return replaceOperand(CI, 0, InsertTuple);
    }

    ConstantInt *ALMIdx;
    if (match(Vec, m_Intrinsic<Intrinsic::get_active_lane_mask>(
                       m_Zero(), m_ConstantInt(ALMIdx)))) {
      const auto &Attrs = II->getFunction()->getAttributes().getFnAttrs();
      unsigned VScaleMin = Attrs.getVScaleRangeMin();
      if (!ALMIdx->isNegative() &&
          ExtractIdx * VScaleMin >= ALMIdx->getZExtValue())
        return replaceInstUsesWith(CI,
                                   ConstantVector::getNullValue(ReturnType));
    }

    auto *DstTy = dyn_cast<VectorType>(ReturnType);
    auto *VecTy = dyn_cast<VectorType>(Vec->getType());

    if (DstTy && VecTy) {
      auto DstEltCnt = DstTy->getElementCount();
      auto VecEltCnt = VecTy->getElementCount();
      unsigned IdxN = cast<ConstantInt>(Idx)->getZExtValue();

      // Extracting the entirety of Vec is a nop.
      if (DstEltCnt == VecTy->getElementCount()) {
        replaceInstUsesWith(CI, Vec);
        return eraseInstFromFunction(CI);
      }

      // Only canonicalize to shufflevector if the destination vector and
      // Vec are fixed vectors.
      if (VecEltCnt.isScalable() || DstEltCnt.isScalable())

Review comment (suggestion):
I'm not sure if there is a canonicalisation of const arg cases like `get_active_lane_mask(3, 7)` -> `get_active_lane_mask(0, 4)` and so the start value should always be zero. I just wondered if we care about non-zero start values because in theory for args (3,7) we know only 4 lanes will be active.

Code after:
    // (extract_vector (insert_vector InsertTuple, InsertValue, InsertIdx),
    // ExtractIdx)
    unsigned ExtractIdx = cast<ConstantInt>(Idx)->getZExtValue();
    Value *InsertTuple, *InsertIdx, *InsertValue;
    if (match(Vec, m_Intrinsic<Intrinsic::vector_insert>(m_Value(InsertTuple),
                                                         m_Value(InsertValue),
                                                         m_Value(InsertIdx))) &&
        InsertValue->getType() == ReturnType) {
      unsigned Index = cast<ConstantInt>(InsertIdx)->getZExtValue();
      // Case where we get the same index right after setting it.
      // extract.vector(insert.vector(InsertTuple, InsertValue, Idx), Idx) -->
      // InsertValue
      if (ExtractIdx == Index)
        return replaceInstUsesWith(CI, InsertValue);
      // If we are getting a different index than what was set in the
      // insert.vector intrinsic. We can just set the input tuple to the one up
      // in the chain. extract.vector(insert.vector(InsertTuple, InsertValue,
      // InsertIndex), ExtractIndex)
      // --> extract.vector(InsertTuple, ExtractIndex)
      else
        return replaceOperand(CI, 0, InsertTuple);
    }

    ConstantInt *ALMUpperBound;
    if (match(Vec, m_Intrinsic<Intrinsic::get_active_lane_mask>(
                       m_Value(), m_ConstantInt(ALMUpperBound)))) {
      const auto &Attrs = II->getFunction()->getAttributes().getFnAttrs();
      unsigned VScaleMin = Attrs.getVScaleRangeMin();
      if (ExtractIdx * VScaleMin >= ALMUpperBound->getZExtValue())
        return replaceInstUsesWith(CI,
                                   ConstantVector::getNullValue(ReturnType));
    }

    auto *DstTy = dyn_cast<VectorType>(ReturnType);
    auto *VecTy = dyn_cast<VectorType>(Vec->getType());

    if (DstTy && VecTy) {
      auto DstEltCnt = DstTy->getElementCount();
      auto VecEltCnt = VecTy->getElementCount();
      unsigned IdxN = cast<ConstantInt>(Idx)->getZExtValue();

      // Extracting the entirety of Vec is a nop.
      if (DstEltCnt == VecTy->getElementCount()) {
        replaceInstUsesWith(CI, Vec);
        return eraseInstFromFunction(CI);
      }

      // Only canonicalize to shufflevector if the destination vector and
      // Vec are fixed vectors.
      if (VecEltCnt.isScalable() || DstEltCnt.isScalable())
        break;