Skip to content

Commit 8df5b3d

Browse files
Jessica Paquetteahoppen
authored andcommitted
[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
1 parent 1bcbf02 commit 8df5b3d

File tree

2 files changed

+88
-34
lines changed

2 files changed

+88
-34
lines changed

llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp

Lines changed: 21 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2485,41 +2485,31 @@ bool IRTranslator::translateInvoke(const User &U,
24852485
if (!isa<LandingPadInst>(EHPadBB->getFirstNonPHI()))
24862486
return false;
24872487

2488-
bool LowerInlineAsm = false;
2489-
if (I.isInlineAsm()) {
2490-
const InlineAsm *IA = cast<InlineAsm>(I.getCalledOperand());
2491-
if (!IA->canThrow()) {
2492-
// Fast path without emitting EH_LABELs.
2493-
2494-
if (!translateInlineAsm(I, MIRBuilder))
2495-
return false;
2496-
2497-
MachineBasicBlock *InvokeMBB = &MIRBuilder.getMBB(),
2498-
*ReturnMBB = &getMBB(*ReturnBB);
2499-
2500-
// Update successor info.
2501-
addSuccessorWithProb(InvokeMBB, ReturnMBB, BranchProbability::getOne());
2502-
2503-
MIRBuilder.buildBr(*ReturnMBB);
2504-
return true;
2505-
} else {
2506-
LowerInlineAsm = true;
2507-
}
2508-
}
2488+
bool LowerInlineAsm = I.isInlineAsm();
2489+
bool NeedEHLabel = true;
2490+
// If it can't throw then use a fast-path without emitting EH labels.
2491+
if (LowerInlineAsm)
2492+
NeedEHLabel = (cast<InlineAsm>(I.getCalledOperand()))->canThrow();
25092493

25102494
// Emit the actual call, bracketed by EH_LABELs so that the MF knows about
25112495
// the region covered by the try.
2512-
MCSymbol *BeginSymbol = Context.createTempSymbol();
2513-
MIRBuilder.buildInstr(TargetOpcode::EH_LABEL).addSym(BeginSymbol);
2496+
MCSymbol *BeginSymbol = nullptr;
2497+
if (NeedEHLabel) {
2498+
BeginSymbol = Context.createTempSymbol();
2499+
MIRBuilder.buildInstr(TargetOpcode::EH_LABEL).addSym(BeginSymbol);
2500+
}
25142501

25152502
if (LowerInlineAsm) {
25162503
if (!translateInlineAsm(I, MIRBuilder))
25172504
return false;
25182505
} else if (!translateCallBase(I, MIRBuilder))
25192506
return false;
25202507

2521-
MCSymbol *EndSymbol = Context.createTempSymbol();
2522-
MIRBuilder.buildInstr(TargetOpcode::EH_LABEL).addSym(EndSymbol);
2508+
MCSymbol *EndSymbol = nullptr;
2509+
if (NeedEHLabel) {
2510+
EndSymbol = Context.createTempSymbol();
2511+
MIRBuilder.buildInstr(TargetOpcode::EH_LABEL).addSym(EndSymbol);
2512+
}
25232513

25242514
SmallVector<std::pair<MachineBasicBlock *, BranchProbability>, 1> UnwindDests;
25252515
BranchProbabilityInfo *BPI = FuncInfo.BPI;
@@ -2541,7 +2531,12 @@ bool IRTranslator::translateInvoke(const User &U,
25412531
}
25422532
InvokeMBB->normalizeSuccProbs();
25432533

2544-
MF->addInvoke(&EHPadMBB, BeginSymbol, EndSymbol);
2534+
if (NeedEHLabel) {
2535+
assert(BeginSymbol && "Expected a begin symbol!");
2536+
assert(EndSymbol && "Expected an end symbol!");
2537+
MF->addInvoke(&EHPadMBB, BeginSymbol, EndSymbol);
2538+
}
2539+
25452540
MIRBuilder.buildBr(ReturnMBB);
25462541
return true;
25472542
}
Lines changed: 67 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
12
; RUN: llc -O0 -global-isel -stop-after=irtranslator < %s | FileCheck %s
23

34
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"
67
@.str.2 = private unnamed_addr constant [7 x i8] c"Boom!\0A\00", align 1
78

89
define dso_local void @trap() {
10+
; CHECK-LABEL: name: trap
11+
; CHECK: bb.1.entry:
912
entry:
1013
unreachable
1114
}
1215

1316
define dso_local void @test() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
17+
; CHECK-LABEL: name: test
18+
; CHECK: bb.1.entry:
19+
; CHECK-NEXT: successors: %bb.2(0x40000000), %bb.3(0x40000000)
20+
; CHECK-NEXT: {{ $}}
21+
; CHECK-NEXT: [[GV:%[0-9]+]]:_(p0) = G_GLOBAL_VALUE @.str.2
22+
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY [[GV]](p0)
23+
; CHECK-NEXT: EH_LABEL <mcsymbol >
24+
; CHECK-NEXT: INLINEASM &"bl trap", 1 /* sideeffect attdialect */
25+
; CHECK-NEXT: EH_LABEL <mcsymbol >
26+
; CHECK-NEXT: G_BR %bb.2
27+
; CHECK-NEXT: {{ $}}
28+
; CHECK-NEXT: bb.2.invoke.cont:
29+
; CHECK-NEXT: RET_ReallyLR
30+
; CHECK-NEXT: {{ $}}
31+
; CHECK-NEXT: bb.3.lpad (landing-pad):
32+
; CHECK-NEXT: liveins: $x0, $x1
33+
; CHECK-NEXT: {{ $}}
34+
; CHECK-NEXT: EH_LABEL <mcsymbol >
35+
; CHECK-NEXT: [[DEF:%[0-9]+]]:_(s128) = G_IMPLICIT_DEF
36+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(p0) = COPY $x0
37+
; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(p0) = COPY $x1
38+
; CHECK-NEXT: [[PTRTOINT:%[0-9]+]]:_(s32) = G_PTRTOINT [[COPY2]](p0)
39+
; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp
40+
; CHECK-NEXT: $x0 = COPY [[COPY]](p0)
41+
; CHECK-NEXT: BL @printf, csr_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit $x0
42+
; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp
43+
; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp
44+
; CHECK-NEXT: $x0 = COPY [[COPY1]](p0)
45+
; CHECK-NEXT: BL @_Unwind_Resume, csr_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit $x0
46+
; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp
1447
entry:
1548

16-
; CHECK-LABEL: name: test
17-
; CHECK: body:
18-
; CHECK-NEXT: bb.1.entry
19-
; CHECK: EH_LABEL
20-
; CHECK-NEXT: INLINEASM
21-
; CHECK-NEXT: EH_LABEL
2249

2350
invoke void asm sideeffect unwind "bl trap", ""()
2451
to label %invoke.cont unwind label %lpad
@@ -27,8 +54,6 @@ invoke.cont:
2754
ret void
2855

2956
lpad:
30-
; CHECK: bb.3.lpad
31-
; CHECK: EH_LABEL
3257

3358
%0 = landingpad { i8*, i32 }
3459
cleanup
@@ -37,6 +62,40 @@ lpad:
3762

3863
}
3964

65+
define void @test2() #0 personality i32 (...)* @__gcc_personality_v0 {
66+
; CHECK-LABEL: name: test2
67+
; CHECK: bb.1 (%ir-block.0):
68+
; CHECK-NEXT: successors: %bb.2(0x40000000), %bb.3(0x40000000)
69+
; CHECK-NEXT: {{ $}}
70+
; CHECK-NEXT: [[DEF:%[0-9]+]]:_(p0) = G_IMPLICIT_DEF
71+
; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64common = COPY [[DEF]](p0)
72+
; CHECK-NEXT: INLINEASM &"", 1 /* sideeffect attdialect */, 1572873 /* reguse:GPR64common */, [[COPY]]
73+
; CHECK-NEXT: G_BR %bb.2
74+
; CHECK-NEXT: {{ $}}
75+
; CHECK-NEXT: bb.2.a:
76+
; CHECK-NEXT: RET_ReallyLR
77+
; CHECK-NEXT: {{ $}}
78+
; CHECK-NEXT: bb.3.b (landing-pad):
79+
; CHECK-NEXT: liveins: $x0, $x1
80+
; CHECK-NEXT: {{ $}}
81+
; CHECK-NEXT: EH_LABEL <mcsymbol >
82+
; CHECK-NEXT: [[DEF1:%[0-9]+]]:_(s128) = G_IMPLICIT_DEF
83+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(p0) = COPY $x0
84+
; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(p0) = COPY $x1
85+
; CHECK-NEXT: [[PTRTOINT:%[0-9]+]]:_(s32) = G_PTRTOINT [[COPY2]](p0)
86+
; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp
87+
; CHECK-NEXT: $x0 = COPY [[COPY1]](p0)
88+
; CHECK-NEXT: BL @_Unwind_Resume, csr_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit $x0
89+
; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp
90+
invoke void asm sideeffect "", "r"(i64* undef) to label %a unwind label %b
91+
a:
92+
ret void
93+
b:
94+
%landing_pad = landingpad { i8*, i32 } cleanup
95+
resume { i8*, i32 } %landing_pad
96+
}
97+
98+
declare i32 @__gcc_personality_v0(...)
4099
declare dso_local i32 @__gxx_personality_v0(...)
41100

42101
declare dso_local void @printf(i8*, ...)

0 commit comments

Comments
 (0)