diff options
7 files changed, 48 insertions, 4 deletions
diff --git a/llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td b/llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td index a3d310cfe1c..af26375802a 100644 --- a/llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td +++ b/llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td @@ -88,6 +88,7 @@ def : GINodeEquiv<G_CTTZ, cttz>;  def : GINodeEquiv<G_CTLZ_ZERO_UNDEF, ctlz_zero_undef>;  def : GINodeEquiv<G_CTTZ_ZERO_UNDEF, cttz_zero_undef>;  def : GINodeEquiv<G_CTPOP, ctpop>; +def : GINodeEquiv<G_EXTRACT_VECTOR_ELT, vector_extract>;  // Broadly speaking G_LOAD is equivalent to ISD::LOAD but there are some  // complications that tablegen must take care of. For example, Predicates such diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp index 709965ba151..ab7d3a87975 100644 --- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp +++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp @@ -1330,7 +1330,22 @@ bool IRTranslator::translateExtractElement(const User &U,    }    unsigned Res = getOrCreateVReg(U);    unsigned Val = getOrCreateVReg(*U.getOperand(0)); -  unsigned Idx = getOrCreateVReg(*U.getOperand(1)); +  const auto &TLI = *MF->getSubtarget().getTargetLowering(); +  unsigned PreferredVecIdxWidth = TLI.getVectorIdxTy(*DL).getSizeInBits(); +  unsigned Idx = 0; +  if (auto *CI = dyn_cast<ConstantInt>(U.getOperand(1))) { +    if (CI->getBitWidth() != PreferredVecIdxWidth) { +      APInt NewIdx = CI->getValue().sextOrTrunc(PreferredVecIdxWidth); +      auto *NewIdxCI = ConstantInt::get(CI->getContext(), NewIdx); +      Idx = getOrCreateVReg(*NewIdxCI); +    } +  } +  if (!Idx) +    Idx = getOrCreateVReg(*U.getOperand(1)); +  if (MRI->getType(Idx).getSizeInBits() != PreferredVecIdxWidth) { +    const LLT &VecIdxTy = LLT::scalar(PreferredVecIdxWidth); +    Idx = MIRBuilder.buildSExtOrTrunc(VecIdxTy, Idx)->getOperand(0).getReg(); +  }    MIRBuilder.buildExtractVectorElement(Res, Val, Idx);    return true;  } diff --git a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp index ff2e61c03b4..c9ed97aa390 100644 --- a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp +++ b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp @@ -878,6 +878,12 @@ LegalizerHelper::widenScalar(MachineInstr &MI, unsigned TypeIdx, LLT WideTy) {      MIRBuilder.recordInsertion(&MI);      return Legalized;    } +  case TargetOpcode::G_EXTRACT_VECTOR_ELT: +    if (TypeIdx != 2) +      return UnableToLegalize; +    widenScalarSrc(MI, WideTy, 2, TargetOpcode::G_SEXT); +    MIRBuilder.recordInsertion(&MI); +    return Legalized;    }  } diff --git a/llvm/lib/Target/AArch64/AArch64LegalizerInfo.cpp b/llvm/lib/Target/AArch64/AArch64LegalizerInfo.cpp index 327c758a7f8..b3c2fbf2b15 100644 --- a/llvm/lib/Target/AArch64/AArch64LegalizerInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64LegalizerInfo.cpp @@ -385,6 +385,17 @@ AArch64LegalizerInfo::AArch64LegalizerInfo(const AArch64Subtarget &ST) {                           });    } +  getActionDefinitionsBuilder(G_EXTRACT_VECTOR_ELT) +      .unsupportedIf([=](const LegalityQuery &Query) { +        const LLT &EltTy = Query.Types[1].getElementType(); +        return Query.Types[0] != EltTy; +      }) +      .minScalar(2, s64) +      .legalIf([=](const LegalityQuery &Query) { +        const LLT &VecTy = Query.Types[1]; +        return VecTy == v4s32 || VecTy == v2s64; +      }); +    computeTables();    verify(*ST.getInstrInfo());  } diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/arm64-fallback.ll b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-fallback.ll index e1defd71958..da3aa3c1009 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/arm64-fallback.ll +++ b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-fallback.ll @@ -141,7 +141,7 @@ define fp128 @test_quad_dump() {    ret fp128 0xL00000000000000004000000000000000  } -; FALLBACK-WITH-REPORT-ERR: remark: <unknown>:0:0: unable to legalize instruction: %2:_(p0) = G_EXTRACT_VECTOR_ELT %0:_(<2 x p0>), %3:_(s32) (in function: vector_of_pointers_extractelement) +; FALLBACK-WITH-REPORT-ERR: remark: <unknown>:0:0: unable to legalize instruction: %2:_(p0) = G_EXTRACT_VECTOR_ELT %0:_(<2 x p0>), %3:_(s64) (in function: vector_of_pointers_extractelement)  ; FALLBACK-WITH-REPORT-ERR: warning: Instruction selection used fallback path for vector_of_pointers_extractelement  ; FALLBACK-WITH-REPORT-OUT-LABEL: vector_of_pointers_extractelement:  @var = global <2 x i16*> zeroinitializer diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll index a021eeda353..2997c5350eb 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll +++ b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll @@ -1530,12 +1530,23 @@ define i32 @test_extractelement(<2 x i32> %vec, i32 %idx) {  ; CHECK-LABEL: name: test_extractelement  ; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = COPY $d0  ; CHECK: [[IDX:%[0-9]+]]:_(s32) = COPY $w0 -; CHECK: [[RES:%[0-9]+]]:_(s32) = G_EXTRACT_VECTOR_ELT [[VEC]](<2 x s32>), [[IDX]](s32) +; CHECK: [[IDXEXT:%[0-9]+]]:_(s64) = G_SEXT [[IDX]] +; CHECK: [[RES:%[0-9]+]]:_(s32) = G_EXTRACT_VECTOR_ELT [[VEC]](<2 x s32>), [[IDXEXT]](s64)  ; CHECK: $w0 = COPY [[RES]](s32)    %res = extractelement <2 x i32> %vec, i32 %idx    ret i32 %res  } +define i32 @test_extractelement_const_idx(<2 x i32> %vec) { +; CHECK-LABEL: name: test_extractelement +; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = COPY $d0 +; CHECK: [[IDX:%[0-9]+]]:_(s64) = G_CONSTANT i64 1 +; CHECK: [[RES:%[0-9]+]]:_(s32) = G_EXTRACT_VECTOR_ELT [[VEC]](<2 x s32>), [[IDX]](s64) +; CHECK: $w0 = COPY [[RES]](s32) +  %res = extractelement <2 x i32> %vec, i32 1 +  ret i32 %res +} +  define i32 @test_singleelementvector(i32 %elt){  ; CHECK-LABEL: name: test_singleelementvector  ; CHECK: [[ELT:%[0-9]+]]:_(s32) = COPY $w0 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir b/llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir index f776ca6df31..ca059cf1544 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir @@ -295,7 +295,7 @@  # DEBUG:      .. type index coverage check SKIPPED: no rules defined  #  # DEBUG-NEXT: G_EXTRACT_VECTOR_ELT (opcode {{[0-9]+}}): 3 type indices -# DEBUG:      .. type index coverage check SKIPPED: no rules defined +# DEBUG:      .. type index coverage check SKIPPED: user-defined predicate detected  #  # DEBUG-NEXT: G_SHUFFLE_VECTOR (opcode {{[0-9]+}}): 3 type indices  # DEBUG:      .. type index coverage check SKIPPED: no rules defined  | 

