1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -mtriple=i686-- -verify-machineinstrs < %s | FileCheck %s
3
4; A test for asm-goto output
5
6define 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 .Ltmp0
14; CHECK-NEXT:    #NO_APP
15; CHECK-NEXT:  # %bb.1: # %normal
16; CHECK-NEXT:    retl
17; CHECK-NEXT:  .Ltmp0: # Block address taken
18; CHECK-NEXT:  .LBB0_2: # %abnormal
19; CHECK-NEXT:    movl $1, %eax
20; CHECK-NEXT:    retl
21entry:
22  %add = add nsw i32 %x, 4
23  %ret = callbr i32 asm "xorl $1, $0; jmp ${2:l}", "=r,r,X,~{dirflag},~{fpsr},~{flags}"(i32 %add, i8* blockaddress(@test1, %abnormal))
24          to label %normal [label %abnormal]
25
26normal:
27  ret i32 %ret
28
29abnormal:
30  ret i32 1
31}
32
33define i32 @test2(i32 %out1, i32 %out2) {
34; CHECK-LABEL: test2:
35; CHECK:       # %bb.0: # %entry
36; CHECK-NEXT:    pushl %edi
37; CHECK-NEXT:    .cfi_def_cfa_offset 8
38; CHECK-NEXT:    pushl %esi
39; CHECK-NEXT:    .cfi_def_cfa_offset 12
40; CHECK-NEXT:    .cfi_offset %esi, -12
41; CHECK-NEXT:    .cfi_offset %edi, -8
42; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %edi
43; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %esi
44; CHECK-NEXT:    movl $-1, %eax
45; CHECK-NEXT:    cmpl %edi, %esi
46; CHECK-NEXT:    jge .LBB1_2
47; CHECK-NEXT:  # %bb.1: # %if.then
48; CHECK-NEXT:    #APP
49; CHECK-NEXT:    testl %esi, %esi
50; CHECK-NEXT:    testl %edi, %esi
51; CHECK-NEXT:    jne .Ltmp1
52; CHECK-NEXT:    #NO_APP
53; CHECK-NEXT:    jmp .LBB1_3
54; CHECK-NEXT:  .LBB1_2: # %if.else
55; CHECK-NEXT:    #APP
56; CHECK-NEXT:    testl %esi, %edi
57; CHECK-NEXT:    testl %esi, %edi
58; CHECK-NEXT:    jne .Ltmp2
59; CHECK-NEXT:    #NO_APP
60; CHECK-NEXT:  .LBB1_3:
61; CHECK-NEXT:    movl %esi, %eax
62; CHECK-NEXT:    addl %edi, %eax
63; CHECK-NEXT:  .Ltmp2: # Block address taken
64; CHECK-NEXT:  .LBB1_5: # %return
65; CHECK-NEXT:    popl %esi
66; CHECK-NEXT:    .cfi_def_cfa_offset 8
67; CHECK-NEXT:    popl %edi
68; CHECK-NEXT:    .cfi_def_cfa_offset 4
69; CHECK-NEXT:    retl
70; CHECK-NEXT:  .Ltmp1: # Block address taken
71; CHECK-NEXT:  .LBB1_4: # %label_true
72; CHECK-NEXT:    .cfi_def_cfa_offset 12
73; CHECK-NEXT:    movl $-2, %eax
74; CHECK-NEXT:    jmp .LBB1_5
75entry:
76  %cmp = icmp slt i32 %out1, %out2
77  br i1 %cmp, label %if.then, label %if.else
78
79if.then:                                          ; preds = %entry
80  %0 = callbr { i32, i32 } asm sideeffect "testl $0, $0; testl $1, $2; jne ${3:l}", "={si},={di},r,X,X,0,1,~{dirflag},~{fpsr},~{flags}"(i32 %out1, i8* blockaddress(@test2, %label_true), i8* blockaddress(@test2, %return), i32 %out1, i32 %out2)
81          to label %if.end [label %label_true, label %return]
82
83if.else:                                          ; preds = %entry
84  %1 = callbr { i32, i32 } asm sideeffect "testl $0, $1; testl $2, $3; jne ${5:l}", "={si},={di},r,r,X,X,0,1,~{dirflag},~{fpsr},~{flags}"(i32 %out1, i32 %out2, i8* blockaddress(@test2, %label_true), i8* blockaddress(@test2, %return), i32 %out1, i32 %out2)
85          to label %if.end [label %label_true, label %return]
86
87if.end:                                           ; preds = %if.else, %if.then
88  %.sink11 = phi { i32, i32 } [ %0, %if.then ], [ %1, %if.else ]
89  %asmresult3 = extractvalue { i32, i32 } %.sink11, 0
90  %asmresult4 = extractvalue { i32, i32 } %.sink11, 1
91  %add = add nsw i32 %asmresult4, %asmresult3
92  br label %return
93
94label_true:                                       ; preds = %if.else, %if.then
95  br label %return
96
97return:                                           ; preds = %if.then, %if.else, %label_true, %if.end
98  %retval.0 = phi i32 [ %add, %if.end ], [ -2, %label_true ], [ -1, %if.else ], [ -1, %if.then ]
99  ret i32 %retval.0
100}
101
102define i32 @test3(i1 %cmp) {
103; CHECK-LABEL: test3:
104; CHECK:       # %bb.0: # %entry
105; CHECK-NEXT:    pushl %edi
106; CHECK-NEXT:    .cfi_def_cfa_offset 8
107; CHECK-NEXT:    pushl %esi
108; CHECK-NEXT:    .cfi_def_cfa_offset 12
109; CHECK-NEXT:    .cfi_offset %esi, -12
110; CHECK-NEXT:    .cfi_offset %edi, -8
111; CHECK-NEXT:    testb $1, {{[0-9]+}}(%esp)
112; CHECK-NEXT:    je .LBB2_3
113; CHECK-NEXT:  # %bb.1: # %true
114; CHECK-NEXT:    #APP
115; CHECK-NEXT:    .short %esi
116; CHECK-NEXT:    .short %edi
117; CHECK-NEXT:    #NO_APP
118; CHECK-NEXT:  # %bb.2:
119; CHECK-NEXT:    movl %edi, %eax
120; CHECK-NEXT:    jmp .LBB2_5
121; CHECK-NEXT:  .LBB2_3: # %false
122; CHECK-NEXT:    #APP
123; CHECK-NEXT:    .short %eax
124; CHECK-NEXT:    .short %edx
125; CHECK-NEXT:    #NO_APP
126; CHECK-NEXT:  # %bb.4:
127; CHECK-NEXT:    movl %edx, %eax
128; CHECK-NEXT:  .LBB2_5: # %asm.fallthrough
129; CHECK-NEXT:    popl %esi
130; CHECK-NEXT:    .cfi_def_cfa_offset 8
131; CHECK-NEXT:    popl %edi
132; CHECK-NEXT:    .cfi_def_cfa_offset 4
133; CHECK-NEXT:    retl
134; CHECK-NEXT:  .Ltmp3: # Block address taken
135; CHECK-NEXT:  .LBB2_6: # %indirect
136; CHECK-NEXT:    .cfi_def_cfa_offset 12
137; CHECK-NEXT:    movl $42, %eax
138; CHECK-NEXT:    jmp .LBB2_5
139entry:
140  br i1 %cmp, label %true, label %false
141
142true:
143  %0 = callbr { i32, i32 } asm sideeffect ".word $0, $1", "={si},={di},X" (i8* blockaddress(@test3, %indirect)) to label %asm.fallthrough [label %indirect]
144
145false:
146  %1 = callbr { i32, i32 } asm sideeffect ".word $0, $1", "={ax},={dx},X" (i8* blockaddress(@test3, %indirect)) to label %asm.fallthrough [label %indirect]
147
148asm.fallthrough:
149  %vals = phi { i32, i32 } [ %0, %true ], [ %1, %false ]
150  %v = extractvalue { i32, i32 } %vals, 1
151  ret i32 %v
152
153indirect:
154  ret i32 42
155}
156
157; Test 4 - asm-goto with output constraints.
158define i32 @test4(i32 %out1, i32 %out2) {
159; CHECK-LABEL: test4:
160; CHECK:       # %bb.0: # %entry
161; CHECK-NEXT:    movl $-1, %eax
162; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %ecx
163; CHECK-NEXT:    #APP
164; CHECK-NEXT:    testl %ecx, %ecx
165; CHECK-NEXT:    testl %edx, %ecx
166; CHECK-NEXT:    jne .Ltmp4
167; CHECK-NEXT:    #NO_APP
168; CHECK-NEXT:  # %bb.1: # %asm.fallthrough
169; CHECK-NEXT:    #APP
170; CHECK-NEXT:    testl %ecx, %edx
171; CHECK-NEXT:    testl %ecx, %edx
172; CHECK-NEXT:    jne .Ltmp5
173; CHECK-NEXT:    #NO_APP
174; CHECK-NEXT:  # %bb.2: # %asm.fallthrough2
175; CHECK-NEXT:    addl %edx, %ecx
176; CHECK-NEXT:    movl %ecx, %eax
177; CHECK-NEXT:    retl
178; CHECK-NEXT:  .Ltmp4: # Block address taken
179; CHECK-NEXT:  .LBB3_3: # %label_true
180; CHECK-NEXT:    movl $-2, %eax
181; CHECK-NEXT:  .Ltmp5: # Block address taken
182; CHECK-NEXT:  .LBB3_4: # %return
183; CHECK-NEXT:    retl
184entry:
185  %0 = callbr { i32, i32 } asm sideeffect "testl $0, $0; testl $1, $2; jne ${3:l}", "=r,=r,r,X,X,~{dirflag},~{fpsr},~{flags}"(i32 %out1, i8* blockaddress(@test4, %label_true), i8* blockaddress(@test4, %return))
186          to label %asm.fallthrough [label %label_true, label %return]
187
188asm.fallthrough:                                  ; preds = %entry
189  %asmresult = extractvalue { i32, i32 } %0, 0
190  %asmresult1 = extractvalue { i32, i32 } %0, 1
191  %1 = callbr { i32, i32 } asm sideeffect "testl $0, $1; testl $2, $3; jne ${5:l}", "=r,=r,r,r,X,X,~{dirflag},~{fpsr},~{flags}"(i32 %asmresult, i32 %asmresult1, i8* blockaddress(@test4, %label_true), i8* blockaddress(@test4, %return))
192          to label %asm.fallthrough2 [label %label_true, label %return]
193
194asm.fallthrough2:                                 ; preds = %asm.fallthrough
195  %asmresult3 = extractvalue { i32, i32 } %1, 0
196  %asmresult4 = extractvalue { i32, i32 } %1, 1
197  %add = add nsw i32 %asmresult3, %asmresult4
198  br label %return
199
200label_true:                                       ; preds = %asm.fallthrough, %entry
201  br label %return
202
203return:                                           ; preds = %entry, %asm.fallthrough, %label_true, %asm.fallthrough2
204  %retval.0 = phi i32 [ %add, %asm.fallthrough2 ], [ -2, %label_true ], [ -1, %asm.fallthrough ], [ -1, %entry ]
205  ret i32 %retval.0
206}
207