1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -S -passes=instcombine < %s | FileCheck %s
4 declare void @use.i1(i1)
5 declare void @use.i8(i8)
6 declare void @use.i16(i16)
8 define i1 @and_test1(ptr %x) {
9 ; CHECK-LABEL: @and_test1(
10 ; CHECK-NEXT: [[LOAD:%.*]] = load i16, ptr [[X:%.*]], align 4
11 ; CHECK-NEXT: [[OR:%.*]] = icmp eq i16 [[LOAD]], 17791
12 ; CHECK-NEXT: ret i1 [[OR]]
14 %load = load i16, ptr %x, align 4
15 %trunc = trunc i16 %load to i8
16 %cmp1 = icmp eq i8 %trunc, 127
17 %and = and i16 %load, -256
18 %cmp2 = icmp eq i16 %and, 17664
19 %or = and i1 %cmp1, %cmp2
23 define i1 @and_test1_logical(ptr %x) {
24 ; CHECK-LABEL: @and_test1_logical(
25 ; CHECK-NEXT: [[LOAD:%.*]] = load i16, ptr [[X:%.*]], align 4
26 ; CHECK-NEXT: [[OR:%.*]] = icmp eq i16 [[LOAD]], 17791
27 ; CHECK-NEXT: ret i1 [[OR]]
29 %load = load i16, ptr %x, align 4
30 %trunc = trunc i16 %load to i8
31 %cmp1 = icmp eq i8 %trunc, 127
32 %and = and i16 %load, -256
33 %cmp2 = icmp eq i16 %and, 17664
34 %or = select i1 %cmp1, i1 %cmp2, i1 false
38 define <2 x i1> @and_test1_vector(ptr %x) {
39 ; CHECK-LABEL: @and_test1_vector(
40 ; CHECK-NEXT: [[LOAD:%.*]] = load <2 x i16>, ptr [[X:%.*]], align 4
41 ; CHECK-NEXT: [[OR:%.*]] = icmp eq <2 x i16> [[LOAD]], splat (i16 17791)
42 ; CHECK-NEXT: ret <2 x i1> [[OR]]
44 %load = load <2 x i16>, ptr %x, align 4
45 %trunc = trunc <2 x i16> %load to <2 x i8>
46 %cmp1 = icmp eq <2 x i8> %trunc, <i8 127, i8 127>
47 %and = and <2 x i16> %load, <i16 -256, i16 -256>
48 %cmp2 = icmp eq <2 x i16> %and, <i16 17664, i16 17664>
49 %or = and <2 x i1> %cmp1, %cmp2
53 define i1 @and_test2(ptr %x) {
54 ; CHECK-LABEL: @and_test2(
55 ; CHECK-NEXT: [[LOAD:%.*]] = load i16, ptr [[X:%.*]], align 4
56 ; CHECK-NEXT: [[OR:%.*]] = icmp eq i16 [[LOAD]], 32581
57 ; CHECK-NEXT: ret i1 [[OR]]
59 %load = load i16, ptr %x, align 4
60 %and = and i16 %load, -256
61 %cmp1 = icmp eq i16 %and, 32512
62 %trunc = trunc i16 %load to i8
63 %cmp2 = icmp eq i8 %trunc, 69
64 %or = and i1 %cmp1, %cmp2
68 define i1 @and_test2_logical(ptr %x) {
69 ; CHECK-LABEL: @and_test2_logical(
70 ; CHECK-NEXT: [[LOAD:%.*]] = load i16, ptr [[X:%.*]], align 4
71 ; CHECK-NEXT: [[OR:%.*]] = icmp eq i16 [[LOAD]], 32581
72 ; CHECK-NEXT: ret i1 [[OR]]
74 %load = load i16, ptr %x, align 4
75 %and = and i16 %load, -256
76 %cmp1 = icmp eq i16 %and, 32512
77 %trunc = trunc i16 %load to i8
78 %cmp2 = icmp eq i8 %trunc, 69
79 %or = select i1 %cmp1, i1 %cmp2, i1 false
83 define <2 x i1> @and_test2_vector(ptr %x) {
84 ; CHECK-LABEL: @and_test2_vector(
85 ; CHECK-NEXT: [[LOAD:%.*]] = load <2 x i16>, ptr [[X:%.*]], align 4
86 ; CHECK-NEXT: [[OR:%.*]] = icmp eq <2 x i16> [[LOAD]], splat (i16 32581)
87 ; CHECK-NEXT: ret <2 x i1> [[OR]]
89 %load = load <2 x i16>, ptr %x, align 4
90 %and = and <2 x i16> %load, <i16 -256, i16 -256>
91 %cmp1 = icmp eq <2 x i16> %and, <i16 32512, i16 32512>
92 %trunc = trunc <2 x i16> %load to <2 x i8>
93 %cmp2 = icmp eq <2 x i8> %trunc, <i8 69, i8 69>
94 %or = and <2 x i1> %cmp1, %cmp2
98 define i1 @or_basic(i16 %load) {
99 ; CHECK-LABEL: @or_basic(
100 ; CHECK-NEXT: [[OR:%.*]] = icmp ne i16 [[LOAD:%.*]], 17791
101 ; CHECK-NEXT: ret i1 [[OR]]
103 %trunc = trunc i16 %load to i8
104 %cmp1 = icmp ne i8 %trunc, 127
105 %and = and i16 %load, -256
106 %cmp2 = icmp ne i16 %and, 17664
107 %or = or i1 %cmp1, %cmp2
111 define i1 @or_basic_commuted(i16 %load) {
112 ; CHECK-LABEL: @or_basic_commuted(
113 ; CHECK-NEXT: [[OR:%.*]] = icmp ne i16 [[LOAD:%.*]], 32581
114 ; CHECK-NEXT: ret i1 [[OR]]
116 %and = and i16 %load, -256
117 %cmp1 = icmp ne i16 %and, 32512
118 %trunc = trunc i16 %load to i8
119 %cmp2 = icmp ne i8 %trunc, 69
120 %or = or i1 %cmp1, %cmp2
124 define <2 x i1> @or_vector(<2 x i16> %load) {
125 ; CHECK-LABEL: @or_vector(
126 ; CHECK-NEXT: [[OR:%.*]] = icmp ne <2 x i16> [[LOAD:%.*]], splat (i16 17791)
127 ; CHECK-NEXT: ret <2 x i1> [[OR]]
129 %trunc = trunc <2 x i16> %load to <2 x i8>
130 %cmp1 = icmp ne <2 x i8> %trunc, <i8 127, i8 127>
131 %and = and <2 x i16> %load, <i16 -256, i16 -256>
132 %cmp2 = icmp ne <2 x i16> %and, <i16 17664, i16 17664>
133 %or = or <2 x i1> %cmp1, %cmp2
137 define i1 @or_nontrivial_mask1(i16 %load) {
138 ; CHECK-LABEL: @or_nontrivial_mask1(
139 ; CHECK-NEXT: [[TMP1:%.*]] = and i16 [[LOAD:%.*]], 4095
140 ; CHECK-NEXT: [[OR:%.*]] = icmp ne i16 [[TMP1]], 1407
141 ; CHECK-NEXT: ret i1 [[OR]]
143 %trunc = trunc i16 %load to i8
144 %cmp1 = icmp ne i8 %trunc, 127
145 %and = and i16 %load, 3840
146 %cmp2 = icmp ne i16 %and, 1280
147 %or = or i1 %cmp1, %cmp2
151 define i1 @or_nontrivial_mask2(i16 %load) {
152 ; CHECK-LABEL: @or_nontrivial_mask2(
153 ; CHECK-NEXT: [[TMP1:%.*]] = and i16 [[LOAD:%.*]], -3841
154 ; CHECK-NEXT: [[OR:%.*]] = icmp ne i16 [[TMP1]], 20607
155 ; CHECK-NEXT: ret i1 [[OR]]
157 %trunc = trunc i16 %load to i8
158 %cmp1 = icmp ne i8 %trunc, 127
159 %and = and i16 %load, -4096
160 %cmp2 = icmp ne i16 %and, 20480
161 %or = or i1 %cmp1, %cmp2
165 define i1 @or_extra_use1(i16 %load) {
166 ; CHECK-LABEL: @or_extra_use1(
167 ; CHECK-NEXT: [[TRUNC:%.*]] = trunc i16 [[LOAD:%.*]] to i8
168 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i8 [[TRUNC]], 127
169 ; CHECK-NEXT: call void @use.i1(i1 [[CMP1]])
170 ; CHECK-NEXT: [[AND:%.*]] = and i16 [[LOAD]], -4096
171 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i16 [[AND]], 20480
172 ; CHECK-NEXT: [[OR:%.*]] = or i1 [[CMP1]], [[CMP2]]
173 ; CHECK-NEXT: ret i1 [[OR]]
175 %trunc = trunc i16 %load to i8
176 %cmp1 = icmp ne i8 %trunc, 127
177 call void @use.i1(i1 %cmp1)
178 %and = and i16 %load, -4096
179 %cmp2 = icmp ne i16 %and, 20480
180 %or = or i1 %cmp1, %cmp2
184 define i1 @or_extra_use2(i16 %load) {
185 ; CHECK-LABEL: @or_extra_use2(
186 ; CHECK-NEXT: [[TRUNC:%.*]] = trunc i16 [[LOAD:%.*]] to i8
187 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i8 [[TRUNC]], 127
188 ; CHECK-NEXT: [[AND:%.*]] = and i16 [[LOAD]], -4096
189 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i16 [[AND]], 20480
190 ; CHECK-NEXT: call void @use.i1(i1 [[CMP2]])
191 ; CHECK-NEXT: [[OR:%.*]] = or i1 [[CMP1]], [[CMP2]]
192 ; CHECK-NEXT: ret i1 [[OR]]
194 %trunc = trunc i16 %load to i8
195 %cmp1 = icmp ne i8 %trunc, 127
196 %and = and i16 %load, -4096
197 %cmp2 = icmp ne i16 %and, 20480
198 call void @use.i1(i1 %cmp2)
199 %or = or i1 %cmp1, %cmp2
203 define i1 @or_extra_use3(i16 %load) {
204 ; CHECK-LABEL: @or_extra_use3(
205 ; CHECK-NEXT: [[TRUNC:%.*]] = trunc i16 [[LOAD:%.*]] to i8
206 ; CHECK-NEXT: call void @use.i8(i8 [[TRUNC]])
207 ; CHECK-NEXT: [[TMP1:%.*]] = and i16 [[LOAD]], -3841
208 ; CHECK-NEXT: [[OR:%.*]] = icmp ne i16 [[TMP1]], 20607
209 ; CHECK-NEXT: ret i1 [[OR]]
211 %trunc = trunc i16 %load to i8
212 call void @use.i8(i8 %trunc)
213 %cmp1 = icmp ne i8 %trunc, 127
214 %and = and i16 %load, -4096
215 %cmp2 = icmp ne i16 %and, 20480
216 %or = or i1 %cmp1, %cmp2
220 define i1 @or_extra_use4(i16 %load) {
221 ; CHECK-LABEL: @or_extra_use4(
222 ; CHECK-NEXT: [[AND:%.*]] = and i16 [[LOAD:%.*]], -4096
223 ; CHECK-NEXT: call void @use.i16(i16 [[AND]])
224 ; CHECK-NEXT: [[TMP1:%.*]] = and i16 [[LOAD]], -3841
225 ; CHECK-NEXT: [[OR:%.*]] = icmp ne i16 [[TMP1]], 20607
226 ; CHECK-NEXT: ret i1 [[OR]]
228 %trunc = trunc i16 %load to i8
229 %cmp1 = icmp ne i8 %trunc, 127
230 %and = and i16 %load, -4096
231 call void @use.i16(i16 %and)
232 %cmp2 = icmp ne i16 %and, 20480
233 %or = or i1 %cmp1, %cmp2
237 define i1 @or_wrong_pred1(i16 %load) {
238 ; CHECK-LABEL: @or_wrong_pred1(
239 ; CHECK-NEXT: [[TRUNC:%.*]] = trunc i16 [[LOAD:%.*]] to i8
240 ; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i8 [[TRUNC]], 127
241 ; CHECK-NEXT: [[AND:%.*]] = and i16 [[LOAD]], -256
242 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i16 [[AND]], 17664
243 ; CHECK-NEXT: [[OR:%.*]] = or i1 [[CMP1]], [[CMP2]]
244 ; CHECK-NEXT: ret i1 [[OR]]
246 %trunc = trunc i16 %load to i8
247 %cmp1 = icmp eq i8 %trunc, 127
248 %and = and i16 %load, -256
249 %cmp2 = icmp ne i16 %and, 17664
250 %or = or i1 %cmp1, %cmp2
254 define i1 @or_wrong_pred2(i16 %load) {
255 ; CHECK-LABEL: @or_wrong_pred2(
256 ; CHECK-NEXT: [[TRUNC:%.*]] = trunc i16 [[LOAD:%.*]] to i8
257 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i8 [[TRUNC]], 127
258 ; CHECK-NEXT: [[AND:%.*]] = and i16 [[LOAD]], -256
259 ; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i16 [[AND]], 17664
260 ; CHECK-NEXT: [[OR:%.*]] = or i1 [[CMP1]], [[CMP2]]
261 ; CHECK-NEXT: ret i1 [[OR]]
263 %trunc = trunc i16 %load to i8
264 %cmp1 = icmp ne i8 %trunc, 127
265 %and = and i16 %load, -256
266 %cmp2 = icmp eq i16 %and, 17664
267 %or = or i1 %cmp1, %cmp2
271 define i1 @or_wrong_pred3(i16 %load) {
272 ; CHECK-LABEL: @or_wrong_pred3(
273 ; CHECK-NEXT: [[TRUNC:%.*]] = trunc i16 [[LOAD:%.*]] to i8
274 ; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i8 [[TRUNC]], 127
275 ; CHECK-NEXT: [[AND:%.*]] = and i16 [[LOAD]], -256
276 ; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i16 [[AND]], 17664
277 ; CHECK-NEXT: [[OR:%.*]] = or i1 [[CMP1]], [[CMP2]]
278 ; CHECK-NEXT: ret i1 [[OR]]
280 %trunc = trunc i16 %load to i8
281 %cmp1 = icmp eq i8 %trunc, 127
282 %and = and i16 %load, -256
283 %cmp2 = icmp eq i16 %and, 17664
284 %or = or i1 %cmp1, %cmp2
288 define i1 @or_wrong_op(i16 %load, i16 %other) {
289 ; CHECK-LABEL: @or_wrong_op(
290 ; CHECK-NEXT: [[TRUNC:%.*]] = trunc i16 [[LOAD:%.*]] to i8
291 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i8 [[TRUNC]], 127
292 ; CHECK-NEXT: [[AND:%.*]] = and i16 [[OTHER:%.*]], -256
293 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i16 [[AND]], 17664
294 ; CHECK-NEXT: [[OR:%.*]] = or i1 [[CMP1]], [[CMP2]]
295 ; CHECK-NEXT: ret i1 [[OR]]
297 %trunc = trunc i16 %load to i8
298 %cmp1 = icmp ne i8 %trunc, 127
299 %and = and i16 %other, -256
300 %cmp2 = icmp ne i16 %and, 17664
301 %or = or i1 %cmp1, %cmp2
305 define i1 @or_wrong_const1(i16 %load) {
306 ; CHECK-LABEL: @or_wrong_const1(
307 ; CHECK-NEXT: ret i1 true
309 %trunc = trunc i16 %load to i8
310 %cmp1 = icmp ne i8 %trunc, 127
311 %and = and i16 %load, -256
312 %cmp2 = icmp ne i16 %and, 17665
313 %or = or i1 %cmp1, %cmp2
317 define i1 @or_wrong_const2(i16 %load) {
318 ; CHECK-LABEL: @or_wrong_const2(
319 ; CHECK-NEXT: [[TRUNC:%.*]] = trunc i16 [[LOAD:%.*]] to i8
320 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i8 [[TRUNC]], 127
321 ; CHECK-NEXT: [[AND:%.*]] = and i16 [[LOAD]], -255
322 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i16 [[AND]], 17665
323 ; CHECK-NEXT: [[OR:%.*]] = or i1 [[CMP1]], [[CMP2]]
324 ; CHECK-NEXT: ret i1 [[OR]]
326 %trunc = trunc i16 %load to i8
327 %cmp1 = icmp ne i8 %trunc, 127
328 %and = and i16 %load, -255
329 %cmp2 = icmp ne i16 %and, 17665
330 %or = or i1 %cmp1, %cmp2