From: Tim Northover Date: Tue, 31 Jan 2017 18:36:11 +0000 (+0000) Subject: GlobalISel: merge invoke and call translation paths. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a90703d224a67b33600aba90c91ec95603103c07;p=llvm GlobalISel: merge invoke and call translation paths. Well, sort of. But the lower-level code that invoke used to be using completely botched the handling of varargs functions, which hopefully won't be possible if they're using the same code. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@293670 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/CodeGen/GlobalISel/CallLowering.h b/include/llvm/CodeGen/GlobalISel/CallLowering.h index 8eec32cece2..41bba8a4750 100644 --- a/include/llvm/CodeGen/GlobalISel/CallLowering.h +++ b/include/llvm/CodeGen/GlobalISel/CallLowering.h @@ -169,6 +169,9 @@ public: /// This hook must be implemented to lower the given call instruction, /// including argument and return value marshalling. /// + /// \p CI is either a CallInst or InvokeInst reference (other instantiations + /// will fail at link time). + /// /// \p ResReg is a register where the call's return value should be stored (or /// 0 if there is no return value). /// @@ -181,9 +184,10 @@ public: /// range of an immediate jump. /// /// \return true if the lowering succeeded, false otherwise. - virtual bool lowerCall(MachineIRBuilder &MIRBuilder, const CallInst &CI, - unsigned ResReg, ArrayRef ArgRegs, - std::function GetCalleeReg) const; + template + bool lowerCall(MachineIRBuilder &MIRBuilder, const CallInstTy &CI, + unsigned ResReg, ArrayRef ArgRegs, + std::function GetCalleeReg) const; }; } // End namespace llvm. diff --git a/lib/CodeGen/GlobalISel/CallLowering.cpp b/lib/CodeGen/GlobalISel/CallLowering.cpp index 33e70856c95..2d6f7d23e3b 100644 --- a/lib/CodeGen/GlobalISel/CallLowering.cpp +++ b/lib/CodeGen/GlobalISel/CallLowering.cpp @@ -23,8 +23,9 @@ using namespace llvm; +template bool CallLowering::lowerCall( - MachineIRBuilder &MIRBuilder, const CallInst &CI, unsigned ResReg, + MachineIRBuilder &MIRBuilder, const CallInstTy &CI, unsigned ResReg, ArrayRef ArgRegs, std::function GetCalleeReg) const { auto &DL = CI.getParent()->getParent()->getParent()->getDataLayout(); @@ -55,6 +56,16 @@ bool CallLowering::lowerCall( return lowerCall(MIRBuilder, Callee, OrigRet, OrigArgs); } +template bool +CallLowering::lowerCall(MachineIRBuilder &MIRBuilder, const CallInst &CI, + unsigned ResReg, ArrayRef ArgRegs, + std::function GetCalleeReg) const; + +template bool +CallLowering::lowerCall(MachineIRBuilder &MIRBuilder, const InvokeInst &CI, + unsigned ResReg, ArrayRef ArgRegs, + std::function GetCalleeReg) const; + template void CallLowering::setArgFlags(CallLowering::ArgInfo &Arg, unsigned OpIdx, const DataLayout &DL, diff --git a/lib/CodeGen/GlobalISel/IRTranslator.cpp b/lib/CodeGen/GlobalISel/IRTranslator.cpp index 0f66bd9d171..51613ab81f6 100644 --- a/lib/CodeGen/GlobalISel/IRTranslator.cpp +++ b/lib/CodeGen/GlobalISel/IRTranslator.cpp @@ -733,17 +733,12 @@ bool IRTranslator::translateInvoke(const User &U, MIRBuilder.buildInstr(TargetOpcode::EH_LABEL).addSym(BeginSymbol); unsigned Res = I.getType()->isVoidTy() ? 0 : getOrCreateVReg(I); - SmallVector Args; + SmallVector Args; for (auto &Arg: I.arg_operands()) - Args.emplace_back(getOrCreateVReg(*Arg), Arg->getType()); + Args.push_back(getOrCreateVReg(*Arg)); - auto CalleeMO = - Fn ? MachineOperand::CreateGA(Fn, 0) - : MachineOperand::CreateReg(getOrCreateVReg(*Callee), false); - - if (!CLI->lowerCall(MIRBuilder, CalleeMO, - CallLowering::ArgInfo(Res, I.getType()), Args)) - return false; + CLI->lowerCall(MIRBuilder, I, Res, Args, + [&]() { return getOrCreateVReg(*I.getCalledValue()); }); MCSymbol *EndSymbol = Context.createTempSymbol(); MIRBuilder.buildInstr(TargetOpcode::EH_LABEL).addSym(EndSymbol); diff --git a/test/CodeGen/AArch64/GlobalISel/irtranslator-exceptions.ll b/test/CodeGen/AArch64/GlobalISel/irtranslator-exceptions.ll index 412f70e17b2..9cb3923fd2a 100644 --- a/test/CodeGen/AArch64/GlobalISel/irtranslator-exceptions.ll +++ b/test/CodeGen/AArch64/GlobalISel/irtranslator-exceptions.ll @@ -57,3 +57,34 @@ broken: continue: ret void } + +; CHECK-LABEL: name: test_invoke_varargs + +; CHECK: [[NULL:%[0-9]+]](p0) = G_CONSTANT i64 0 +; CHECK: [[ANSWER:%[0-9]+]](s32) = G_CONSTANT i32 42 +; CHECK: [[ONE:%[0-9]+]](s32) = G_FCONSTANT float 1.0 + +; CHECK: %x0 = COPY [[NULL]] + +; CHECK: [[SP:%[0-9]+]](p0) = COPY %sp +; CHECK: [[OFFSET:%[0-9]+]](s64) = G_CONSTANT i64 0 +; CHECK: [[SLOT:%[0-9]+]](p0) = G_GEP [[SP]], [[OFFSET]](s64) +; CHECK: G_STORE [[ANSWER]](s32), [[SLOT]] + +; CHECK: [[SP:%[0-9]+]](p0) = COPY %sp +; CHECK: [[OFFSET:%[0-9]+]](s64) = G_CONSTANT i64 8 +; CHECK: [[SLOT:%[0-9]+]](p0) = G_GEP [[SP]], [[OFFSET]](s64) +; CHECK: G_STORE [[ONE]](s32), [[SLOT]] + +; CHECK: BL @printf +declare void @printf(i8*, ...) +define void @test_invoke_varargs() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { + invoke void(i8*, ...) @printf(i8* null, i32 42, float 1.0) to label %continue unwind label %broken + +broken: + landingpad { i8*, i32 } catch i8* bitcast(i8** @_ZTIi to i8*) + ret void + +continue: + ret void +}