From: Jessica Paquette Date: Mon, 8 Nov 2021 22:43:12 +0000 (-0800) Subject: [GlobalISel] Ensure that translateInvoke adds all successors for inlineasm X-Git-Tag: upstream/15.0.7~26242 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=3eabcda81453854677faa70ae20f41e1a483cfe2;p=platform%2Fupstream%2Fllvm.git [GlobalISel] Ensure that translateInvoke adds all successors for inlineasm The existing code didn't add all necessary successors, which resulted in disjoint basic blocks. These would end up not being legalized which, in the best case, caused a fallback only in assert builds. Here's an example: https://godbolt.org/z/ndx15Enfj We also end up getting weird codegen here as well. Refactoring the code here allows us to correctly attach all successors. With this patch, the above example gives correct codegen at -O0 with and without asserts. Also autogen the testcase to show that we add all the successors now. Differential Revision: https://reviews.llvm.org/D113437 --- diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp index e4e26876857e..87cc60d51bc2 100644 --- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp +++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp @@ -2502,32 +2502,19 @@ bool IRTranslator::translateInvoke(const User &U, if (!isa(EHPadBB->getFirstNonPHI())) return false; - bool LowerInlineAsm = false; - if (I.isInlineAsm()) { - const InlineAsm *IA = cast(I.getCalledOperand()); - if (!IA->canThrow()) { - // Fast path without emitting EH_LABELs. - - if (!translateInlineAsm(I, MIRBuilder)) - return false; - - MachineBasicBlock *InvokeMBB = &MIRBuilder.getMBB(), - *ReturnMBB = &getMBB(*ReturnBB); - - // Update successor info. - addSuccessorWithProb(InvokeMBB, ReturnMBB, BranchProbability::getOne()); - - MIRBuilder.buildBr(*ReturnMBB); - return true; - } else { - LowerInlineAsm = true; - } - } + bool LowerInlineAsm = I.isInlineAsm(); + bool NeedEHLabel = true; + // If it can't throw then use a fast-path without emitting EH labels. + if (LowerInlineAsm) + NeedEHLabel = (cast(I.getCalledOperand()))->canThrow(); // Emit the actual call, bracketed by EH_LABELs so that the MF knows about // the region covered by the try. - MCSymbol *BeginSymbol = Context.createTempSymbol(); - MIRBuilder.buildInstr(TargetOpcode::EH_LABEL).addSym(BeginSymbol); + MCSymbol *BeginSymbol = nullptr; + if (NeedEHLabel) { + BeginSymbol = Context.createTempSymbol(); + MIRBuilder.buildInstr(TargetOpcode::EH_LABEL).addSym(BeginSymbol); + } if (LowerInlineAsm) { if (!translateInlineAsm(I, MIRBuilder)) @@ -2535,8 +2522,11 @@ bool IRTranslator::translateInvoke(const User &U, } else if (!translateCallBase(I, MIRBuilder)) return false; - MCSymbol *EndSymbol = Context.createTempSymbol(); - MIRBuilder.buildInstr(TargetOpcode::EH_LABEL).addSym(EndSymbol); + MCSymbol *EndSymbol = nullptr; + if (NeedEHLabel) { + EndSymbol = Context.createTempSymbol(); + MIRBuilder.buildInstr(TargetOpcode::EH_LABEL).addSym(EndSymbol); + } SmallVector, 1> UnwindDests; BranchProbabilityInfo *BPI = FuncInfo.BPI; @@ -2558,7 +2548,12 @@ bool IRTranslator::translateInvoke(const User &U, } InvokeMBB->normalizeSuccProbs(); - MF->addInvoke(&EHPadMBB, BeginSymbol, EndSymbol); + if (NeedEHLabel) { + assert(BeginSymbol && "Expected a begin symbol!"); + assert(EndSymbol && "Expected an end symbol!"); + MF->addInvoke(&EHPadMBB, BeginSymbol, EndSymbol); + } + MIRBuilder.buildBr(ReturnMBB); return true; } diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/irtranslator-unwind-inline-asm.ll b/llvm/test/CodeGen/AArch64/GlobalISel/irtranslator-unwind-inline-asm.ll index fdb0543c8cdd..5d1e78285bf7 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/irtranslator-unwind-inline-asm.ll +++ b/llvm/test/CodeGen/AArch64/GlobalISel/irtranslator-unwind-inline-asm.ll @@ -1,3 +1,4 @@ +; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py ; RUN: llc -O0 -global-isel -stop-after=irtranslator < %s | FileCheck %s target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128" @@ -6,19 +7,45 @@ target triple = "aarch64-unknown-linux-gnu" @.str.2 = private unnamed_addr constant [7 x i8] c"Boom!\0A\00", align 1 define dso_local void @trap() { + ; CHECK-LABEL: name: trap + ; CHECK: bb.1.entry: entry: unreachable } define dso_local void @test() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { + ; CHECK-LABEL: name: test + ; CHECK: bb.1.entry: + ; CHECK-NEXT: successors: %bb.2(0x40000000), %bb.3(0x40000000) + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[GV:%[0-9]+]]:_(p0) = G_GLOBAL_VALUE @.str.2 + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY [[GV]](p0) + ; CHECK-NEXT: EH_LABEL + ; CHECK-NEXT: INLINEASM &"bl trap", 1 /* sideeffect attdialect */ + ; CHECK-NEXT: EH_LABEL + ; CHECK-NEXT: G_BR %bb.2 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: bb.2.invoke.cont: + ; CHECK-NEXT: RET_ReallyLR + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: bb.3.lpad (landing-pad): + ; CHECK-NEXT: liveins: $x0, $x1 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: EH_LABEL + ; CHECK-NEXT: [[DEF:%[0-9]+]]:_(s128) = G_IMPLICIT_DEF + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(p0) = COPY $x0 + ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(p0) = COPY $x1 + ; CHECK-NEXT: [[PTRTOINT:%[0-9]+]]:_(s32) = G_PTRTOINT [[COPY2]](p0) + ; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp + ; CHECK-NEXT: $x0 = COPY [[COPY]](p0) + ; CHECK-NEXT: BL @printf, csr_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit $x0 + ; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp + ; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp + ; CHECK-NEXT: $x0 = COPY [[COPY1]](p0) + ; CHECK-NEXT: BL @_Unwind_Resume, csr_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit $x0 + ; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp entry: -; CHECK-LABEL: name: test -; CHECK: body: -; CHECK-NEXT: bb.1.entry -; CHECK: EH_LABEL -; CHECK-NEXT: INLINEASM -; CHECK-NEXT: EH_LABEL invoke void asm sideeffect unwind "bl trap", ""() to label %invoke.cont unwind label %lpad @@ -27,8 +54,6 @@ invoke.cont: ret void lpad: -; CHECK: bb.3.lpad -; CHECK: EH_LABEL %0 = landingpad { i8*, i32 } cleanup @@ -37,6 +62,40 @@ lpad: } +define void @test2() #0 personality i32 (...)* @__gcc_personality_v0 { + ; CHECK-LABEL: name: test2 + ; CHECK: bb.1 (%ir-block.0): + ; CHECK-NEXT: successors: %bb.2(0x40000000), %bb.3(0x40000000) + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[DEF:%[0-9]+]]:_(p0) = G_IMPLICIT_DEF + ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64common = COPY [[DEF]](p0) + ; CHECK-NEXT: INLINEASM &"", 1 /* sideeffect attdialect */, 1572873 /* reguse:GPR64common */, [[COPY]] + ; CHECK-NEXT: G_BR %bb.2 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: bb.2.a: + ; CHECK-NEXT: RET_ReallyLR + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: bb.3.b (landing-pad): + ; CHECK-NEXT: liveins: $x0, $x1 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: EH_LABEL + ; CHECK-NEXT: [[DEF1:%[0-9]+]]:_(s128) = G_IMPLICIT_DEF + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(p0) = COPY $x0 + ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(p0) = COPY $x1 + ; CHECK-NEXT: [[PTRTOINT:%[0-9]+]]:_(s32) = G_PTRTOINT [[COPY2]](p0) + ; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp + ; CHECK-NEXT: $x0 = COPY [[COPY1]](p0) + ; CHECK-NEXT: BL @_Unwind_Resume, csr_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit $x0 + ; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp + invoke void asm sideeffect "", "r"(i64* undef) to label %a unwind label %b +a: + ret void +b: + %landing_pad = landingpad { i8*, i32 } cleanup + resume { i8*, i32 } %landing_pad +} + +declare i32 @__gcc_personality_v0(...) declare dso_local i32 @__gxx_personality_v0(...) declare dso_local void @printf(i8*, ...)