Revert " [LoongArch][ISel] Check the number of sign bits in `PatGprGpr_32` (#107432)"
[llvm-project.git] / llvm / test / CodeGen / X86 / callbr-asm-outputs.ll
blobaadbda1716ba785b3b49b357d2d78c0177e050e7
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=i686-- -verify-machineinstrs < %s | FileCheck %s
4 ; A test for asm-goto output
6 define i32 @test1(i32 %x) {
7 ; CHECK-LABEL: test1:
8 ; CHECK:       # %bb.0: # %entry
9 ; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %eax
10 ; CHECK-NEXT:    addl $4, %eax
11 ; CHECK-NEXT:    #APP
12 ; CHECK-NEXT:    xorl %eax, %eax
13 ; CHECK-NEXT:    jmp .LBB0_2
14 ; CHECK-NEXT:    #NO_APP
15 ; CHECK-NEXT:  # %bb.1: # %normal
16 ; CHECK-NEXT:    retl
17 ; CHECK-NEXT:  .LBB0_2: # Block address taken
18 ; CHECK-NEXT:    # %abnormal
19 ; CHECK-NEXT:    # Label of block must be emitted
20 ; CHECK-NEXT:    movl $1, %eax
21 ; CHECK-NEXT:    retl
22 entry:
23   %add = add nsw i32 %x, 4
24   %ret = callbr i32 asm "xorl $1, $0; jmp ${2:l}", "=r,r,!i"(i32 %add)
25           to label %normal [label %abnormal]
27 normal:
28   ret i32 %ret
30 abnormal:
31   ret i32 1
34 define i32 @test2(i32 %out1, i32 %out2) nounwind {
35 ; CHECK-LABEL: test2:
36 ; CHECK:       # %bb.0: # %entry
37 ; CHECK-NEXT:    pushl %edi
38 ; CHECK-NEXT:    pushl %esi
39 ; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %edi
40 ; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %esi
41 ; CHECK-NEXT:    cmpl %edi, %esi
42 ; CHECK-NEXT:    jge .LBB1_3
43 ; CHECK-NEXT:  # %bb.1: # %if.then
44 ; CHECK-NEXT:    #APP
45 ; CHECK-NEXT:    testl %esi, %esi
46 ; CHECK-NEXT:    testl %edi, %esi
47 ; CHECK-NEXT:    jne .LBB1_2
48 ; CHECK-NEXT:    #NO_APP
49 ; CHECK-NEXT:    jmp .LBB1_4
50 ; CHECK-NEXT:  .LBB1_2: # Block address taken
51 ; CHECK-NEXT:    # %if.then.label_true_crit_edge
52 ; CHECK-NEXT:    # Label of block must be emitted
53 ; CHECK-NEXT:    jmp .LBB1_9
54 ; CHECK-NEXT:  .LBB1_3: # %if.else
55 ; CHECK-NEXT:    #APP
56 ; CHECK-NEXT:    testl %esi, %edi
57 ; CHECK-NEXT:    testl %esi, %edi
58 ; CHECK-NEXT:    jne .LBB1_7
59 ; CHECK-NEXT:    #NO_APP
60 ; CHECK-NEXT:  .LBB1_4:
61 ; CHECK-NEXT:    movl %esi, %eax
62 ; CHECK-NEXT:    addl %edi, %eax
63 ; CHECK-NEXT:  .LBB1_5: # %return
64 ; CHECK-NEXT:    popl %esi
65 ; CHECK-NEXT:    popl %edi
66 ; CHECK-NEXT:    retl
67 ; CHECK-NEXT:  .LBB1_6: # Block address taken
68 ; CHECK-NEXT:    # %if.then.return_crit_edge
69 ; CHECK-NEXT:    # Label of block must be emitted
70 ; CHECK-NEXT:  .LBB1_7: # Block address taken
71 ; CHECK-NEXT:    # %if.else.return_crit_edge
72 ; CHECK-NEXT:    # Label of block must be emitted
73 ; CHECK-NEXT:    movl $-1, %eax
74 ; CHECK-NEXT:    jmp .LBB1_5
75 ; CHECK-NEXT:  .LBB1_8: # Block address taken
76 ; CHECK-NEXT:    # %if.else.label_true_crit_edge
77 ; CHECK-NEXT:    # Label of block must be emitted
78 ; CHECK-NEXT:  .LBB1_9: # %label_true
79 ; CHECK-NEXT:    movl $-2, %eax
80 ; CHECK-NEXT:    jmp .LBB1_5
81 entry:
82   %cmp = icmp slt i32 %out1, %out2
83   br i1 %cmp, label %if.then, label %if.else
85 if.then:                                          ; preds = %entry
86   %0 = callbr { i32, i32 } asm sideeffect "testl $0, $0; testl $1, $2; jne ${3:l}", "={si},={di},r,!i,!i,0,1"(i32 %out1, i32 %out1, i32 %out2)
87           to label %if.end [label %label_true, label %return]
89 if.else:                                          ; preds = %entry
90   %1 = callbr { i32, i32 } asm sideeffect "testl $0, $1; testl $2, $3; jne ${5:l}", "={si},={di},r,r,!i,!i,0,1"(i32 %out1, i32 %out2, i32 %out1, i32 %out2)
91           to label %if.end [label %label_true, label %return]
93 if.end:                                           ; preds = %if.else, %if.then
94   %.sink11 = phi { i32, i32 } [ %0, %if.then ], [ %1, %if.else ]
95   %asmresult3 = extractvalue { i32, i32 } %.sink11, 0
96   %asmresult4 = extractvalue { i32, i32 } %.sink11, 1
97   %add = add nsw i32 %asmresult4, %asmresult3
98   br label %return
100 label_true:                                       ; preds = %if.else, %if.then
101   br label %return
103 return:                                           ; preds = %if.then, %if.else, %label_true, %if.end
104   %retval.0 = phi i32 [ %add, %if.end ], [ -2, %label_true ], [ -1, %if.else ], [ -1, %if.then ]
105   ret i32 %retval.0
108 define i32 @test3(i1 %cmp) nounwind {
109 ; CHECK-LABEL: test3:
110 ; CHECK:       # %bb.0: # %entry
111 ; CHECK-NEXT:    pushl %edi
112 ; CHECK-NEXT:    pushl %esi
113 ; CHECK-NEXT:    testb $1, {{[0-9]+}}(%esp)
114 ; CHECK-NEXT:    je .LBB2_3
115 ; CHECK-NEXT:  # %bb.1: # %true
116 ; CHECK-NEXT:    #APP
117 ; CHECK-NEXT:    .short %esi
118 ; CHECK-NEXT:    .short %edi
119 ; CHECK-NEXT:    #NO_APP
120 ; CHECK-NEXT:  # %bb.2:
121 ; CHECK-NEXT:    movl %edi, %eax
122 ; CHECK-NEXT:    jmp .LBB2_4
123 ; CHECK-NEXT:  .LBB2_3: # %false
124 ; CHECK-NEXT:    #APP
125 ; CHECK-NEXT:    .short %eax
126 ; CHECK-NEXT:    .short %edx
127 ; CHECK-NEXT:    #NO_APP
128 ; CHECK-NEXT:    movl %edx, %eax
129 ; CHECK-NEXT:  .LBB2_4: # %asm.fallthrough
130 ; CHECK-NEXT:    popl %esi
131 ; CHECK-NEXT:    popl %edi
132 ; CHECK-NEXT:    retl
133 ; CHECK-NEXT:  .LBB2_5: # Block address taken
134 ; CHECK-NEXT:    # %true.indirect_crit_edge
135 ; CHECK-NEXT:    # Label of block must be emitted
136 ; CHECK-NEXT:  .LBB2_6: # Block address taken
137 ; CHECK-NEXT:    # %false.indirect_crit_edge
138 ; CHECK-NEXT:    # Label of block must be emitted
139 ; CHECK-NEXT:    movl $42, %eax
140 ; CHECK-NEXT:    jmp .LBB2_4
141 entry:
142   br i1 %cmp, label %true, label %false
144 true:
145   %0 = callbr { i32, i32 } asm sideeffect ".word $0, $1", "={si},={di},!i" () to label %asm.fallthrough [label %indirect]
147 false:
148   %1 = callbr { i32, i32 } asm sideeffect ".word $0, $1", "={ax},={dx},!i" () to label %asm.fallthrough [label %indirect]
150 asm.fallthrough:
151   %vals = phi { i32, i32 } [ %0, %true ], [ %1, %false ]
152   %v = extractvalue { i32, i32 } %vals, 1
153   ret i32 %v
155 indirect:
156   ret i32 42
159 ; Test 4 - asm-goto with output constraints.
160 define i32 @test4(i32 %out1, i32 %out2) {
161 ; CHECK-LABEL: test4:
162 ; CHECK:       # %bb.0: # %entry
163 ; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %eax
164 ; CHECK-NEXT:    #APP
165 ; CHECK-NEXT:    testl %eax, %eax
166 ; CHECK-NEXT:    testl %ecx, %eax
167 ; CHECK-NEXT:    jne .LBB3_5
168 ; CHECK-NEXT:    #NO_APP
169 ; CHECK-NEXT:  # %bb.1: # %asm.fallthrough
170 ; CHECK-NEXT:    #APP
171 ; CHECK-NEXT:    testl %eax, %ecx
172 ; CHECK-NEXT:    testl %eax, %ecx
173 ; CHECK-NEXT:    jne .LBB3_4
174 ; CHECK-NEXT:    #NO_APP
175 ; CHECK-NEXT:  # %bb.2: # %asm.fallthrough2
176 ; CHECK-NEXT:    addl %ecx, %eax
177 ; CHECK-NEXT:    retl
178 ; CHECK-NEXT:  .LBB3_3: # Block address taken
179 ; CHECK-NEXT:    # %entry.return_crit_edge
180 ; CHECK-NEXT:    # Label of block must be emitted
181 ; CHECK-NEXT:  .LBB3_4: # Block address taken
182 ; CHECK-NEXT:    # %asm.fallthrough.return_crit_edge
183 ; CHECK-NEXT:    # Label of block must be emitted
184 ; CHECK-NEXT:    movl $-1, %eax
185 ; CHECK-NEXT:    retl
186 ; CHECK-NEXT:  .LBB3_5: # Block address taken
187 ; CHECK-NEXT:    # %entry.label_true_crit_edge
188 ; CHECK-NEXT:    # Label of block must be emitted
189 ; CHECK-NEXT:  .LBB3_6: # Block address taken
190 ; CHECK-NEXT:    # %asm.fallthrough.label_true_crit_edge
191 ; CHECK-NEXT:    # Label of block must be emitted
192 ; CHECK-NEXT:    movl $-2, %eax
193 ; CHECK-NEXT:    retl
194 entry:
195   %0 = callbr { i32, i32 } asm sideeffect "testl $0, $0; testl $1, $2; jne ${3:l}", "=r,=r,r,!i,!i"(i32 %out1)
196           to label %asm.fallthrough [label %label_true, label %return]
198 asm.fallthrough:                                  ; preds = %entry
199   %asmresult = extractvalue { i32, i32 } %0, 0
200   %asmresult1 = extractvalue { i32, i32 } %0, 1
201   %1 = callbr { i32, i32 } asm sideeffect "testl $0, $1; testl $2, $3; jne ${5:l}", "=r,=r,r,r,!i,!i"(i32 %asmresult, i32 %asmresult1)
202           to label %asm.fallthrough2 [label %label_true, label %return]
204 asm.fallthrough2:                                 ; preds = %asm.fallthrough
205   %asmresult3 = extractvalue { i32, i32 } %1, 0
206   %asmresult4 = extractvalue { i32, i32 } %1, 1
207   %add = add nsw i32 %asmresult3, %asmresult4
208   br label %return
210 label_true:                                       ; preds = %asm.fallthrough, %entry
211   br label %return
213 return:                                           ; preds = %entry, %asm.fallthrough, %label_true, %asm.fallthrough2
214   %retval.0 = phi i32 [ %add, %asm.fallthrough2 ], [ -2, %label_true ], [ -1, %asm.fallthrough ], [ -1, %entry ]
215   ret i32 %retval.0
218 ; Test5 - test that we don't rely on a positional constraint. ie. +r in
219 ; GCCAsmStmt being turned into "={esp},0" since after D87279 they're turned
220 ; into "={esp},{esp}". This previously caused an ICE; this test is more so
221 ; about avoiding another ICE than what the actual output is.
222 define dso_local void @test5() {
223 ; CHECK-LABEL: test5:
224 ; CHECK:       # %bb.0:
225 ; CHECK-NEXT:    #APP
226 ; CHECK-NEXT:    #NO_APP
227 ; CHECK-NEXT:  # %bb.1:
228 ; CHECK-NEXT:    retl
229 ; CHECK-NEXT:  .LBB4_2: # Block address taken
230 ; CHECK-NEXT:    # %._crit_edge
231 ; CHECK-NEXT:    # Label of block must be emitted
232 ; CHECK-NEXT:    retl
233   %1 = call i32 @llvm.read_register.i32(metadata !3)
234   %2 = callbr i32 asm "", "={esp},!i,{esp}"(i32 %1)
235           to label %3 [label %4]
238   call void @llvm.write_register.i32(metadata !3, i32 %2)
239   br label %4
242   ret void
245 declare i32 @llvm.read_register.i32(metadata)
246 declare void @llvm.write_register.i32(metadata, i32)
247 !3 = !{!"esp"}