GlobalISel: Use the correct types when translating landingpad instructions

There was a bug here where we were using p0 instead of s32 for the
selector type in the landingpad. Instead of hardcoding these types we
should get the types from the landingpad instruction directly.

Note that we replicate an assert from SDAG here to only support
two-valued landingpads.

llvm-svn: 292995
This commit is contained in:
Justin Bogner 2017-01-25 00:16:53 +00:00
parent d843cd55b5
commit a029531e10
3 changed files with 54 additions and 6 deletions

View File

@ -701,22 +701,26 @@ bool IRTranslator::translateLandingPad(const User &U,
MIRBuilder.buildInstr(TargetOpcode::EH_LABEL)
.addSym(MF->addLandingPad(&MBB));
SmallVector<LLT, 2> Tys;
for (Type *Ty : cast<StructType>(LP.getType())->elements())
Tys.push_back(LLT{*Ty, *DL});
assert(Tys.size() == 2 && "Only two-valued landingpads are supported");
// Mark exception register as live in.
SmallVector<unsigned, 2> Regs;
SmallVector<uint64_t, 2> Offsets;
LLT p0 = LLT::pointer(0, DL->getPointerSizeInBits());
if (unsigned Reg = TLI.getExceptionPointerRegister(PersonalityFn)) {
unsigned VReg = MRI->createGenericVirtualRegister(p0);
unsigned VReg = MRI->createGenericVirtualRegister(Tys[0]);
MIRBuilder.buildCopy(VReg, Reg);
Regs.push_back(VReg);
Offsets.push_back(0);
}
if (unsigned Reg = TLI.getExceptionSelectorRegister(PersonalityFn)) {
unsigned VReg = MRI->createGenericVirtualRegister(p0);
unsigned VReg = MRI->createGenericVirtualRegister(Tys[1]);
MIRBuilder.buildCopy(VReg, Reg);
Regs.push_back(VReg);
Offsets.push_back(p0.getSizeInBits());
Offsets.push_back(Tys[0].getSizeInBits());
}
MIRBuilder.buildSequence(getOrCreateVReg(LP), Regs, Offsets);

View File

@ -19,8 +19,8 @@ declare i32 @llvm.eh.typeid.for(i8*)
; CHECK: [[BAD]] (landing-pad):
; CHECK: EH_LABEL
; CHECK: [[PTR:%[0-9]+]](p0) = COPY %x0
; CHECK: [[SEL:%[0-9]+]](p0) = COPY %x1
; CHECK: [[PTR_SEL:%[0-9]+]](s128) = G_SEQUENCE [[PTR]](p0), 0, [[SEL]](p0), 64
; CHECK: [[SEL:%[0-9]+]](s32) = COPY %x1
; CHECK: [[PTR_SEL:%[0-9]+]](s128) = G_SEQUENCE [[PTR]](p0), 0, [[SEL]](s32), 64
; CHECK: [[PTR_RET:%[0-9]+]](s64), [[SEL_RET:%[0-9]+]](s32) = G_EXTRACT [[PTR_SEL]](s128), 0, 64
; CHECK: %x0 = COPY [[PTR_RET]]
; CHECK: %w1 = COPY [[SEL_RET]]

View File

@ -0,0 +1,44 @@
; RUN: llc -O0 -mtriple=aarch64-apple-ios -global-isel -stop-after=legalizer %s -o - | FileCheck %s
@_ZTIi = external global i8*
declare i32 @foo(i32)
declare i32 @__gxx_personality_v0(...)
declare i32 @llvm.eh.typeid.for(i8*)
declare void @_Unwind_Resume(i8*)
; CHECK: name: bar
; CHECK: body:
; CHECK-NEXT: bb.1 (%ir-block.0):
; CHECK: successors: %{{bb.[0-9]+.continue.*}}%[[LP:bb.[0-9]+.cleanup]]
; CHECK: [[LP]] (landing-pad):
; CHECK: EH_LABEL
; CHECK: [[PTR:%[0-9]+]](p0) = COPY %x0
; CHECK: [[SEL:%[0-9]+]](s32) = COPY %x1
; CHECK-NOT: G_SEQUENCE
; CHECK-NOT: G_EXTRACT
; CHECK: G_STORE [[PTR]](p0), {{%[0-9]+}}(p0)
; CHECK: G_STORE [[SEL]](s32), {{%[0-9]+}}(p0)
define void @bar() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
%exn.slot = alloca i8*
%ehselector.slot = alloca i32
%1 = invoke i32 @foo(i32 42) to label %continue unwind label %cleanup
cleanup:
%2 = landingpad { i8*, i32 } cleanup
%3 = extractvalue { i8*, i32 } %2, 0
store i8* %3, i8** %exn.slot, align 8
%4 = extractvalue { i8*, i32 } %2, 1
store i32 %4, i32* %ehselector.slot, align 4
br label %eh.resume
continue:
ret void
eh.resume:
%exn = load i8*, i8** %exn.slot, align 8
call void @_Unwind_Resume(i8* %exn)
unreachable
}