1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -S -passes=instsimplify < %s | FileCheck %s
4 ; select(Y | X == 0, X, Y | X)
5 define i32 @select_or_1(i32 %x, i32 %y) {
6 ; CHECK-LABEL: @select_or_1(
7 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y:%.*]], [[X:%.*]]
8 ; CHECK-NEXT: ret i32 [[OR]]
11 %cmp = icmp eq i32 %or, 0
12 %ret = select i1 %cmp, i32 %x, i32 %or
16 ; select(Y | X == 0, Y, Y | X)
17 define i32 @select_or_2(i32 %x, i32 %y) {
18 ; CHECK-LABEL: @select_or_2(
19 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y:%.*]], [[X:%.*]]
20 ; CHECK-NEXT: ret i32 [[OR]]
23 %cmp = icmp eq i32 %or, 0
24 %ret = select i1 %cmp, i32 %y, i32 %or
28 ; select(Y | X != 0, Y | X, X)
29 define i32 @select_or_3(i32 %x, i32 %y) {
30 ; CHECK-LABEL: @select_or_3(
31 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y:%.*]], [[X:%.*]]
32 ; CHECK-NEXT: ret i32 [[OR]]
35 %cmp = icmp ne i32 %or, 0
36 %ret = select i1 %cmp, i32 %or, i32 %x
40 ; select(Y | X != 0, Y | X, Y)
41 define i32 @select_or_4(i32 %x, i32 %y) {
42 ; CHECK-LABEL: @select_or_4(
43 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y:%.*]], [[X:%.*]]
44 ; CHECK-NEXT: ret i32 [[OR]]
47 %cmp = icmp ne i32 %or, 0
48 %ret = select i1 %cmp, i32 %or, i32 %y
52 ; select(Y | X != 0, Y | X, Y)
53 define <4 x i32> @select_or_vec(<4 x i32> %x, <4 x i32> %y) {
54 ; CHECK-LABEL: @select_or_vec(
55 ; CHECK-NEXT: [[OR:%.*]] = or <4 x i32> [[Y:%.*]], [[X:%.*]]
56 ; CHECK-NEXT: ret <4 x i32> [[OR]]
58 %or = or <4 x i32> %y, %x
59 %cmp = icmp ne <4 x i32> %or, zeroinitializer
60 %ret = select <4 x i1> %cmp, <4 x i32> %or, <4 x i32> %y
64 ; select(Y | X == 0, Y | X, Y)
65 define i32 @select_or_not_1(i32 %x, i32 %y) {
66 ; CHECK-LABEL: @select_or_not_1(
67 ; CHECK-NEXT: ret i32 [[Y:%.*]]
70 %cmp = icmp eq i32 %or, 0
71 %ret = select i1 %cmp, i32 %or, i32 %y
74 ; select(Y | X != 0, Y, Y | X)
75 define i32 @select_or_not_2(i32 %x, i32 %y) {
76 ; CHECK-LABEL: @select_or_not_2(
77 ; CHECK-NEXT: ret i32 [[Y:%.*]]
80 %cmp = icmp ne i32 %or, 0
81 %ret = select i1 %cmp, i32 %y, i32 %or
84 ; select(Y | X != 1, Y, Y | X)
85 define i32 @select_or_not_3(i32 %x, i32 %y) {
86 ; CHECK-LABEL: @select_or_not_3(
87 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y:%.*]], [[X:%.*]]
88 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[OR]], 1
89 ; CHECK-NEXT: [[RET:%.*]] = select i1 [[CMP]], i32 [[Y]], i32 [[OR]]
90 ; CHECK-NEXT: ret i32 [[RET]]
93 %cmp = icmp ne i32 %or, 1
94 %ret = select i1 %cmp, i32 %y, i32 %or
98 ; select(Y & X == -1, X, Y & X)
99 define i32 @select_and_1(i32 %x, i32 %y) {
100 ; CHECK-LABEL: @select_and_1(
101 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y:%.*]], [[X:%.*]]
102 ; CHECK-NEXT: ret i32 [[AND]]
104 %and = and i32 %y, %x
105 %cmp = icmp eq i32 %and, -1
106 %ret = select i1 %cmp, i32 %x, i32 %and
110 ; select(Y & X == -1, Y, Y & X)
111 define i32 @select_and_2(i32 %x, i32 %y) {
112 ; CHECK-LABEL: @select_and_2(
113 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y:%.*]], [[X:%.*]]
114 ; CHECK-NEXT: ret i32 [[AND]]
116 %and = and i32 %y, %x
117 %cmp = icmp eq i32 %and, -1
118 %ret = select i1 %cmp, i32 %y, i32 %and
123 ; select(Y & X != -1, Y & X, X)
124 define i32 @select_and_3(i32 %x, i32 %y) {
125 ; CHECK-LABEL: @select_and_3(
126 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y:%.*]], [[X:%.*]]
127 ; CHECK-NEXT: ret i32 [[AND]]
129 %and = and i32 %y, %x
130 %cmp = icmp ne i32 %and, -1
131 %ret = select i1 %cmp, i32 %and, i32 %x
135 ; select(Y & X != -1, Y & X, Y)
136 define i32 @select_and_4(i32 %x, i32 %y) {
137 ; CHECK-LABEL: @select_and_4(
138 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y:%.*]], [[X:%.*]]
139 ; CHECK-NEXT: ret i32 [[AND]]
141 %and = and i32 %y, %x
142 %cmp = icmp ne i32 %and, -1
143 %ret = select i1 %cmp, i32 %and, i32 %y
147 ; select(Y & X != -1, Y, Y & X)
148 define i32 @select_and_not_1(i32 %x, i32 %y) {
149 ; CHECK-LABEL: @select_and_not_1(
150 ; CHECK-NEXT: ret i32 [[Y:%.*]]
152 %and = and i32 %y, %x
153 %cmp = icmp eq i32 %and, -1
154 %ret = select i1 %cmp, i32 %and, i32 %y
158 ; select(Y & X != -1, Y, Y & X)
159 define i32 @select_and_not_2(i32 %x, i32 %y) {
160 ; CHECK-LABEL: @select_and_not_2(
161 ; CHECK-NEXT: ret i32 [[Y:%.*]]
163 %and = and i32 %y, %x
164 %cmp = icmp ne i32 %and, -1
165 %ret = select i1 %cmp, i32 %y, i32 %and
169 ; select(Y & X != 123, Y, Y & X)
170 define i32 @select_and_not_3(i32 %x, i32 %y) {
171 ; CHECK-LABEL: @select_and_not_3(
172 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y:%.*]], [[X:%.*]]
173 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[AND]], 123
174 ; CHECK-NEXT: [[RET:%.*]] = select i1 [[CMP]], i32 [[Y]], i32 [[AND]]
175 ; CHECK-NEXT: ret i32 [[RET]]
177 %and = and i32 %y, %x
178 %cmp = icmp ne i32 %and, 123
179 %ret = select i1 %cmp, i32 %y, i32 %and
183 ; https://alive2.llvm.org/ce/z/1ILbih
184 define i32 @select_icmp_and_eq(i32 %a, i32 %b) {
185 ; CHECK-LABEL: @select_icmp_and_eq(
186 ; CHECK-NEXT: ret i32 -1
188 %and = and i32 %a, %b
189 %tobool = icmp eq i32 %and, -1
190 %cond = select i1 %tobool, i32 %a, i32 -1
194 define i32 @select_icmp_and_eq_commuted(i32 %a, i32 %b) {
195 ; CHECK-LABEL: @select_icmp_and_eq_commuted(
196 ; CHECK-NEXT: ret i32 -1
198 %and = and i32 %a, %b
199 %tobool = icmp eq i32 %and, -1
200 %cond = select i1 %tobool, i32 %b, i32 -1
204 ; https://alive2.llvm.org/ce/z/HfYXvx
205 define <2 x i16> @select_icmp_and_eq_vec(<2 x i16> %a, <2 x i16> %b) {
206 ; CHECK-LABEL: @select_icmp_and_eq_vec(
207 ; CHECK-NEXT: ret <2 x i16> <i16 -1, i16 -1>
209 %and = and <2 x i16> %a, %b
210 %tobool = icmp eq <2 x i16> %and, <i16 -1, i16 -1>
211 %cond = select <2 x i1> %tobool, <2 x i16> %a, <2 x i16> <i16 -1, i16 -1>
215 ; The ne should also be macthed
216 define i32 @select_icmp_and_ne(i32 %a, i32 %b) {
217 ; CHECK-LABEL: @select_icmp_and_ne(
218 ; CHECK-NEXT: ret i32 -1
220 %and = and i32 %a, %b
221 %tobool = icmp ne i32 %and, -1
222 %cond = select i1 %tobool, i32 -1, i32 %a
226 ; Negative test: Incorrect const value for icmp
227 define i32 @select_icmp_and_eq_incorrect_const(i32 %a, i32 %b) {
228 ; CHECK-LABEL: @select_icmp_and_eq_incorrect_const(
229 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[A:%.*]], [[B:%.*]]
230 ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[AND]], 0
231 ; CHECK-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i32 [[A]], i32 -1
232 ; CHECK-NEXT: ret i32 [[COND]]
234 %and = and i32 %a, %b
235 %tobool = icmp eq i32 %and, 0 ; Incorrect const value
236 %cond = select i1 %tobool, i32 %a, i32 -1
240 ; https://alive2.llvm.org/ce/z/hSyCuR
241 define i32 @select_icmp_or_eq(i32 %a, i32 %b) {
242 ; CHECK-LABEL: @select_icmp_or_eq(
243 ; CHECK-NEXT: ret i32 0
246 %tobool = icmp eq i32 %or, 0
247 %cond = select i1 %tobool, i32 %a, i32 0
251 define i32 @select_icmp_or_eq_commuted(i32 %a, i32 %b) {
252 ; CHECK-LABEL: @select_icmp_or_eq_commuted(
253 ; CHECK-NEXT: ret i32 0
256 %tobool = icmp eq i32 %or, 0
257 %cond = select i1 %tobool, i32 %b, i32 0
261 ; https://alive2.llvm.org/ce/z/S_pQek
262 define <2 x i16> @select_icmp_or_eq_vec(<2 x i16> %a, <2 x i16> %b) {
263 ; CHECK-LABEL: @select_icmp_or_eq_vec(
264 ; CHECK-NEXT: ret <2 x i16> zeroinitializer
266 %or = or <2 x i16> %a, %b
267 %tobool = icmp eq <2 x i16> %or, <i16 0, i16 0>
268 %cond = select <2 x i1> %tobool, <2 x i16> %a, <2 x i16> zeroinitializer
272 ; The ne will also be matched
273 define i32 @select_icmp_or_ne(i32 %a, i32 %b) {
274 ; CHECK-LABEL: @select_icmp_or_ne(
275 ; CHECK-NEXT: ret i32 0
278 %tobool = icmp ne i32 %or, 0
279 %cond = select i1 %tobool, i32 0, i32 %a
283 ; Negative test: Incorrect const value for icmp
284 define i32 @select_icmp_or_eq_incorrect_const(i32 %a, i32 %b) {
285 ; CHECK-LABEL: @select_icmp_or_eq_incorrect_const(
286 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[A:%.*]], [[B:%.*]]
287 ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[OR]], -1
288 ; CHECK-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i32 [[A]], i32 0
289 ; CHECK-NEXT: ret i32 [[COND]]
292 %tobool = icmp eq i32 %or, -1
293 %cond = select i1 %tobool, i32 %a, i32 0