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
5 @A = global i32 zeroinitializer
6 @B = global i32 zeroinitializer
7 @C = global i32 zeroinitializer
9 ; Test that 'and' is sunk into bb0.
10 define i32 @and_sink1(i32 %a, i1 %c) {
11 ; CHECK-LABEL: and_sink1:
13 ; CHECK-NEXT: testb $1, {{[0-9]+}}(%esp)
14 ; CHECK-NEXT: je .LBB0_3
15 ; CHECK-NEXT: # %bb.1: # %bb0
16 ; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax
17 ; CHECK-NEXT: testb $4, %al
18 ; CHECK-NEXT: movl $0, A
19 ; CHECK-NEXT: jne .LBB0_3
20 ; CHECK-NEXT: # %bb.2: # %bb1
21 ; CHECK-NEXT: movl $1, %eax
23 ; CHECK-NEXT: .LBB0_3: # %bb2
24 ; CHECK-NEXT: xorl %eax, %eax
27 ; CHECK-CGP-LABEL: @and_sink1(
28 ; CHECK-CGP-NOT: and i32
30 br i1 %c, label %bb0, label %bb2
32 ; CHECK-CGP-LABEL: bb0:
34 ; CHECK-CGP-NEXT: icmp eq i32
35 ; CHECK-CGP-NEXT: store
37 %cmp = icmp eq i32 %and, 0
39 br i1 %cmp, label %bb1, label %bb2
46 ; Test that both 'and' and cmp get sunk to bb1.
47 define i32 @and_sink2(i32 %a, i1 %c, i1 %c2) {
48 ; CHECK-LABEL: and_sink2:
50 ; CHECK-NEXT: movl $0, A
51 ; CHECK-NEXT: testb $1, {{[0-9]+}}(%esp)
52 ; CHECK-NEXT: je .LBB1_5
53 ; CHECK-NEXT: # %bb.1: # %bb0.preheader
54 ; CHECK-NEXT: movb {{[0-9]+}}(%esp), %al
55 ; CHECK-NEXT: movl {{[0-9]+}}(%esp), %ecx
56 ; CHECK-NEXT: .p2align 4, 0x90
57 ; CHECK-NEXT: .LBB1_2: # %bb0
58 ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
59 ; CHECK-NEXT: movl $0, B
60 ; CHECK-NEXT: testb $1, %al
61 ; CHECK-NEXT: je .LBB1_5
62 ; CHECK-NEXT: # %bb.3: # %bb1
63 ; CHECK-NEXT: # in Loop: Header=BB1_2 Depth=1
64 ; CHECK-NEXT: testb $4, %cl
65 ; CHECK-NEXT: movl $0, C
66 ; CHECK-NEXT: jne .LBB1_2
67 ; CHECK-NEXT: # %bb.4: # %bb2
68 ; CHECK-NEXT: movl $1, %eax
70 ; CHECK-NEXT: .LBB1_5: # %bb3
71 ; CHECK-NEXT: xorl %eax, %eax
74 ; CHECK-CGP-LABEL: @and_sink2(
75 ; CHECK-CGP-NOT: and i32
78 br i1 %c, label %bb0, label %bb3
80 ; CHECK-CGP-LABEL: bb0:
81 ; CHECK-CGP-NOT: and i32
83 %cmp = icmp eq i32 %and, 0
85 br i1 %c2, label %bb1, label %bb3
87 ; CHECK-CGP-LABEL: bb1:
89 ; CHECK-CGP-NEXT: icmp eq i32
90 ; CHECK-CGP-NEXT: store
93 br i1 %cmp, label %bb2, label %bb0
100 ; Test that CodeGenPrepare doesn't get stuck in a loop sinking and hoisting a masked load.
101 define i32 @and_sink3(i1 %c, i32* %p) {
102 ; CHECK-LABEL: and_sink3:
104 ; CHECK-NEXT: testb $1, {{[0-9]+}}(%esp)
105 ; CHECK-NEXT: je .LBB2_3
106 ; CHECK-NEXT: # %bb.1: # %bb0
107 ; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax
108 ; CHECK-NEXT: movzbl (%eax), %eax
109 ; CHECK-NEXT: testl %eax, %eax
110 ; CHECK-NEXT: movl $0, A
111 ; CHECK-NEXT: je .LBB2_2
112 ; CHECK-NEXT: .LBB2_3: # %bb2
113 ; CHECK-NEXT: xorl %eax, %eax
115 ; CHECK-NEXT: .LBB2_2: # %bb1
116 ; CHECK-NEXT: movl $1, %eax
119 ; CHECK-CGP-LABEL: @and_sink3(
120 ; CHECK-CGP: load i32
121 ; CHECK-CGP-NEXT: and i32
122 %load = load i32, i32* %p
123 %and = and i32 %load, 255
124 br i1 %c, label %bb0, label %bb2
126 ; CHECK-CGP-LABEL: bb0:
127 ; CHECK-CGP-NOT: and i32
128 ; CHECK-CGP: icmp eq i32
129 %cmp = icmp eq i32 %and, 0
131 br i1 %cmp, label %bb1, label %bb2
138 ; Test that CodeGenPrepare sinks/duplicates non-immediate 'and'.
139 define i32 @and_sink4(i32 %a, i32 %b, i1 %c) {
140 ; CHECK-LABEL: and_sink4:
142 ; CHECK-NEXT: testb $1, {{[0-9]+}}(%esp)
143 ; CHECK-NEXT: je .LBB3_4
144 ; CHECK-NEXT: # %bb.1: # %bb0
145 ; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax
146 ; CHECK-NEXT: movl {{[0-9]+}}(%esp), %ecx
147 ; CHECK-NEXT: testl %eax, %ecx
148 ; CHECK-NEXT: movl $0, A
149 ; CHECK-NEXT: jne .LBB3_4
150 ; CHECK-NEXT: # %bb.2: # %bb1
151 ; CHECK-NEXT: leal (%ecx,%eax), %edx
152 ; CHECK-NEXT: testl %eax, %ecx
153 ; CHECK-NEXT: movl %edx, B
154 ; CHECK-NEXT: je .LBB3_3
155 ; CHECK-NEXT: .LBB3_4: # %bb3
156 ; CHECK-NEXT: xorl %eax, %eax
158 ; CHECK-NEXT: .LBB3_3: # %bb2
159 ; CHECK-NEXT: movl $1, %eax
162 ; CHECK-CGP-LABEL: @and_sink4(
163 ; CHECK-CGP-NOT: and i32
164 ; CHECK-CGP-NOT: icmp
165 %and = and i32 %a, %b
166 %cmp = icmp eq i32 %and, 0
167 br i1 %c, label %bb0, label %bb3
169 ; CHECK-CGP-LABEL: bb0:
171 ; CHECK-CGP-NEXT: icmp eq i32
173 br i1 %cmp, label %bb1, label %bb3
175 ; CHECK-CGP-LABEL: bb1:
177 ; CHECK-CGP-NEXT: icmp eq i32
178 %add = add i32 %a, %b
179 store i32 %add, i32* @B
180 br i1 %cmp, label %bb2, label %bb3
188 ; Test that CodeGenPrepare doesn't sink/duplicate non-immediate 'and'
189 ; when it would increase register pressure.
190 define i32 @and_sink5(i32 %a, i32 %b, i32 %a2, i32 %b2, i1 %c) {
191 ; CHECK-LABEL: and_sink5:
193 ; CHECK-NEXT: testb $1, {{[0-9]+}}(%esp)
194 ; CHECK-NEXT: je .LBB4_4
195 ; CHECK-NEXT: # %bb.1: # %bb0
196 ; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax
197 ; CHECK-NEXT: andl {{[0-9]+}}(%esp), %eax
198 ; CHECK-NEXT: movl $0, A
199 ; CHECK-NEXT: jne .LBB4_4
200 ; CHECK-NEXT: # %bb.2: # %bb1
201 ; CHECK-NEXT: movl {{[0-9]+}}(%esp), %ecx
202 ; CHECK-NEXT: addl {{[0-9]+}}(%esp), %ecx
203 ; CHECK-NEXT: testl %eax, %eax
204 ; CHECK-NEXT: movl %ecx, B
205 ; CHECK-NEXT: je .LBB4_3
206 ; CHECK-NEXT: .LBB4_4: # %bb3
207 ; CHECK-NEXT: xorl %eax, %eax
209 ; CHECK-NEXT: .LBB4_3: # %bb2
210 ; CHECK-NEXT: movl $1, %eax
213 ; CHECK-CGP-LABEL: @and_sink5(
215 ; CHECK-CGP-NOT: icmp
216 %and = and i32 %a, %b
217 %cmp = icmp eq i32 %and, 0
218 br i1 %c, label %bb0, label %bb3
220 ; CHECK-CGP-LABEL: bb0:
221 ; CHECK-CGP-NOT: and i32
222 ; CHECK-CGP: icmp eq i32
224 br i1 %cmp, label %bb1, label %bb3
226 ; CHECK-CGP-LABEL: bb1:
227 ; CHECK-CGP-NOT: and i32
228 ; CHECK-CGP: icmp eq i32
229 %add = add i32 %a2, %b2
230 store i32 %add, i32* @B
231 br i1 %cmp, label %bb2, label %bb3