1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=i686-unknown -verify-machineinstrs < %s | FileCheck %s
3 ; RUN: opt < %s -codegenprepare -S -mtriple=x86_64-unknown-unknown | FileCheck --check-prefix=CHECK-CGP %s
4 ; RUN: opt < %s -codegenprepare -cgpp-huge-func=0 -S -mtriple=x86_64-unknown-unknown | FileCheck --check-prefix=CHECK-CGP %s
6 @A = global i32 zeroinitializer
7 @B = global i32 zeroinitializer
8 @C = global i32 zeroinitializer
10 ; Test that 'and' is sunk into bb0.
11 define i32 @and_sink1(i32 %a, i1 %c) {
12 ; CHECK-LABEL: and_sink1:
14 ; CHECK-NEXT: testb $1, {{[0-9]+}}(%esp)
15 ; CHECK-NEXT: je .LBB0_3
16 ; CHECK-NEXT: # %bb.1: # %bb0
17 ; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax
18 ; CHECK-NEXT: testb $4, %al
19 ; CHECK-NEXT: movl $0, A
20 ; CHECK-NEXT: jne .LBB0_3
21 ; CHECK-NEXT: # %bb.2: # %bb1
22 ; CHECK-NEXT: movl $1, %eax
24 ; CHECK-NEXT: .LBB0_3: # %bb2
25 ; CHECK-NEXT: xorl %eax, %eax
28 ; CHECK-CGP-LABEL: @and_sink1(
29 ; CHECK-CGP-NOT: and i32
31 br i1 %c, label %bb0, label %bb2
33 ; CHECK-CGP-LABEL: bb0:
35 ; CHECK-CGP-NEXT: icmp eq i32
36 ; CHECK-CGP-NEXT: store
38 %cmp = icmp eq i32 %and, 0
40 br i1 %cmp, label %bb1, label %bb2
47 ; Test that both 'and' and cmp get sunk to bb1.
48 define i32 @and_sink2(i32 %a, i1 %c, i1 %c2) {
49 ; CHECK-LABEL: and_sink2:
51 ; CHECK-NEXT: movl $0, A
52 ; CHECK-NEXT: testb $1, {{[0-9]+}}(%esp)
53 ; CHECK-NEXT: je .LBB1_5
54 ; CHECK-NEXT: # %bb.1: # %bb0.preheader
55 ; CHECK-NEXT: movzbl {{[0-9]+}}(%esp), %eax
56 ; CHECK-NEXT: movl {{[0-9]+}}(%esp), %ecx
57 ; CHECK-NEXT: .p2align 4, 0x90
58 ; CHECK-NEXT: .LBB1_2: # %bb0
59 ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
60 ; CHECK-NEXT: movl $0, B
61 ; CHECK-NEXT: testb $1, %al
62 ; CHECK-NEXT: je .LBB1_5
63 ; CHECK-NEXT: # %bb.3: # %bb1
64 ; CHECK-NEXT: # in Loop: Header=BB1_2 Depth=1
65 ; CHECK-NEXT: testb $4, %cl
66 ; CHECK-NEXT: movl $0, C
67 ; CHECK-NEXT: jne .LBB1_2
68 ; CHECK-NEXT: # %bb.4: # %bb2
69 ; CHECK-NEXT: movl $1, %eax
71 ; CHECK-NEXT: .LBB1_5: # %bb3
72 ; CHECK-NEXT: xorl %eax, %eax
75 ; CHECK-CGP-LABEL: @and_sink2(
76 ; CHECK-CGP-NOT: and i32
79 br i1 %c, label %bb0, label %bb3
81 ; CHECK-CGP-LABEL: bb0:
82 ; CHECK-CGP-NOT: and i32
84 %cmp = icmp eq i32 %and, 0
86 br i1 %c2, label %bb1, label %bb3
88 ; CHECK-CGP-LABEL: bb1:
90 ; CHECK-CGP-NEXT: icmp eq i32
91 ; CHECK-CGP-NEXT: store
94 br i1 %cmp, label %bb2, label %bb0
101 ; Test that CodeGenPrepare doesn't get stuck in a loop sinking and hoisting a masked load.
102 define i32 @and_sink3(i1 %c, ptr %p) {
103 ; CHECK-LABEL: and_sink3:
105 ; CHECK-NEXT: testb $1, {{[0-9]+}}(%esp)
106 ; CHECK-NEXT: je .LBB2_3
107 ; CHECK-NEXT: # %bb.1: # %bb0
108 ; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax
109 ; CHECK-NEXT: movzbl (%eax), %eax
110 ; CHECK-NEXT: testl %eax, %eax
111 ; CHECK-NEXT: movl $0, A
112 ; CHECK-NEXT: je .LBB2_2
113 ; CHECK-NEXT: .LBB2_3: # %bb2
114 ; CHECK-NEXT: xorl %eax, %eax
116 ; CHECK-NEXT: .LBB2_2: # %bb1
117 ; CHECK-NEXT: movl $1, %eax
120 ; CHECK-CGP-LABEL: @and_sink3(
121 ; CHECK-CGP: load i32
122 ; CHECK-CGP-NEXT: and i32
123 %load = load i32, ptr %p
124 %and = and i32 %load, 255
125 br i1 %c, label %bb0, label %bb2
127 ; CHECK-CGP-LABEL: bb0:
128 ; CHECK-CGP-NOT: and i32
129 ; CHECK-CGP: icmp eq i32
130 %cmp = icmp eq i32 %and, 0
132 br i1 %cmp, label %bb1, label %bb2
139 ; Test that CodeGenPrepare sinks/duplicates non-immediate 'and'.
140 define i32 @and_sink4(i32 %a, i32 %b, i1 %c) {
141 ; CHECK-LABEL: and_sink4:
143 ; CHECK-NEXT: testb $1, {{[0-9]+}}(%esp)
144 ; CHECK-NEXT: je .LBB3_4
145 ; CHECK-NEXT: # %bb.1: # %bb0
146 ; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax
147 ; CHECK-NEXT: movl {{[0-9]+}}(%esp), %ecx
148 ; CHECK-NEXT: testl %eax, %ecx
149 ; CHECK-NEXT: movl $0, A
150 ; CHECK-NEXT: jne .LBB3_4
151 ; CHECK-NEXT: # %bb.2: # %bb1
152 ; CHECK-NEXT: leal (%ecx,%eax), %edx
153 ; CHECK-NEXT: testl %eax, %ecx
154 ; CHECK-NEXT: movl %edx, B
155 ; CHECK-NEXT: je .LBB3_3
156 ; CHECK-NEXT: .LBB3_4: # %bb3
157 ; CHECK-NEXT: xorl %eax, %eax
159 ; CHECK-NEXT: .LBB3_3: # %bb2
160 ; CHECK-NEXT: movl $1, %eax
163 ; CHECK-CGP-LABEL: @and_sink4(
164 ; CHECK-CGP-NOT: and i32
165 ; CHECK-CGP-NOT: icmp
166 %and = and i32 %a, %b
167 %cmp = icmp eq i32 %and, 0
168 br i1 %c, label %bb0, label %bb3
170 ; CHECK-CGP-LABEL: bb0:
172 ; CHECK-CGP-NEXT: icmp eq i32
174 br i1 %cmp, label %bb1, label %bb3
176 ; CHECK-CGP-LABEL: bb1:
178 ; CHECK-CGP-NEXT: icmp eq i32
179 %add = add i32 %a, %b
180 store i32 %add, ptr @B
181 br i1 %cmp, label %bb2, label %bb3
189 ; Test that CodeGenPrepare doesn't sink/duplicate non-immediate 'and'
190 ; when it would increase register pressure.
191 define i32 @and_sink5(i32 %a, i32 %b, i32 %a2, i32 %b2, i1 %c) {
192 ; CHECK-LABEL: and_sink5:
194 ; CHECK-NEXT: testb $1, {{[0-9]+}}(%esp)
195 ; CHECK-NEXT: je .LBB4_4
196 ; CHECK-NEXT: # %bb.1: # %bb0
197 ; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax
198 ; CHECK-NEXT: andl {{[0-9]+}}(%esp), %eax
199 ; CHECK-NEXT: movl $0, A
200 ; CHECK-NEXT: jne .LBB4_4
201 ; CHECK-NEXT: # %bb.2: # %bb1
202 ; CHECK-NEXT: movl {{[0-9]+}}(%esp), %ecx
203 ; CHECK-NEXT: addl {{[0-9]+}}(%esp), %ecx
204 ; CHECK-NEXT: testl %eax, %eax
205 ; CHECK-NEXT: movl %ecx, B
206 ; CHECK-NEXT: je .LBB4_3
207 ; CHECK-NEXT: .LBB4_4: # %bb3
208 ; CHECK-NEXT: xorl %eax, %eax
210 ; CHECK-NEXT: .LBB4_3: # %bb2
211 ; CHECK-NEXT: movl $1, %eax
214 ; CHECK-CGP-LABEL: @and_sink5(
216 ; CHECK-CGP-NOT: icmp
217 %and = and i32 %a, %b
218 %cmp = icmp eq i32 %and, 0
219 br i1 %c, label %bb0, label %bb3
221 ; CHECK-CGP-LABEL: bb0:
222 ; CHECK-CGP-NOT: and i32
223 ; CHECK-CGP: icmp eq i32
225 br i1 %cmp, label %bb1, label %bb3
227 ; CHECK-CGP-LABEL: bb1:
228 ; CHECK-CGP-NOT: and i32
229 ; CHECK-CGP: icmp eq i32
230 %add = add i32 %a2, %b2
231 store i32 %add, ptr @B
232 br i1 %cmp, label %bb2, label %bb3