diff options
6 files changed, 37 insertions, 4 deletions
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h b/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h index 0a5c9418378..e8c0a1a42dd 100644 --- a/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h @@ -149,6 +149,8 @@ private: /// \pre \p U is a branch instruction. bool translateBr(const User &U); + bool translateExtractValue(const User &U); + /// Translate return (ret) instruction. /// The target needs to implement CallLowering::lowerReturn for /// this to succeed. @@ -266,7 +268,6 @@ private: bool translateExtractElement(const User &U) { return false; } bool translateInsertElement(const User &U) { return false; } bool translateShuffleVector(const User &U) { return false; } - bool translateExtractValue(const User &U) { return false; } bool translateInsertValue(const User &U) { return false; } bool translateLandingPad(const User &U) { return false; } diff --git a/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h b/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h index be7155717d3..30c4967d6e8 100644 --- a/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h @@ -225,7 +225,7 @@ public: /// /// \return a MachineInstrBuilder for the newly created instruction. MachineInstrBuilder buildExtract(LLT Ty, ArrayRef<unsigned> Results, - unsigned Src, ArrayRef<unsigned> Indexes); + unsigned Src, ArrayRef<uint64_t> Indexes); /// Build and insert \p Res<def> = G_SEQUENCE \p Ty \p Op0, \p Idx0... /// diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp index ac95b8262d9..ed0ce8d848b 100644 --- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp +++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp @@ -182,6 +182,27 @@ bool IRTranslator::translateStore(const User &U) { return true; } +bool IRTranslator::translateExtractValue(const User &U) { + const ExtractValueInst &EVI = cast<ExtractValueInst>(U); + const Value *Src = EVI.getAggregateOperand(); + Type *Int32Ty = Type::getInt32Ty(EVI.getContext()); + SmallVector<Value *, 1> Indices; + + // getIndexedOffsetInType is designed for GEPs, so the first index is the + // usual array element rather than looking into the actual aggregate. + Indices.push_back(ConstantInt::get(Int32Ty, 0)); + for (auto Idx : EVI.indices()) + Indices.push_back(ConstantInt::get(Int32Ty, Idx)); + + uint64_t Offset = 8 * DL->getIndexedOffsetInType(Src->getType(), Indices); + + unsigned Res = getOrCreateVReg(EVI); + MIRBuilder.buildExtract(LLT{*EVI.getType()}, Res, getOrCreateVReg(*Src), + Offset); + + return true; +} + bool IRTranslator::translateBitCast(const User &U) { if (LLT{*U.getOperand(0)->getType()} == LLT{*U.getType()}) { unsigned &Reg = ValToVReg[&U]; diff --git a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp index 92dbab05e03..0ee70999b08 100644 --- a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp +++ b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp @@ -143,7 +143,7 @@ MachineInstrBuilder MachineIRBuilder::buildAnyExtend(LLT Ty, unsigned Res, MachineInstrBuilder MachineIRBuilder::buildExtract(LLT Ty, ArrayRef<unsigned> Results, unsigned Src, - ArrayRef<unsigned> Indexes) { + ArrayRef<uint64_t> Indexes) { assert(Results.size() == Indexes.size() && "inconsistent number of regs"); MachineInstrBuilder MIB = buildInstr(TargetOpcode::G_EXTRACT, Ty); diff --git a/llvm/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp b/llvm/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp index d999fbe8892..6d2d1057a6b 100644 --- a/llvm/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp +++ b/llvm/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp @@ -51,7 +51,7 @@ MachineLegalizeHelper::LegalizeResult MachineLegalizeHelper::legalizeInstr( void MachineLegalizeHelper::extractParts(unsigned Reg, LLT Ty, int NumParts, SmallVectorImpl<unsigned> &VRegs) { unsigned Size = Ty.getSizeInBits(); - SmallVector<unsigned, 4> Indexes; + SmallVector<uint64_t, 4> Indexes; for (int i = 0; i < NumParts; ++i) { VRegs.push_back(MRI.createGenericVirtualRegister(Size)); Indexes.push_back(i * Size); diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll index 060bae20e45..ea0178271e3 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll +++ b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll @@ -682,3 +682,14 @@ define void @test_umul_overflow(i32 %lhs, i32 %rhs, { i32, i1 }* %addr) { store { i32, i1 } %res, { i32, i1 }* %addr ret void } + +; CHECK-LABEL: name: test_extractvalue +; CHECK: [[STRUCT:%[0-9]+]](128) = G_LOAD { s128, p0 } +; CHECK: [[RES:%[0-9]+]](32) = G_EXTRACT s32 [[STRUCT]], 64 +; CHECK: %w0 = COPY [[RES]] +%struct.nested = type {i8, { i8, i32 }, i32} +define i32 @test_extractvalue(%struct.nested* %addr) { + %struct = load %struct.nested, %struct.nested* %addr + %res = extractvalue %struct.nested %struct, 1, 1 + ret i32 %res +} |

