Skip to content

Commit 3eabcda

Browse files
author
Jessica Paquette
committed
[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 1bed03b commit 3eabcda

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
@@ -2502,41 +2502,31 @@ bool IRTranslator::translateInvoke(const User &U,
25022502
if (!isa<LandingPadInst>(EHPadBB->getFirstNonPHI()))
25032503
return false;
25042504

2505-
bool LowerInlineAsm = false;
2506-
if (I.isInlineAsm()) {
2507-
const InlineAsm *IA = cast<InlineAsm>(I.getCalledOperand());
2508-
if (!IA->canThrow()) {
2509-
// Fast path without emitting EH_LABELs.
2510-
2511-
if (!translateInlineAsm(I, MIRBuilder))
2512-
return false;
2513-
2514-
MachineBasicBlock *InvokeMBB = &MIRBuilder.getMBB(),
2515-
*ReturnMBB = &getMBB(*ReturnBB);
2516-
2517-
// Update successor info.
2518-
addSuccessorWithProb(InvokeMBB, ReturnMBB, BranchProbability::getOne());
2519-
2520-
MIRBuilder.buildBr(*ReturnMBB);
2521-
return true;
2522-
} else {
2523-
LowerInlineAsm = true;
2524-
}
2525-
}
2505+
bool LowerInlineAsm = I.isInlineAsm();
2506+
bool NeedEHLabel = true;
2507+
// If it can't throw then use a fast-path without emitting EH labels.
2508+
if (LowerInlineAsm)
2509+
NeedEHLabel = (cast<InlineAsm>(I.getCalledOperand()))->canThrow();
25262510

25272511
// Emit the actual call, bracketed by EH_LABELs so that the MF knows about
25282512
// the region covered by the try.
2529-
MCSymbol *BeginSymbol = Context.createTempSymbol();
2530-
MIRBuilder.buildInstr(TargetOpcode::EH_LABEL).addSym(BeginSymbol);
2513+
MCSymbol *BeginSymbol = nullptr;
2514+
if (NeedEHLabel) {
2515+
BeginSymbol = Context.createTempSymbol();
2516+
MIRBuilder.buildInstr(TargetOpcode::EH_LABEL).addSym(BeginSymbol);
2517+
}
25312518

25322519
if (LowerInlineAsm) {
25332520
if (!translateInlineAsm(I, MIRBuilder))
25342521
return false;
25352522
} else if (!translateCallBase(I, MIRBuilder))
25362523
return false;
25372524

2538-
MCSymbol *EndSymbol = Context.createTempSymbol();
2539-
MIRBuilder.buildInstr(TargetOpcode::EH_LABEL).addSym(EndSymbol);
2525+
MCSymbol *EndSymbol = nullptr;
2526+
if (NeedEHLabel) {
2527+
EndSymbol = Context.createTempSymbol();
2528+
MIRBuilder.buildInstr(TargetOpcode::EH_LABEL).addSym(EndSymbol);
2529+
}
25402530

25412531
SmallVector<std::pair<MachineBasicBlock *, BranchProbability>, 1> UnwindDests;
25422532
BranchProbabilityInfo *BPI = FuncInfo.BPI;
@@ -2558,7 +2548,12 @@ bool IRTranslator::translateInvoke(const User &U,
25582548
}
25592549
InvokeMBB->normalizeSuccProbs();
25602550

2561-
MF->addInvoke(&EHPadMBB, BeginSymbol, EndSymbol);
2551+
if (NeedEHLabel) {
2552+
assert(BeginSymbol && "Expected a begin symbol!");
2553+
assert(EndSymbol && "Expected an end symbol!");
2554+
MF->addInvoke(&EHPadMBB, BeginSymbol, EndSymbol);
2555+
}
2556+
25622557
MIRBuilder.buildBr(ReturnMBB);
25632558
return true;
25642559
}
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)