Skip to content

Commit 8301034

Browse files
committed
[BranchFolding] Avoid moving blocks to fall through to an indirect target
1 parent ef5e65d commit 8301034

File tree

3 files changed

+101
-54
lines changed

3 files changed

+101
-54
lines changed

llvm/lib/CodeGen/BranchFolding.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1776,8 +1776,8 @@ bool BranchFolder::OptimizeBlock(MachineBasicBlock *MBB) {
17761776
// Okay, there is no really great place to put this block. If, however,
17771777
// the block before this one would be a fall-through if this block were
17781778
// removed, move this block to the end of the function. There is no real
1779-
// advantage in "falling through" to an EH block, so we don't want to
1780-
// perform this transformation for that case.
1779+
// advantage in "falling through" to an EH block or an other indirect
1780+
// target, so we don't want to perform this transformation for that case.
17811781
//
17821782
// Also, Windows EH introduced the possibility of an arbitrary number of
17831783
// successors to a given block. The analyzeBranch call does not consider
@@ -1787,10 +1787,14 @@ bool BranchFolder::OptimizeBlock(MachineBasicBlock *MBB) {
17871787
// below were performed for EH "FallThrough" blocks. Therefore, even if
17881788
// that appears not to be happening anymore, we should assume that it is
17891789
// possible and not remove the "!FallThrough()->isEHPad" condition below.
1790+
//
1791+
// Similarly, indirect branches like callbr/indirectbr also introduced the
1792+
// possibility of infinite rotation, as there are an arbitrary number of
1793+
// successors to a given block.
17901794
MachineBasicBlock *PrevTBB = nullptr, *PrevFBB = nullptr;
17911795
SmallVector<MachineOperand, 4> PrevCond;
1792-
if (FallThrough != MF.end() &&
1793-
!FallThrough->isEHPad() &&
1796+
if (FallThrough != MF.end() && !FallThrough->isEHPad() &&
1797+
!FallThrough->hasAddressTaken() &&
17941798
!TII->analyzeBranch(PrevBB, PrevTBB, PrevFBB, PrevCond, true) &&
17951799
PrevBB.isSuccessor(&*FallThrough)) {
17961800
MBB->moveAfter(&MF.back());

llvm/test/CodeGen/X86/callbr-asm-loop.ll

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,29 @@
11
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
22

3-
; RUN: llc -O0 -mtriple=i686-- < %s | FileCheck %s
3+
; RUN: llc -O1 -mtriple=i686-- < %s | FileCheck %s
44

55
; Test that causes multiple defs of %eax.
66
; FIXME: The testcase hangs with -O1/2/3 enabled.
77
define i32 @loop1() nounwind {
88
; CHECK-LABEL: loop1:
99
; CHECK: # %bb.0: # %entry
10-
; CHECK-NEXT: pushl %esi
11-
; CHECK-NEXT: jmp .LBB0_1
10+
; CHECK-NEXT: .p2align 4
1211
; CHECK-NEXT: .LBB0_1: # %tailrecurse
1312
; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
1413
; CHECK-NEXT: xorl %eax, %eax
1514
; CHECK-NEXT: movl $1, %edx
1615
; CHECK-NEXT: #APP
1716
; CHECK-NEXT: #NO_APP
18-
; CHECK-NEXT: movl %eax, %ecx
19-
; CHECK-NEXT: movl %edx, %esi
20-
; CHECK-NEXT: jmp .LBB0_3
17+
; CHECK-NEXT: jmp .LBB0_1
2118
; CHECK-NEXT: .LBB0_2: # Inline asm indirect target
22-
; CHECK-NEXT: # %tailrecurse.tailrecurse.backedge_crit_edge
19+
; CHECK-NEXT: # %tailrecurse.tailrecurse_crit_edge
2320
; CHECK-NEXT: # in Loop: Header=BB0_1 Depth=1
2421
; CHECK-NEXT: # Label of block must be emitted
25-
; CHECK-NEXT: .LBB0_3: # %tailrecurse.backedge
26-
; CHECK-NEXT: # in Loop: Header=BB0_1 Depth=1
2722
; CHECK-NEXT: jmp .LBB0_1
28-
; CHECK-NEXT: .LBB0_4: # Inline asm indirect target
23+
; CHECK-NEXT: .LBB0_3: # Inline asm indirect target
2924
; CHECK-NEXT: # %lab2.split
3025
; CHECK-NEXT: # Label of block must be emitted
3126
; CHECK-NEXT: movl %edx, %eax
32-
; CHECK-NEXT: popl %esi
3327
; CHECK-NEXT: retl
3428
entry:
3529
br label %tailrecurse

llvm/test/CodeGen/X86/catchpad-reuse.ll

Lines changed: 88 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
12
; RUN: llc < %s | FileCheck %s
23

34
; IR generated by the following C++ source with modifications to reuse the 'v'
@@ -15,46 +16,8 @@
1516
; }
1617
; return 0;
1718
; }
18-
19-
; CHECK: $cppxdata$main:
20-
; CHECK-NEXT: .long 429065506 # MagicNumber
21-
; CHECK-NEXT: .long 4 # MaxState
22-
; CHECK-NEXT: .long $stateUnwindMap$main@IMGREL # UnwindMap
23-
; CHECK-NEXT: .long 2 # NumTryBlocks
24-
; CHECK-NEXT: .long $tryMap$main@IMGREL # TryBlockMap
25-
; CHECK-NEXT: .long 5 # IPMapEntries
26-
; CHECK-NEXT: .long $ip2state$main@IMGREL # IPToStateXData
27-
; CHECK-NEXT: .long 32 # UnwindHelp
28-
; CHECK-NEXT: .long 0 # ESTypeList
29-
; CHECK-NEXT: .long 1 # EHFlags
30-
31-
; CHECK: $tryMap$main:
32-
; CHECK-NEXT: .long 1 # TryLow
33-
; CHECK-NEXT: .long 1 # TryHigh
34-
; CHECK-NEXT: .long 2 # CatchHigh
35-
; CHECK-NEXT: .long 1 # NumCatches
36-
; CHECK-NEXT: .long $handlerMap$0$main@IMGREL # HandlerArray
37-
; CHECK-NEXT: .long 0 # TryLow
38-
; CHECK-NEXT: .long 2 # TryHigh
39-
; CHECK-NEXT: .long 3 # CatchHigh
40-
; CHECK-NEXT: .long 1 # NumCatches
41-
; CHECK-NEXT: .long $handlerMap$1$main@IMGREL # HandlerArray
42-
43-
; CHECK: $handlerMap$0$main:
44-
; CHECK-NEXT: .long 0 # Adjectives
45-
; CHECK-NEXT: .long "??_R0H@8"@IMGREL # Type
46-
; CHECK-NEXT: .long [[v_offset:[0-9]+]] # CatchObjOffset
47-
; CHECK-NEXT: .long "?catch$2@?0?main@4HA"@IMGREL # Handler
48-
; CHECK-NEXT: .long {{.*}} # ParentFrameOffset
49-
50-
; CHECK: $handlerMap$1$main:
51-
; CHECK-NEXT: .long 0 # Adjectives
52-
; CHECK-NEXT: .long "??_R0H@8"@IMGREL # Type
53-
; CHECK-NEXT: .long [[v_offset]] # CatchObjOffset
54-
; CHECK-NEXT: .long "?catch$4@?0?main@4HA"@IMGREL # Handler
55-
; CHECK-NEXT: .long {{.*}} # ParentFrameOffset
56-
5719
; ModuleID = 't.cpp'
20+
5821
source_filename = "t.cpp"
5922
target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
6023
target triple = "x86_64-pc-windows-msvc19.0.24210"
@@ -68,6 +31,92 @@ $"\01??_R0H@8" = comdat any
6831

6932
; Function Attrs: norecurse uwtable
7033
define i32 @main() local_unnamed_addr personality ptr @__CxxFrameHandler3 {
34+
; CHECK-LABEL: main:
35+
; CHECK: # %bb.0: # %entry
36+
; CHECK-NEXT: pushq %rbp
37+
; CHECK-NEXT: .seh_pushreg %rbp
38+
; CHECK-NEXT: subq $48, %rsp
39+
; CHECK-NEXT: .seh_stackalloc 48
40+
; CHECK-NEXT: leaq {{[0-9]+}}(%rsp), %rbp
41+
; CHECK-NEXT: .seh_setframe %rbp, 48
42+
; CHECK-NEXT: .seh_endprologue
43+
; CHECK-NEXT: movq $-2, -16(%rbp)
44+
; CHECK-NEXT: .Ltmp0: # EH_LABEL
45+
; CHECK-NEXT: callq maythrow
46+
; CHECK-NEXT: nop
47+
; CHECK-NEXT: .Ltmp1: # EH_LABEL
48+
; CHECK-NEXT: .LBB0_1: # Block address taken
49+
; CHECK-NEXT: # %try.cont6
50+
; CHECK-NEXT: $ehgcr_0_1:
51+
; CHECK-NEXT: xorl %eax, %eax
52+
; CHECK-NEXT: .seh_startepilogue
53+
; CHECK-NEXT: addq $48, %rsp
54+
; CHECK-NEXT: popq %rbp
55+
; CHECK-NEXT: .seh_endepilogue
56+
; CHECK-NEXT: retq
57+
; CHECK-NEXT: .seh_handlerdata
58+
; CHECK-NEXT: .long $cppxdata$main@IMGREL
59+
; CHECK-NEXT: .text
60+
; CHECK-NEXT: .seh_endproc
61+
; CHECK-NEXT: .def "?catch$2@?0?main@4HA";
62+
; CHECK-NEXT: .scl 3;
63+
; CHECK-NEXT: .type 32;
64+
; CHECK-NEXT: .endef
65+
; CHECK-NEXT: .p2align 4
66+
; CHECK-NEXT: "?catch$2@?0?main@4HA":
67+
; CHECK-NEXT: .seh_proc "?catch$2@?0?main@4HA"
68+
; CHECK-NEXT: .seh_handler __CxxFrameHandler3, @unwind, @except
69+
; CHECK-NEXT: .LBB0_2: # %catch3
70+
; CHECK-NEXT: movq %rdx, {{[0-9]+}}(%rsp)
71+
; CHECK-NEXT: pushq %rbp
72+
; CHECK-NEXT: .seh_pushreg %rbp
73+
; CHECK-NEXT: subq $32, %rsp
74+
; CHECK-NEXT: .seh_stackalloc 32
75+
; CHECK-NEXT: leaq 48(%rdx), %rbp
76+
; CHECK-NEXT: .seh_endprologue
77+
; CHECK-NEXT: callq maythrow
78+
; CHECK-NEXT: leaq .LBB0_1(%rip), %rax
79+
; CHECK-NEXT: .seh_startepilogue
80+
; CHECK-NEXT: addq $32, %rsp
81+
; CHECK-NEXT: popq %rbp
82+
; CHECK-NEXT: .seh_endepilogue
83+
; CHECK-NEXT: retq # CATCHRET
84+
; CHECK-NEXT: .seh_handlerdata
85+
; CHECK-NEXT: .long $cppxdata$main@IMGREL
86+
; CHECK-NEXT: .text
87+
; CHECK-NEXT: .seh_endproc
88+
; CHECK-NEXT: .def "?catch$3@?0?main@4HA";
89+
; CHECK-NEXT: .scl 3;
90+
; CHECK-NEXT: .type 32;
91+
; CHECK-NEXT: .endef
92+
; CHECK-NEXT: .p2align 4
93+
; CHECK-NEXT: "?catch$3@?0?main@4HA":
94+
; CHECK-NEXT: .seh_proc "?catch$3@?0?main@4HA"
95+
; CHECK-NEXT: .seh_handler __CxxFrameHandler3, @unwind, @except
96+
; CHECK-NEXT: .LBB0_3: # %catch
97+
; CHECK-NEXT: movq %rdx, {{[0-9]+}}(%rsp)
98+
; CHECK-NEXT: pushq %rbp
99+
; CHECK-NEXT: .seh_pushreg %rbp
100+
; CHECK-NEXT: subq $32, %rsp
101+
; CHECK-NEXT: .seh_stackalloc 32
102+
; CHECK-NEXT: leaq 48(%rdx), %rbp
103+
; CHECK-NEXT: .seh_endprologue
104+
; CHECK-NEXT: .Ltmp2: # EH_LABEL
105+
; CHECK-NEXT: callq maythrow
106+
; CHECK-NEXT: nop
107+
; CHECK-NEXT: .Ltmp3: # EH_LABEL
108+
; CHECK-NEXT: # %bb.4: # %invoke.cont1
109+
; CHECK-NEXT: leaq .LBB0_1(%rip), %rax
110+
; CHECK-NEXT: .seh_startepilogue
111+
; CHECK-NEXT: addq $32, %rsp
112+
; CHECK-NEXT: popq %rbp
113+
; CHECK-NEXT: .seh_endepilogue
114+
; CHECK-NEXT: retq # CATCHRET
115+
; CHECK-NEXT: .Lfunc_end0:
116+
; CHECK-NEXT: .seh_handlerdata
117+
; CHECK-NEXT: .long $cppxdata$main@IMGREL
118+
; CHECK-NEXT: .text
119+
; CHECK-NEXT: .seh_endproc
71120
entry:
72121
%v = alloca i32, align 4
73122
invoke void @maythrow()

0 commit comments

Comments
 (0)