Index: include/llvm/Target/GenericOpcodes.td =================================================================== --- include/llvm/Target/GenericOpcodes.td +++ include/llvm/Target/GenericOpcodes.td @@ -810,7 +810,8 @@ let hasSideEffects = 0; } -// Generic extractelement. +// Generic extractelement. If the return type is larger than the vector's scalar element, +// then the higher bits are undefined and the result is any_ext'd. def G_EXTRACT_VECTOR_ELT : GenericInstruction { let OutOperandList = (outs type0:$dst); let InOperandList = (ins type1:$src, type2:$idx); Index: lib/CodeGen/GlobalISel/MachineIRBuilder.cpp =================================================================== --- lib/CodeGen/GlobalISel/MachineIRBuilder.cpp +++ lib/CodeGen/GlobalISel/MachineIRBuilder.cpp @@ -976,8 +976,8 @@ DstOps[0].getLLTTy(*getMRI()).isPointer()) && "Invalid operand type"); assert(SrcOps[1].getLLTTy(*getMRI()).isScalar() && "Invalid operand type"); - assert(SrcOps[0].getLLTTy(*getMRI()).getElementType() == - DstOps[0].getLLTTy(*getMRI()) && + assert(SrcOps[0].getLLTTy(*getMRI()).getElementType().getSizeInBits() <= + DstOps[0].getLLTTy(*getMRI()).getSizeInBits() && "Type mismatch"); break; } Index: lib/CodeGen/MachineVerifier.cpp =================================================================== --- lib/CodeGen/MachineVerifier.cpp +++ lib/CodeGen/MachineVerifier.cpp @@ -1266,6 +1266,26 @@ break; } + case TargetOpcode::G_EXTRACT_VECTOR_ELT: { + LLT DstTy = MRI->getType(MI->getOperand(0).getReg()); + LLT SrcTy = MRI->getType(MI->getOperand(1).getReg()); + if (!SrcTy.isVector()) + report("Generic G_EXTRACT_VECTOR_ELT's source should be vector", MI); + if (!DstTy.isScalar() && !DstTy.isPointer()) + report("Generic G_EXTRACT_VECTOR_ELT's dst should be scalar/pointer", MI); + if (DstTy.isPointer() && DstTy != SrcTy.getElementType()) { + report("Generic G_EXTRACT_VECTOR_ELT's dst and src should match when " + "pointer", + MI); + } + if (DstTy.isScalar() && SrcTy.isVector() && + DstTy.getSizeInBits() < SrcTy.getElementType().getSizeInBits()) { + report("Generic G_EXTRACT_VECTOR_ELT's dst can't be smaller than src " + "element type", + MI); + } + break; + } case TargetOpcode::G_EXTRACT: { const MachineOperand &SrcOp = MI->getOperand(1); if (!SrcOp.isReg()) { Index: test/MachineVerifier/test_g_extract_vec_elt.mir =================================================================== --- /dev/null +++ test/MachineVerifier/test_g_extract_vec_elt.mir @@ -0,0 +1,33 @@ +# RUN: not llc -march=aarch64 -o /dev/null -run-pass=none -verify-machineinstrs %s 2>&1 | FileCheck %s +# REQUIRES: global-isel, aarch64-registered-target + +--- +name: test_extract +legalized: true +regBankSelected: false +selected: false +tracksRegLiveness: true +liveins: +body: | + bb.0: + + %0:_(<4 x s16>) = G_IMPLICIT_DEF + %1:_(s32) = G_IMPLICIT_DEF + %2:_(s32) = G_CONSTANT i32 0 + + ; CHECK: Generic G_EXTRACT_VECTOR_ELT's source should be vector + %3:_(s32) = G_EXTRACT_VECTOR_ELT %1, %2 + + ; CHECK: Generic G_EXTRACT_VECTOR_ELT's dst can't be smaller than src element type + %4:_(s8) = G_EXTRACT_VECTOR_ELT %0, %2 + + ; This should be okay. + %5:_(s32) = G_EXTRACT_VECTOR_ELT %0, %2 + + ; CHECK: Generic G_EXTRACT_VECTOR_ELT's dst should be scalar/pointer + %6:_(<4 x s8>) = G_EXTRACT_VECTOR_ELT %0, %2 + + %7:_(<4 x p0>) = G_IMPLICIT_DEF + ; CHECK: Generic G_EXTRACT_VECTOR_ELT's dst and src should match when pointer + %8:_(p1) = G_EXTRACT_VECTOR_ELT %7, %2 +... Index: unittests/CodeGen/GlobalISel/MachineIRBuilderTest.cpp =================================================================== --- unittests/CodeGen/GlobalISel/MachineIRBuilderTest.cpp +++ unittests/CodeGen/GlobalISel/MachineIRBuilderTest.cpp @@ -90,3 +90,18 @@ EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; } + +TEST_F(GISelMITest, ExtractVecEltAnyExt) { + if (!TM) + return; + + SmallVector Copies; + collectCopies(Copies, MF); + + LLT s32 = LLT::scalar(32); + LLT s16 = LLT::scalar(16); + auto MIB = B.buildExtractVectorElement(s32, B.buildUndef(LLT::vector(4, s16)), + B.buildConstant(s32, 0)); + + EXPECT_TRUE(MIB->getOpcode() == TargetOpcode::G_EXTRACT_VECTOR_ELT); +}