#include "llvm/Instructions.h"
#include "llvm/IntrinsicInst.h"
#include "llvm/Operator.h"
+#include "llvm/CodeGen/Analysis.h"
#include "llvm/CodeGen/FastISel.h"
#include "llvm/CodeGen/FunctionLoweringInfo.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
return true;
}
+bool
+FastISel::SelectExtractValue(const User *U) {
+ const ExtractValueInst *EVI = dyn_cast<ExtractValueInst>(U);
+ if (!U)
+ return false;
+
+ // Make sure we only try to handle extracts with a legal result.
+ EVT RealVT = TLI.getValueType(EVI->getType(), /*AllowUnknown=*/true);
+ if (!RealVT.isSimple())
+ return false;
+ MVT VT = RealVT.getSimpleVT();
+ if (!TLI.isTypeLegal(VT))
+ return false;
+
+ const Value *Op0 = EVI->getOperand(0);
+ const Type *AggTy = Op0->getType();
+
+ // Get the base result register.
+ unsigned ResultReg;
+ DenseMap<const Value *, unsigned>::iterator I = FuncInfo.ValueMap.find(Op0);
+ if (I != FuncInfo.ValueMap.end())
+ ResultReg = I->second;
+ else
+ ResultReg = FuncInfo.InitializeRegForValue(Op0);
+
+ // Get the actual result register, which is an offset from the base register.
+ unsigned VTIndex = ComputeLinearIndex(AggTy, EVI->idx_begin(), EVI->idx_end());
+
+ SmallVector<EVT, 4> AggValueVTs;
+ ComputeValueVTs(TLI, AggTy, AggValueVTs);
+
+ for (unsigned i = 0; i < VTIndex; i++)
+ ResultReg += TLI.getNumRegisters(FuncInfo.Fn->getContext(), AggValueVTs[i]);
+
+ UpdateValueMap(EVI, ResultReg);
+ return true;
+}
+
bool
FastISel::SelectOperator(const User *I, unsigned Opcode) {
switch (Opcode) {
return true;
}
+ case Instruction::ExtractValue:
+ return SelectExtractValue(I);
+
case Instruction::PHI:
llvm_unreachable("FastISel shouldn't visit PHI nodes!");
--- /dev/null
+; RUN: llc < %s -mtriple x86_64-apple-darwin11 -O0 | FileCheck %s
+
+%struct.x = type { i64, i64 }
+declare %struct.x @f()
+
+define void @test1(i64*) nounwind ssp {
+ %2 = tail call %struct.x @f() nounwind
+ %3 = extractvalue %struct.x %2, 0
+ %4 = add i64 %3, 10
+ store i64 %4, i64* %0
+ ret void
+; CHECK: test1:
+; CHECK: callq _f
+; CHECK-NEXT: addq $10, %rax
+}
+
+define void @test2(i64*) nounwind ssp {
+ %2 = tail call %struct.x @f() nounwind
+ %3 = extractvalue %struct.x %2, 1
+ %4 = add i64 %3, 10
+ store i64 %4, i64* %0
+ ret void
+; CHECK: test2:
+; CHECK: callq _f
+; CHECK-NEXT: addq $10, %rdx
+}