diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp index 869589b9aa78..817428bfb03a 100644 --- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp +++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp @@ -838,40 +838,42 @@ bool IRTranslator::translateLandingPad(const User &U, MIRBuilder.buildInstr(TargetOpcode::EH_LABEL) .addSym(MF->addLandingPad(&MBB)); + LLT Ty{*LP.getType(), *DL}; + unsigned Undef = MRI->createGenericVirtualRegister(Ty); + MIRBuilder.buildUndef(Undef); + SmallVector Tys; for (Type *Ty : cast(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 Regs; - SmallVector Offsets; - if (unsigned Reg = TLI.getExceptionPointerRegister(PersonalityFn)) { - MBB.addLiveIn(Reg); - unsigned VReg = MRI->createGenericVirtualRegister(Tys[0]); - MIRBuilder.buildCopy(VReg, Reg); - Regs.push_back(VReg); - Offsets.push_back(0); - } + unsigned ExceptionReg = TLI.getExceptionPointerRegister(PersonalityFn); + if (!ExceptionReg) + return false; - if (unsigned Reg = TLI.getExceptionSelectorRegister(PersonalityFn)) { - MBB.addLiveIn(Reg); + MBB.addLiveIn(ExceptionReg); + unsigned VReg = MRI->createGenericVirtualRegister(Tys[0]), + Tmp = MRI->createGenericVirtualRegister(Ty); + MIRBuilder.buildCopy(VReg, ExceptionReg); + MIRBuilder.buildInsert(Tmp, Undef, VReg, 0); - // N.b. the exception selector register always has pointer type and may not - // match the actual IR-level type in the landingpad so an extra cast is - // needed. - unsigned PtrVReg = MRI->createGenericVirtualRegister(Tys[0]); - MIRBuilder.buildCopy(PtrVReg, Reg); + unsigned SelectorReg = TLI.getExceptionSelectorRegister(PersonalityFn); + if (!SelectorReg) + return false; - unsigned VReg = MRI->createGenericVirtualRegister(Tys[1]); - MIRBuilder.buildInstr(TargetOpcode::G_PTRTOINT) - .addDef(VReg) - .addUse(PtrVReg); - Regs.push_back(VReg); - Offsets.push_back(Tys[0].getSizeInBits()); - } + MBB.addLiveIn(SelectorReg); - MIRBuilder.buildSequence(getOrCreateVReg(LP), Regs, Offsets); + // N.b. the exception selector register always has pointer type and may not + // match the actual IR-level type in the landingpad so an extra cast is + // needed. + unsigned PtrVReg = MRI->createGenericVirtualRegister(Tys[0]); + MIRBuilder.buildCopy(PtrVReg, SelectorReg); + + VReg = MRI->createGenericVirtualRegister(Tys[1]); + MIRBuilder.buildInstr(TargetOpcode::G_PTRTOINT).addDef(VReg).addUse(PtrVReg); + MIRBuilder.buildInsert(getOrCreateVReg(LP), Tmp, VReg, + Tys[0].getSizeInBits()); return true; } diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/irtranslator-exceptions.ll b/llvm/test/CodeGen/AArch64/GlobalISel/irtranslator-exceptions.ll index 75fab607cd73..ef4445111d7b 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/irtranslator-exceptions.ll +++ b/llvm/test/CodeGen/AArch64/GlobalISel/irtranslator-exceptions.ll @@ -19,10 +19,12 @@ declare i32 @llvm.eh.typeid.for(i8*) ; CHECK: [[BAD]] (landing-pad): ; CHECK: EH_LABEL +; CHECK: [[UNDEF:%[0-9]+]](s128) = IMPLICIT_DEF ; CHECK: [[PTR:%[0-9]+]](p0) = COPY %x0 +; CHECK: [[VAL_WITH_PTR:%[0-9]+]](s128) = G_INSERT [[UNDEF]], [[PTR]](p0), 0 ; CHECK: [[SEL_PTR:%[0-9]+]](p0) = COPY %x1 ; CHECK: [[SEL:%[0-9]+]](s32) = G_PTRTOINT [[SEL_PTR]] -; CHECK: [[PTR_SEL:%[0-9]+]](s128) = G_SEQUENCE [[PTR]](p0), 0, [[SEL]](s32), 64 +; CHECK: [[PTR_SEL:%[0-9]+]](s128) = G_INSERT [[VAL_WITH_PTR]], [[SEL]](s32), 64 ; CHECK: [[PTR_RET:%[0-9]+]](s64) = G_EXTRACT [[PTR_SEL]](s128), 0 ; CHECK: [[SEL_RET:%[0-9]+]](s32) = G_EXTRACT [[PTR_SEL]](s128), 64 ; CHECK: %x0 = COPY [[PTR_RET]] diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/legalize-exceptions.ll b/llvm/test/CodeGen/AArch64/GlobalISel/legalize-exceptions.ll index 001aea6409bb..23e7d5163e5a 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/legalize-exceptions.ll +++ b/llvm/test/CodeGen/AArch64/GlobalISel/legalize-exceptions.ll @@ -14,12 +14,20 @@ declare void @_Unwind_Resume(i8*) ; CHECK: [[LP]] (landing-pad): ; CHECK: EH_LABEL + ; CHECK: [[PTR:%[0-9]+]](p0) = COPY %x0 +; CHECK: [[STRUCT_PTR:%[0-9]+]](s64) = G_PTRTOINT [[PTR]](p0) + ; CHECK: [[SEL_PTR:%[0-9]+]](p0) = COPY %x1 ; CHECK: [[SEL:%[0-9]+]](s32) = G_PTRTOINT [[SEL_PTR]] -; CHECK-NOT: G_SEQUENCE -; CHECK-NOT: G_EXTRACT +; CHECK: [[STRUCT_SEL:%[0-9]+]](s64) = G_INSERT {{%[0-9]+}}, [[SEL]](s32), 0 + +; CHECK: [[STRUCT:%[0-9]+]](s128) = G_MERGE_VALUES [[STRUCT_PTR]](s64), [[STRUCT_SEL]] + +; CHECK: [[PTR:%[0-9]+]](p0) = G_EXTRACT [[STRUCT]](s128), 0 ; CHECK: G_STORE [[PTR]](p0), {{%[0-9]+}}(p0) + +; CHECK: [[SEL:%[0-9]+]](s32) = G_EXTRACT [[STRUCT]](s128), 64 ; CHECK: G_STORE [[SEL]](s32), {{%[0-9]+}}(p0) define void @bar() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {