xref: /llvm-project/llvm/test/CodeGen/X86/callbr-asm-branch-folding.ll (revision 189900eb149bb55ae3787346f57c1ccbdc50fb3c)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu | FileCheck %s
3
4; This test hung in the BranchFolding pass during asm-goto bring up
5
6@e = dso_local global i32 0
7@j = dso_local global i32 0
8
9define dso_local void @n(ptr %o, i32 %p, i32 %u) nounwind {
10; CHECK-LABEL: n:
11; CHECK:       # %bb.0: # %entry
12; CHECK-NEXT:    pushq %rbp
13; CHECK-NEXT:    pushq %r15
14; CHECK-NEXT:    pushq %r14
15; CHECK-NEXT:    pushq %r13
16; CHECK-NEXT:    pushq %r12
17; CHECK-NEXT:    pushq %rbx
18; CHECK-NEXT:    pushq %rax
19; CHECK-NEXT:    movl %edx, %ebp
20; CHECK-NEXT:    movl %esi, %r12d
21; CHECK-NEXT:    movq %rdi, %rbx
22; CHECK-NEXT:    callq c
23; CHECK-NEXT:    movl %eax, %r14d
24; CHECK-NEXT:    movq %rbx, %rdi
25; CHECK-NEXT:    callq l
26; CHECK-NEXT:    testl %eax, %eax
27; CHECK-NEXT:    jne .LBB0_9
28; CHECK-NEXT:  # %bb.1: # %if.end
29; CHECK-NEXT:    cmpl $0, e(%rip)
30; CHECK-NEXT:    # implicit-def: $r15d
31; CHECK-NEXT:    # implicit-def: $r13d
32; CHECK-NEXT:    je .LBB0_4
33; CHECK-NEXT:  # %bb.2: # %if.then4
34; CHECK-NEXT:    movslq %r12d, %rdi
35; CHECK-NEXT:    callq m
36; CHECK-NEXT:    # implicit-def: $r15d
37; CHECK-NEXT:    # implicit-def: $r12d
38; CHECK-NEXT:  .LBB0_3: # %r
39; CHECK-NEXT:    callq c
40; CHECK-NEXT:    movl %r12d, %r13d
41; CHECK-NEXT:  .LBB0_4: # %if.end8
42; CHECK-NEXT:    movl %r15d, %edi
43; CHECK-NEXT:    callq i
44; CHECK-NEXT:    movl %eax, %r12d
45; CHECK-NEXT:    orl %r13d, %r12d
46; CHECK-NEXT:    andl $4, %r15d
47; CHECK-NEXT:    testl %r14d, %r14d
48; CHECK-NEXT:    jne .LBB0_3
49; CHECK-NEXT:  # %bb.5: # %if.end12
50; CHECK-NEXT:    testl %r12d, %r12d
51; CHECK-NEXT:    je .LBB0_8
52; CHECK-NEXT:  # %bb.6: # %if.then14
53; CHECK-NEXT:    #APP
54; CHECK-NEXT:    #NO_APP
55; CHECK-NEXT:    jmp .LBB0_9
56; CHECK-NEXT:  .LBB0_7: # Block address taken
57; CHECK-NEXT:    # %if.then20.critedge
58; CHECK-NEXT:    # Label of block must be emitted
59; CHECK-NEXT:    movl j(%rip), %edi
60; CHECK-NEXT:    movslq %ebp, %rcx
61; CHECK-NEXT:    movl $1, %esi
62; CHECK-NEXT:    movq %rbx, %rdx
63; CHECK-NEXT:    addq $8, %rsp
64; CHECK-NEXT:    popq %rbx
65; CHECK-NEXT:    popq %r12
66; CHECK-NEXT:    popq %r13
67; CHECK-NEXT:    popq %r14
68; CHECK-NEXT:    popq %r15
69; CHECK-NEXT:    popq %rbp
70; CHECK-NEXT:    jmp k # TAILCALL
71; CHECK-NEXT:  .LBB0_8: # %if.else
72; CHECK-NEXT:    incq 0
73; CHECK-NEXT:  .LBB0_9: # %cleanup
74; CHECK-NEXT:    addq $8, %rsp
75; CHECK-NEXT:    popq %rbx
76; CHECK-NEXT:    popq %r12
77; CHECK-NEXT:    popq %r13
78; CHECK-NEXT:    popq %r14
79; CHECK-NEXT:    popq %r15
80; CHECK-NEXT:    popq %rbp
81; CHECK-NEXT:    retq
82entry:
83  %call = tail call i32 @c()
84  %call1 = tail call i32 @l(ptr %o)
85  %tobool = icmp eq i32 %call1, 0
86  br i1 %tobool, label %if.end, label %cleanup
87
88if.end:                                           ; preds = %entry
89  %0 = load i32, ptr @e
90  %tobool3 = icmp eq i32 %0, 0
91  br i1 %tobool3, label %if.end8, label %if.then4, !prof !0
92
93if.then4:                                         ; preds = %if.end
94  %conv5 = sext i32 %p to i64
95  %call6 = tail call i32 @m(i64 %conv5)
96  br label %r
97
98r:                                                ; preds = %if.end8, %if.then4
99  %flags.0 = phi i32 [ undef, %if.then4 ], [ %and, %if.end8 ]
100  %major.0 = phi i32 [ undef, %if.then4 ], [ %or, %if.end8 ]
101  %call7 = tail call i32 @c()
102  br label %if.end8
103
104if.end8:                                          ; preds = %r, %if.end
105  %flags.1 = phi i32 [ %flags.0, %r ], [ undef, %if.end ]
106  %major.1 = phi i32 [ %major.0, %r ], [ undef, %if.end ]
107  %call9 = tail call i32 @i(i32 %flags.1)
108  %or = or i32 %call9, %major.1
109  %and = and i32 %flags.1, 4
110  %tobool10 = icmp eq i32 %call, 0
111  br i1 %tobool10, label %if.end12, label %r
112
113if.end12:                                         ; preds = %if.end8
114  %tobool13 = icmp eq i32 %or, 0
115  br i1 %tobool13, label %if.else, label %if.then14
116
117if.then14:                                        ; preds = %if.end12
118  callbr void asm sideeffect "", "!i,~{dirflag},~{fpsr},~{flags}"()
119          to label %cleanup [label %if.then20.critedge]
120
121if.then20.critedge:                               ; preds = %if.then14
122  %1 = load i32, ptr @j
123  %conv21 = sext i32 %u to i64
124  %call22 = tail call i32 @k(i32 %1, i64 1, ptr %o, i64 %conv21)
125  br label %cleanup
126
127if.else:                                          ; preds = %if.end12
128  %2 = load i64, ptr null
129  %inc = add i64 %2, 1
130  store i64 %inc, ptr null
131  br label %cleanup
132
133cleanup:                                          ; preds = %if.else, %if.then20.critedge, %if.then14, %entry
134  ret void
135}
136
137declare dso_local i32 @c()
138
139declare dso_local i32 @l(ptr)
140
141declare dso_local i32 @m(i64)
142
143declare dso_local i32 @i(i32)
144
145declare dso_local i32 @k(i32, i64, ptr, i64)
146
147!0 = !{!"branch_weights", i32 2000, i32 1}
148