1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
5 declare void @use_vec(<2 x i32>)
7 define i32 @testAdd(i32 %X, i32 %Y) {
8 ; CHECK-LABEL: @testAdd(
9 ; CHECK-NEXT: [[T:%.*]] = add i32 [[X:%.*]], [[Y:%.*]]
10 ; CHECK-NEXT: ret i32 [[T]]
13 %tl = bitcast i32 %t to i32
17 define i32 @and_sext_to_sel(i32 %x, i1 %y) {
18 ; CHECK-LABEL: @and_sext_to_sel(
19 ; CHECK-NEXT: [[R:%.*]] = select i1 [[Y:%.*]], i32 [[X:%.*]], i32 0
20 ; CHECK-NEXT: ret i32 [[R]]
22 %sext = sext i1 %y to i32
23 %r = and i32 %sext, %x
27 define <2 x i32> @and_sext_to_sel_constant_vec(<2 x i1> %y) {
28 ; CHECK-LABEL: @and_sext_to_sel_constant_vec(
29 ; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[Y:%.*]], <2 x i32> <i32 42, i32 -7>, <2 x i32> zeroinitializer
30 ; CHECK-NEXT: ret <2 x i32> [[R]]
32 %sext = sext <2 x i1> %y to <2 x i32>
33 %r = and <2 x i32> <i32 42, i32 -7>, %sext
37 define <2 x i32> @and_sext_to_sel_swap(<2 x i32> %px, <2 x i1> %y) {
38 ; CHECK-LABEL: @and_sext_to_sel_swap(
39 ; CHECK-NEXT: [[X:%.*]] = mul <2 x i32> [[PX:%.*]], [[PX]]
40 ; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[Y:%.*]], <2 x i32> [[X]], <2 x i32> zeroinitializer
41 ; CHECK-NEXT: ret <2 x i32> [[R]]
43 %x = mul <2 x i32> %px, %px ; thwart complexity-based canonicalization
44 %sext = sext <2 x i1> %y to <2 x i32>
45 %r = and <2 x i32> %x, %sext
49 define i32 @and_sext_to_sel_multi_use(i32 %x, i1 %y) {
50 ; CHECK-LABEL: @and_sext_to_sel_multi_use(
51 ; CHECK-NEXT: [[SEXT:%.*]] = sext i1 [[Y:%.*]] to i32
52 ; CHECK-NEXT: call void @use(i32 [[SEXT]])
53 ; CHECK-NEXT: [[R:%.*]] = select i1 [[Y]], i32 [[X:%.*]], i32 0
54 ; CHECK-NEXT: ret i32 [[R]]
56 %sext = sext i1 %y to i32
57 call void @use(i32 %sext)
58 %r = and i32 %sext, %x
62 define i32 @and_sext_to_sel_multi_use_constant_mask(i1 %y) {
63 ; CHECK-LABEL: @and_sext_to_sel_multi_use_constant_mask(
64 ; CHECK-NEXT: [[SEXT:%.*]] = sext i1 [[Y:%.*]] to i32
65 ; CHECK-NEXT: call void @use(i32 [[SEXT]])
66 ; CHECK-NEXT: [[R:%.*]] = select i1 [[Y]], i32 42, i32 0
67 ; CHECK-NEXT: ret i32 [[R]]
69 %sext = sext i1 %y to i32
70 call void @use(i32 %sext)
71 %r = and i32 %sext, 42
75 define <2 x i32> @and_not_sext_to_sel(<2 x i32> %x, <2 x i1> %y) {
76 ; CHECK-LABEL: @and_not_sext_to_sel(
77 ; CHECK-NEXT: [[SEXT:%.*]] = sext <2 x i1> [[Y:%.*]] to <2 x i32>
78 ; CHECK-NEXT: call void @use_vec(<2 x i32> [[SEXT]])
79 ; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[Y]], <2 x i32> zeroinitializer, <2 x i32> [[X:%.*]]
80 ; CHECK-NEXT: ret <2 x i32> [[R]]
82 %sext = sext <2 x i1> %y to <2 x i32>
83 call void @use_vec(<2 x i32> %sext)
84 %not = xor <2 x i32> %sext, <i32 -1, i32 -1>
85 %r = and <2 x i32> %not, %x
89 define i32 @and_not_sext_to_sel_commute(i32 %px, i1 %y) {
90 ; CHECK-LABEL: @and_not_sext_to_sel_commute(
91 ; CHECK-NEXT: [[X:%.*]] = mul i32 [[PX:%.*]], [[PX]]
92 ; CHECK-NEXT: [[SEXT:%.*]] = sext i1 [[Y:%.*]] to i32
93 ; CHECK-NEXT: call void @use(i32 [[SEXT]])
94 ; CHECK-NEXT: [[NOT:%.*]] = xor i32 [[SEXT]], -1
95 ; CHECK-NEXT: call void @use(i32 [[NOT]])
96 ; CHECK-NEXT: [[R:%.*]] = select i1 [[Y]], i32 0, i32 [[X]]
97 ; CHECK-NEXT: ret i32 [[R]]
99 %x = mul i32 %px, %px ; thwart complexity-based canonicalization
100 %sext = sext i1 %y to i32
101 call void @use(i32 %sext)
102 %not = xor i32 %sext, -1
103 call void @use(i32 %not)
104 %r = and i32 %x, %not
108 ; negative test - must be 'not'
110 define i32 @and_xor_sext_to_sel(i32 %x, i1 %y) {
111 ; CHECK-LABEL: @and_xor_sext_to_sel(
112 ; CHECK-NEXT: [[SEXT:%.*]] = sext i1 [[Y:%.*]] to i32
113 ; CHECK-NEXT: call void @use(i32 [[SEXT]])
114 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[SEXT]], -2
115 ; CHECK-NEXT: [[R:%.*]] = and i32 [[XOR]], [[X:%.*]]
116 ; CHECK-NEXT: ret i32 [[R]]
118 %sext = sext i1 %y to i32
119 call void @use(i32 %sext)
120 %xor = xor i32 %sext, -2
121 %r = and i32 %xor, %x
125 ; negative test - must be 'sext'
127 define i32 @and_not_zext_to_sel(i32 %x, i1 %y) {
128 ; CHECK-LABEL: @and_not_zext_to_sel(
129 ; CHECK-NEXT: [[ZEXT:%.*]] = zext i1 [[Y:%.*]] to i32
130 ; CHECK-NEXT: call void @use(i32 [[ZEXT]])
131 ; CHECK-NEXT: [[NOT:%.*]] = xor i32 [[ZEXT]], -1
132 ; CHECK-NEXT: [[R:%.*]] = and i32 [[X:%.*]], [[NOT]]
133 ; CHECK-NEXT: ret i32 [[R]]
135 %zext = zext i1 %y to i32
136 call void @use(i32 %zext)
137 %not = xor i32 %zext, -1
138 %r = and i32 %not, %x
142 define i32 @or_sext_to_sel(i32 %x, i1 %y) {
143 ; CHECK-LABEL: @or_sext_to_sel(
144 ; CHECK-NEXT: [[R:%.*]] = select i1 [[Y:%.*]], i32 -1, i32 [[X:%.*]]
145 ; CHECK-NEXT: ret i32 [[R]]
147 %sext = sext i1 %y to i32
148 %r = or i32 %sext, %x
152 define <2 x i32> @or_sext_to_sel_constant_vec(<2 x i1> %y) {
153 ; CHECK-LABEL: @or_sext_to_sel_constant_vec(
154 ; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[Y:%.*]], <2 x i32> splat (i32 -1), <2 x i32> <i32 42, i32 -7>
155 ; CHECK-NEXT: ret <2 x i32> [[R]]
157 %sext = sext <2 x i1> %y to <2 x i32>
158 %r = or <2 x i32> <i32 42, i32 -7>, %sext
162 define <2 x i32> @or_sext_to_sel_swap(<2 x i32> %px, <2 x i1> %y) {
163 ; CHECK-LABEL: @or_sext_to_sel_swap(
164 ; CHECK-NEXT: [[X:%.*]] = mul <2 x i32> [[PX:%.*]], [[PX]]
165 ; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[Y:%.*]], <2 x i32> splat (i32 -1), <2 x i32> [[X]]
166 ; CHECK-NEXT: ret <2 x i32> [[R]]
168 %x = mul <2 x i32> %px, %px ; thwart complexity-based canonicalization
169 %sext = sext <2 x i1> %y to <2 x i32>
170 %r = or <2 x i32> %x, %sext
174 define i32 @or_sext_to_sel_multi_use(i32 %x, i1 %y) {
175 ; CHECK-LABEL: @or_sext_to_sel_multi_use(
176 ; CHECK-NEXT: [[SEXT:%.*]] = sext i1 [[Y:%.*]] to i32
177 ; CHECK-NEXT: call void @use(i32 [[SEXT]])
178 ; CHECK-NEXT: [[R:%.*]] = or i32 [[X:%.*]], [[SEXT]]
179 ; CHECK-NEXT: ret i32 [[R]]
181 %sext = sext i1 %y to i32
182 call void @use(i32 %sext)
183 %r = or i32 %sext, %x
187 define i32 @or_sext_to_sel_multi_use_constant_mask(i1 %y) {
188 ; CHECK-LABEL: @or_sext_to_sel_multi_use_constant_mask(
189 ; CHECK-NEXT: [[SEXT:%.*]] = sext i1 [[Y:%.*]] to i32
190 ; CHECK-NEXT: call void @use(i32 [[SEXT]])
191 ; CHECK-NEXT: [[R:%.*]] = select i1 [[Y]], i32 -1, i32 42
192 ; CHECK-NEXT: ret i32 [[R]]
194 %sext = sext i1 %y to i32
195 call void @use(i32 %sext)
196 %r = or i32 %sext, 42
200 define i32 @xor_sext_to_sel(i32 %x, i1 %y) {
201 ; CHECK-LABEL: @xor_sext_to_sel(
202 ; CHECK-NEXT: [[SEXT:%.*]] = sext i1 [[Y:%.*]] to i32
203 ; CHECK-NEXT: [[R:%.*]] = xor i32 [[X:%.*]], [[SEXT]]
204 ; CHECK-NEXT: ret i32 [[R]]
206 %sext = sext i1 %y to i32
207 %r = xor i32 %sext, %x
211 define <2 x i32> @xor_sext_to_sel_constant_vec(<2 x i1> %y) {
212 ; CHECK-LABEL: @xor_sext_to_sel_constant_vec(
213 ; CHECK-NEXT: [[SEXT:%.*]] = sext <2 x i1> [[Y:%.*]] to <2 x i32>
214 ; CHECK-NEXT: [[R:%.*]] = xor <2 x i32> [[SEXT]], <i32 42, i32 -7>
215 ; CHECK-NEXT: ret <2 x i32> [[R]]
217 %sext = sext <2 x i1> %y to <2 x i32>
218 %r = xor <2 x i32> <i32 42, i32 -7>, %sext
222 define <2 x i32> @xor_sext_to_sel_swap(<2 x i32> %px, <2 x i1> %y) {
223 ; CHECK-LABEL: @xor_sext_to_sel_swap(
224 ; CHECK-NEXT: [[X:%.*]] = mul <2 x i32> [[PX:%.*]], [[PX]]
225 ; CHECK-NEXT: [[SEXT:%.*]] = sext <2 x i1> [[Y:%.*]] to <2 x i32>
226 ; CHECK-NEXT: [[R:%.*]] = xor <2 x i32> [[X]], [[SEXT]]
227 ; CHECK-NEXT: ret <2 x i32> [[R]]
229 %x = mul <2 x i32> %px, %px ; thwart complexity-based canonicalization
230 %sext = sext <2 x i1> %y to <2 x i32>
231 %r = xor <2 x i32> %x, %sext
235 define i32 @xor_sext_to_sel_multi_use(i32 %x, i1 %y) {
236 ; CHECK-LABEL: @xor_sext_to_sel_multi_use(
237 ; CHECK-NEXT: [[SEXT:%.*]] = sext i1 [[Y:%.*]] to i32
238 ; CHECK-NEXT: call void @use(i32 [[SEXT]])
239 ; CHECK-NEXT: [[R:%.*]] = xor i32 [[X:%.*]], [[SEXT]]
240 ; CHECK-NEXT: ret i32 [[R]]
242 %sext = sext i1 %y to i32
243 call void @use(i32 %sext)
244 %r = xor i32 %sext, %x
248 define i32 @xor_sext_to_sel_multi_use_constant_mask(i1 %y) {
249 ; CHECK-LABEL: @xor_sext_to_sel_multi_use_constant_mask(
250 ; CHECK-NEXT: [[SEXT:%.*]] = sext i1 [[Y:%.*]] to i32
251 ; CHECK-NEXT: call void @use(i32 [[SEXT]])
252 ; CHECK-NEXT: [[R:%.*]] = xor i32 [[SEXT]], 42
253 ; CHECK-NEXT: ret i32 [[R]]
255 %sext = sext i1 %y to i32
256 call void @use(i32 %sext)
257 %r = xor i32 %sext, 42
261 define i64 @PR63321(ptr %ptr, i64 %c) {
262 ; CHECK-LABEL: @PR63321(
263 ; CHECK-NEXT: [[VAL:%.*]] = load i8, ptr [[PTR:%.*]], align 1, !range [[RNG0:![0-9]+]]
264 ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8 [[VAL]], 0
265 ; CHECK-NEXT: [[RES:%.*]] = select i1 [[TMP1]], i64 [[C:%.*]], i64 0
266 ; CHECK-NEXT: ret i64 [[RES]]
268 %val = load i8, ptr %ptr, align 1, !range !{i8 0, i8 2}
269 %rhs = zext i8 %val to i64
270 %mask = add i64 -1, %rhs
271 %res = and i64 %mask, %c
275 ; Negative test of PR63321
276 define i64 @and_add_non_bool(ptr %ptr, i64 %c) {
277 ; CHECK-LABEL: @and_add_non_bool(
278 ; CHECK-NEXT: [[VAL:%.*]] = load i8, ptr [[PTR:%.*]], align 1, !range [[RNG1:![0-9]+]]
279 ; CHECK-NEXT: [[RHS:%.*]] = zext nneg i8 [[VAL]] to i64
280 ; CHECK-NEXT: [[MASK:%.*]] = add nsw i64 [[RHS]], -1
281 ; CHECK-NEXT: [[RES:%.*]] = and i64 [[MASK]], [[C:%.*]]
282 ; CHECK-NEXT: ret i64 [[RES]]
284 %val = load i8, ptr %ptr, align 1, !range !{i8 0, i8 3}
285 %rhs = zext i8 %val to i64
286 %mask = add i64 -1, %rhs
287 %res = and i64 %mask, %c
291 define i32 @and_add_bool_to_select(i1 %x, i32 %y) {
292 ; CHECK-LABEL: @and_add_bool_to_select(
293 ; CHECK-NEXT: [[RES:%.*]] = select i1 [[X:%.*]], i32 0, i32 [[Y:%.*]]
294 ; CHECK-NEXT: ret i32 [[RES]]
296 %val = zext i1 %x to i32
297 %mask = add i32 -1, %val
298 %res = and i32 %mask, %y
302 define i32 @and_add_bool_no_fold(i32 %y) {
303 ; CHECK-LABEL: @and_add_bool_no_fold(
304 ; CHECK-NEXT: [[X:%.*]] = and i32 [[Y:%.*]], 1
305 ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[X]], 0
306 ; CHECK-NEXT: [[RES:%.*]] = select i1 [[TMP1]], i32 [[Y]], i32 0
307 ; CHECK-NEXT: ret i32 [[RES]]
310 %mask = add i32 -1, %x
311 %res = and i32 %mask, %y
315 define <2 x i32> @and_add_bool_vec_to_select(<2 x i1> %x, <2 x i32> %y) {
316 ; CHECK-LABEL: @and_add_bool_vec_to_select(
317 ; CHECK-NEXT: [[RES:%.*]] = select <2 x i1> [[X:%.*]], <2 x i32> zeroinitializer, <2 x i32> [[Y:%.*]]
318 ; CHECK-NEXT: ret <2 x i32> [[RES]]
320 %val = zext <2 x i1> %x to <2 x i32>
321 %mask = add <2 x i32> <i32 -1, i32 -1>, %val
322 %res = and <2 x i32> %mask, %y
326 ; Negative test of and_add_bool_to_select
327 define i32 @and_add_bool_to_select_multi_use(i1 %x, i32 %y) {
328 ; CHECK-LABEL: @and_add_bool_to_select_multi_use(
329 ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[Y:%.*]], -1
330 ; CHECK-NEXT: [[RET:%.*]] = select i1 [[X:%.*]], i32 0, i32 [[TMP1]]
331 ; CHECK-NEXT: ret i32 [[RET]]
333 %val = zext i1 %x to i32
334 %mask = add i32 -1, %val
335 %res = and i32 %mask, %y
336 %ret = add i32 %res, %mask