[InstCombine] Signed saturation patterns
[llvm-complete.git] / test / CodeGen / X86 / and-sink.ll
blob0a3636676486f21c7d85b05b8a22415fc3c7c8d4
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:
12 ; CHECK:       # %bb.0:
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
22 ; CHECK-NEXT:    retl
23 ; CHECK-NEXT:  .LBB0_3: # %bb2
24 ; CHECK-NEXT:    xorl %eax, %eax
25 ; CHECK-NEXT:    retl
27 ; CHECK-CGP-LABEL: @and_sink1(
28 ; CHECK-CGP-NOT: and i32
29   %and = and i32 %a, 4
30   br i1 %c, label %bb0, label %bb2
31 bb0:
32 ; CHECK-CGP-LABEL: bb0:
33 ; CHECK-CGP: and i32
34 ; CHECK-CGP-NEXT: icmp eq i32
35 ; CHECK-CGP-NEXT: store
36 ; CHECK-CGP-NEXT: br
37   %cmp = icmp eq i32 %and, 0
38   store i32 0, i32* @A
39   br i1 %cmp, label %bb1, label %bb2
40 bb1:
41   ret i32 1
42 bb2:
43   ret i32 0
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:
49 ; CHECK:       # %bb.0:
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
69 ; CHECK-NEXT:    retl
70 ; CHECK-NEXT:  .LBB1_5: # %bb3
71 ; CHECK-NEXT:    xorl %eax, %eax
72 ; CHECK-NEXT:    retl
74 ; CHECK-CGP-LABEL: @and_sink2(
75 ; CHECK-CGP-NOT: and i32
76   %and = and i32 %a, 4
77   store i32 0, i32* @A
78   br i1 %c, label %bb0, label %bb3
79 bb0:
80 ; CHECK-CGP-LABEL: bb0:
81 ; CHECK-CGP-NOT: and i32
82 ; CHECK-CGP-NOT: icmp
83   %cmp = icmp eq i32 %and, 0
84   store i32 0, i32* @B
85   br i1 %c2, label %bb1, label %bb3
86 bb1:
87 ; CHECK-CGP-LABEL: bb1:
88 ; CHECK-CGP: and i32
89 ; CHECK-CGP-NEXT: icmp eq i32
90 ; CHECK-CGP-NEXT: store
91 ; CHECK-CGP-NEXT: br
92   store i32 0, i32* @C
93   br i1 %cmp, label %bb2, label %bb0
94 bb2:
95   ret i32 1
96 bb3:
97   ret i32 0
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:
103 ; CHECK:       # %bb.0:
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
114 ; CHECK-NEXT:    retl
115 ; CHECK-NEXT:  .LBB2_2: # %bb1
116 ; CHECK-NEXT:    movl $1, %eax
117 ; CHECK-NEXT:    retl
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
125 bb0:
126 ; CHECK-CGP-LABEL: bb0:
127 ; CHECK-CGP-NOT: and i32
128 ; CHECK-CGP: icmp eq i32
129   %cmp = icmp eq i32 %and, 0
130   store i32 0, i32* @A
131   br i1 %cmp, label %bb1, label %bb2
132 bb1:
133   ret i32 1
134 bb2:
135   ret i32 0
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:
141 ; CHECK:       # %bb.0:
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
157 ; CHECK-NEXT:    retl
158 ; CHECK-NEXT:  .LBB3_3: # %bb2
159 ; CHECK-NEXT:    movl $1, %eax
160 ; CHECK-NEXT:    retl
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
168 bb0:
169 ; CHECK-CGP-LABEL: bb0:
170 ; CHECK-CGP: and i32
171 ; CHECK-CGP-NEXT: icmp eq i32
172   store i32 0, i32* @A
173   br i1 %cmp, label %bb1, label %bb3
174 bb1:
175 ; CHECK-CGP-LABEL: bb1:
176 ; CHECK-CGP: and i32
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
181 bb2:
182   ret i32 1
183 bb3:
184   ret i32 0
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:
192 ; CHECK:       # %bb.0:
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
208 ; CHECK-NEXT:    retl
209 ; CHECK-NEXT:  .LBB4_3: # %bb2
210 ; CHECK-NEXT:    movl $1, %eax
211 ; CHECK-NEXT:    retl
213 ; CHECK-CGP-LABEL: @and_sink5(
214 ; CHECK-CGP: and i32
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
219 bb0:
220 ; CHECK-CGP-LABEL: bb0:
221 ; CHECK-CGP-NOT: and i32
222 ; CHECK-CGP: icmp eq i32
223   store i32 0, i32* @A
224   br i1 %cmp, label %bb1, label %bb3
225 bb1:
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
232 bb2:
233   ret i32 1
234 bb3:
235   ret i32 0