Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / llvm / test / CodeGen / X86 / and-sink.ll
blob965e84844758fc009494bbc31d83ba87a190573c
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:
13 ; CHECK:       # %bb.0:
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
23 ; CHECK-NEXT:    retl
24 ; CHECK-NEXT:  .LBB0_3: # %bb2
25 ; CHECK-NEXT:    xorl %eax, %eax
26 ; CHECK-NEXT:    retl
28 ; CHECK-CGP-LABEL: @and_sink1(
29 ; CHECK-CGP-NOT: and i32
30   %and = and i32 %a, 4
31   br i1 %c, label %bb0, label %bb2
32 bb0:
33 ; CHECK-CGP-LABEL: bb0:
34 ; CHECK-CGP: and i32
35 ; CHECK-CGP-NEXT: icmp eq i32
36 ; CHECK-CGP-NEXT: store
37 ; CHECK-CGP-NEXT: br
38   %cmp = icmp eq i32 %and, 0
39   store i32 0, ptr @A
40   br i1 %cmp, label %bb1, label %bb2
41 bb1:
42   ret i32 1
43 bb2:
44   ret i32 0
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:
50 ; CHECK:       # %bb.0:
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
70 ; CHECK-NEXT:    retl
71 ; CHECK-NEXT:  .LBB1_5: # %bb3
72 ; CHECK-NEXT:    xorl %eax, %eax
73 ; CHECK-NEXT:    retl
75 ; CHECK-CGP-LABEL: @and_sink2(
76 ; CHECK-CGP-NOT: and i32
77   %and = and i32 %a, 4
78   store i32 0, ptr @A
79   br i1 %c, label %bb0, label %bb3
80 bb0:
81 ; CHECK-CGP-LABEL: bb0:
82 ; CHECK-CGP-NOT: and i32
83 ; CHECK-CGP-NOT: icmp
84   %cmp = icmp eq i32 %and, 0
85   store i32 0, ptr @B
86   br i1 %c2, label %bb1, label %bb3
87 bb1:
88 ; CHECK-CGP-LABEL: bb1:
89 ; CHECK-CGP: and i32
90 ; CHECK-CGP-NEXT: icmp eq i32
91 ; CHECK-CGP-NEXT: store
92 ; CHECK-CGP-NEXT: br
93   store i32 0, ptr @C
94   br i1 %cmp, label %bb2, label %bb0
95 bb2:
96   ret i32 1
97 bb3:
98   ret i32 0
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:
104 ; CHECK:       # %bb.0:
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
115 ; CHECK-NEXT:    retl
116 ; CHECK-NEXT:  .LBB2_2: # %bb1
117 ; CHECK-NEXT:    movl $1, %eax
118 ; CHECK-NEXT:    retl
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
126 bb0:
127 ; CHECK-CGP-LABEL: bb0:
128 ; CHECK-CGP-NOT: and i32
129 ; CHECK-CGP: icmp eq i32
130   %cmp = icmp eq i32 %and, 0
131   store i32 0, ptr @A
132   br i1 %cmp, label %bb1, label %bb2
133 bb1:
134   ret i32 1
135 bb2:
136   ret i32 0
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:
142 ; CHECK:       # %bb.0:
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
158 ; CHECK-NEXT:    retl
159 ; CHECK-NEXT:  .LBB3_3: # %bb2
160 ; CHECK-NEXT:    movl $1, %eax
161 ; CHECK-NEXT:    retl
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
169 bb0:
170 ; CHECK-CGP-LABEL: bb0:
171 ; CHECK-CGP: and i32
172 ; CHECK-CGP-NEXT: icmp eq i32
173   store i32 0, ptr @A
174   br i1 %cmp, label %bb1, label %bb3
175 bb1:
176 ; CHECK-CGP-LABEL: bb1:
177 ; CHECK-CGP: and i32
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
182 bb2:
183   ret i32 1
184 bb3:
185   ret i32 0
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:
193 ; CHECK:       # %bb.0:
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
209 ; CHECK-NEXT:    retl
210 ; CHECK-NEXT:  .LBB4_3: # %bb2
211 ; CHECK-NEXT:    movl $1, %eax
212 ; CHECK-NEXT:    retl
214 ; CHECK-CGP-LABEL: @and_sink5(
215 ; CHECK-CGP: and i32
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
220 bb0:
221 ; CHECK-CGP-LABEL: bb0:
222 ; CHECK-CGP-NOT: and i32
223 ; CHECK-CGP: icmp eq i32
224   store i32 0, ptr @A
225   br i1 %cmp, label %bb1, label %bb3
226 bb1:
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
233 bb2:
234   ret i32 1
235 bb3:
236   ret i32 0