xref: /llvm-project/llvm/test/Transforms/InstCombine/vec-binop-select.ll (revision 8b56da5e9f3ba737a5ff4bf5dee654416849042f)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=instcombine -S | FileCheck %s
3
4; Non-canonical mask
5
6define <4 x i32> @and(<4 x i32> %x, <4 x i32> %y) {
7; CHECK-LABEL: @and(
8; CHECK-NEXT:    [[R:%.*]] = and <4 x i32> [[X:%.*]], [[Y:%.*]]
9; CHECK-NEXT:    ret <4 x i32> [[R]]
10;
11  %sel1 = shufflevector <4 x i32> %x, <4 x i32> %y, <4 x i32> <i32 0, i32 5, i32 6, i32 3>
12  %sel2 = shufflevector <4 x i32> %x, <4 x i32> %y, <4 x i32> <i32 4, i32 1, i32 2, i32 7>
13  %r = and <4 x i32> %sel1, %sel2
14  ret <4 x i32> %r
15}
16
17define <vscale x 4 x i32> @vscaleand(<vscale x 4 x i32> %x, <vscale x 4 x i32> %y) {
18; CHECK-LABEL: @vscaleand(
19; CHECK-NEXT:    [[TMP1:%.*]] = and <vscale x 4 x i32> [[X:%.*]], [[Y:%.*]]
20; CHECK-NEXT:    [[R:%.*]] = shufflevector <vscale x 4 x i32> [[TMP1]], <vscale x 4 x i32> poison, <vscale x 4 x i32> zeroinitializer
21; CHECK-NEXT:    ret <vscale x 4 x i32> [[R]]
22;
23  %sel1 = shufflevector <vscale x 4 x i32> %x, <vscale x 4 x i32> undef, <vscale x 4 x i32> zeroinitializer
24  %sel2 = shufflevector <vscale x 4 x i32> %y, <vscale x 4 x i32> undef, <vscale x 4 x i32> zeroinitializer
25  %r = and <vscale x 4 x i32> %sel1, %sel2
26  ret <vscale x 4 x i32> %r
27}
28
29define <4 x i32> @or(<4 x i32> %x, <4 x i32> %y) {
30; CHECK-LABEL: @or(
31; CHECK-NEXT:    [[R:%.*]] = or <4 x i32> [[X:%.*]], [[Y:%.*]]
32; CHECK-NEXT:    ret <4 x i32> [[R]]
33;
34  %sel1 = shufflevector <4 x i32> %x, <4 x i32> %y, <4 x i32> <i32 0, i32 5, i32 6, i32 3>
35  %sel2 = shufflevector <4 x i32> %y, <4 x i32> %x, <4 x i32> <i32 0, i32 5, i32 6, i32 3>
36  %r = or <4 x i32> %sel1, %sel2
37  ret <4 x i32> %r
38}
39
40; Non-canonical masks
41
42define <4 x i32> @xor(<4 x i32> %x, <4 x i32> %y) {
43; CHECK-LABEL: @xor(
44; CHECK-NEXT:    [[R:%.*]] = xor <4 x i32> [[Y:%.*]], [[X:%.*]]
45; CHECK-NEXT:    ret <4 x i32> [[R]]
46;
47  %sel1 = shufflevector <4 x i32> %x, <4 x i32> %y, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
48  %sel2 = shufflevector <4 x i32> %y, <4 x i32> %x, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
49  %r = xor <4 x i32> %sel1, %sel2
50  ret <4 x i32> %r
51}
52
53; Flags
54
55define <4 x i32> @add(<4 x i32> %x, <4 x i32> %y) {
56; CHECK-LABEL: @add(
57; CHECK-NEXT:    [[R:%.*]] = add nsw <4 x i32> [[X:%.*]], [[Y:%.*]]
58; CHECK-NEXT:    ret <4 x i32> [[R]]
59;
60  %sel1 = shufflevector <4 x i32> %x, <4 x i32> %y, <4 x i32> <i32 0, i32 5, i32 2, i32 7>
61  %sel2 = shufflevector <4 x i32> %y, <4 x i32> %x, <4 x i32> <i32 0, i32 5, i32 2, i32 7>
62  %r = add nsw <4 x i32> %sel1, %sel2
63  ret <4 x i32> %r
64}
65
66; Negative test - wrong operand
67
68define <4 x i32> @add_wrong_op(<4 x i32> %x, <4 x i32> %y, <4 x i32> %z) {
69; CHECK-LABEL: @add_wrong_op(
70; CHECK-NEXT:    [[SEL1:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]], <4 x i32> <i32 0, i32 5, i32 2, i32 7>
71; CHECK-NEXT:    [[SEL2:%.*]] = shufflevector <4 x i32> [[Y]], <4 x i32> [[Z:%.*]], <4 x i32> <i32 0, i32 5, i32 2, i32 7>
72; CHECK-NEXT:    [[R:%.*]] = add nsw <4 x i32> [[SEL1]], [[SEL2]]
73; CHECK-NEXT:    ret <4 x i32> [[R]]
74;
75  %sel1 = shufflevector <4 x i32> %x, <4 x i32> %y, <4 x i32> <i32 0, i32 5, i32 2, i32 7>
76  %sel2 = shufflevector <4 x i32> %y, <4 x i32> %z, <4 x i32> <i32 0, i32 5, i32 2, i32 7>
77  %r = add nsw <4 x i32> %sel1, %sel2
78  ret <4 x i32> %r
79}
80
81; Negative test - wrong mask (but we could handle this...)
82
83define <4 x i32> @add_non_select_mask(<4 x i32> %x, <4 x i32> %y) {
84; CHECK-LABEL: @add_non_select_mask(
85; CHECK-NEXT:    [[SEL1:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]], <4 x i32> <i32 1, i32 5, i32 2, i32 7>
86; CHECK-NEXT:    [[SEL2:%.*]] = shufflevector <4 x i32> [[Y]], <4 x i32> [[X]], <4 x i32> <i32 1, i32 5, i32 2, i32 7>
87; CHECK-NEXT:    [[R:%.*]] = add nsw <4 x i32> [[SEL1]], [[SEL2]]
88; CHECK-NEXT:    ret <4 x i32> [[R]]
89;
90  %sel1 = shufflevector <4 x i32> %x, <4 x i32> %y, <4 x i32> <i32 1, i32 5, i32 2, i32 7>
91  %sel2 = shufflevector <4 x i32> %y, <4 x i32> %x, <4 x i32> <i32 1, i32 5, i32 2, i32 7>
92  %r = add nsw <4 x i32> %sel1, %sel2
93  ret <4 x i32> %r
94}
95
96; Negative test - wrong mask (but we could handle this...)
97
98define <4 x i32> @add_masks_with_undefs(<4 x i32> %x, <4 x i32> %y) {
99; CHECK-LABEL: @add_masks_with_undefs(
100; CHECK-NEXT:    [[SEL1:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]], <4 x i32> <i32 poison, i32 5, i32 2, i32 7>
101; CHECK-NEXT:    [[SEL2:%.*]] = shufflevector <4 x i32> [[Y]], <4 x i32> [[X]], <4 x i32> <i32 poison, i32 5, i32 2, i32 7>
102; CHECK-NEXT:    [[R:%.*]] = add nsw <4 x i32> [[SEL1]], [[SEL2]]
103; CHECK-NEXT:    ret <4 x i32> [[R]]
104;
105  %sel1 = shufflevector <4 x i32> %x, <4 x i32> %y, <4 x i32> <i32 undef, i32 5, i32 2, i32 7>
106  %sel2 = shufflevector <4 x i32> %y, <4 x i32> %x, <4 x i32> <i32 undef, i32 5, i32 2, i32 7>
107  %r = add nsw <4 x i32> %sel1, %sel2
108  ret <4 x i32> %r
109}
110
111; Non-commutative opcode
112
113define <4 x i32> @sub(<4 x i32> %x, <4 x i32> %y) {
114; CHECK-LABEL: @sub(
115; CHECK-NEXT:    [[SEL1:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]], <4 x i32> <i32 0, i32 1, i32 6, i32 3>
116; CHECK-NEXT:    [[SEL2:%.*]] = shufflevector <4 x i32> [[Y]], <4 x i32> [[X]], <4 x i32> <i32 0, i32 1, i32 6, i32 3>
117; CHECK-NEXT:    [[R:%.*]] = sub <4 x i32> [[SEL1]], [[SEL2]]
118; CHECK-NEXT:    ret <4 x i32> [[R]]
119;
120  %sel1 = shufflevector <4 x i32> %x, <4 x i32> %y, <4 x i32> <i32 0, i32 1, i32 6, i32 3>
121  %sel2 = shufflevector <4 x i32> %y, <4 x i32> %x, <4 x i32> <i32 0, i32 1, i32 6, i32 3>
122  %r = sub <4 x i32> %sel1, %sel2
123  ret <4 x i32> %r
124}
125
126define <4 x i32> @mul(<4 x i32> %x, <4 x i32> %y) {
127; CHECK-LABEL: @mul(
128; CHECK-NEXT:    [[R:%.*]] = mul nuw <4 x i32> [[X:%.*]], [[Y:%.*]]
129; CHECK-NEXT:    ret <4 x i32> [[R]]
130;
131  %sel1 = shufflevector <4 x i32> %x, <4 x i32> %y, <4 x i32> <i32 0, i32 1, i32 6, i32 3>
132  %sel2 = shufflevector <4 x i32> %y, <4 x i32> %x, <4 x i32> <i32 0, i32 1, i32 6, i32 3>
133  %r = mul nuw <4 x i32> %sel1, %sel2
134  ret <4 x i32> %r
135}
136
137define <4 x i32> @sdiv(<4 x i32> %x, <4 x i32> %y) {
138; CHECK-LABEL: @sdiv(
139; CHECK-NEXT:    [[SEL1:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]], <4 x i32> <i32 0, i32 1, i32 6, i32 7>
140; CHECK-NEXT:    [[SEL2:%.*]] = shufflevector <4 x i32> [[Y]], <4 x i32> [[X]], <4 x i32> <i32 0, i32 1, i32 6, i32 7>
141; CHECK-NEXT:    [[R:%.*]] = sdiv <4 x i32> [[SEL1]], [[SEL2]]
142; CHECK-NEXT:    ret <4 x i32> [[R]]
143;
144  %sel1 = shufflevector <4 x i32> %x, <4 x i32> %y, <4 x i32> <i32 0, i32 1, i32 6, i32 7>
145  %sel2 = shufflevector <4 x i32> %y, <4 x i32> %x, <4 x i32> <i32 0, i32 1, i32 6, i32 7>
146  %r = sdiv <4 x i32> %sel1, %sel2
147  ret <4 x i32> %r
148}
149
150define <4 x i32> @udiv(<4 x i32> %x, <4 x i32> %y) {
151; CHECK-LABEL: @udiv(
152; CHECK-NEXT:    [[SEL1:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]], <4 x i32> <i32 0, i32 1, i32 6, i32 3>
153; CHECK-NEXT:    [[SEL2:%.*]] = shufflevector <4 x i32> [[Y]], <4 x i32> [[X]], <4 x i32> <i32 0, i32 1, i32 6, i32 3>
154; CHECK-NEXT:    [[R:%.*]] = udiv <4 x i32> [[SEL1]], [[SEL2]]
155; CHECK-NEXT:    ret <4 x i32> [[R]]
156;
157  %sel1 = shufflevector <4 x i32> %x, <4 x i32> %y, <4 x i32> <i32 0, i32 1, i32 6, i32 3>
158  %sel2 = shufflevector <4 x i32> %y, <4 x i32> %x, <4 x i32> <i32 0, i32 1, i32 6, i32 3>
159  %r = udiv <4 x i32> %sel1, %sel2
160  ret <4 x i32> %r
161}
162
163define <4 x i32> @srem(<4 x i32> %x, <4 x i32> %y) {
164; CHECK-LABEL: @srem(
165; CHECK-NEXT:    [[SEL1:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]], <4 x i32> <i32 0, i32 1, i32 6, i32 7>
166; CHECK-NEXT:    [[SEL2:%.*]] = shufflevector <4 x i32> [[Y]], <4 x i32> [[X]], <4 x i32> <i32 0, i32 1, i32 6, i32 7>
167; CHECK-NEXT:    [[R:%.*]] = srem <4 x i32> [[SEL1]], [[SEL2]]
168; CHECK-NEXT:    ret <4 x i32> [[R]]
169;
170  %sel1 = shufflevector <4 x i32> %x, <4 x i32> %y, <4 x i32> <i32 0, i32 1, i32 6, i32 7>
171  %sel2 = shufflevector <4 x i32> %y, <4 x i32> %x, <4 x i32> <i32 0, i32 1, i32 6, i32 7>
172  %r = srem <4 x i32> %sel1, %sel2
173  ret <4 x i32> %r
174}
175
176define <4 x i32> @urem(<4 x i32> %x, <4 x i32> %y) {
177; CHECK-LABEL: @urem(
178; CHECK-NEXT:    [[SEL1:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]], <4 x i32> <i32 0, i32 1, i32 6, i32 3>
179; CHECK-NEXT:    [[SEL2:%.*]] = shufflevector <4 x i32> [[Y]], <4 x i32> [[X]], <4 x i32> <i32 0, i32 1, i32 6, i32 3>
180; CHECK-NEXT:    [[R:%.*]] = urem <4 x i32> [[SEL1]], [[SEL2]]
181; CHECK-NEXT:    ret <4 x i32> [[R]]
182;
183  %sel1 = shufflevector <4 x i32> %x, <4 x i32> %y, <4 x i32> <i32 0, i32 1, i32 6, i32 3>
184  %sel2 = shufflevector <4 x i32> %y, <4 x i32> %x, <4 x i32> <i32 0, i32 1, i32 6, i32 3>
185  %r = urem <4 x i32> %sel1, %sel2
186  ret <4 x i32> %r
187}
188
189define <4 x i32> @shl(<4 x i32> %x, <4 x i32> %y) {
190; CHECK-LABEL: @shl(
191; CHECK-NEXT:    [[SEL1:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]], <4 x i32> <i32 0, i32 1, i32 6, i32 7>
192; CHECK-NEXT:    [[SEL2:%.*]] = shufflevector <4 x i32> [[Y]], <4 x i32> [[X]], <4 x i32> <i32 0, i32 1, i32 6, i32 7>
193; CHECK-NEXT:    [[R:%.*]] = shl nsw <4 x i32> [[SEL1]], [[SEL2]]
194; CHECK-NEXT:    ret <4 x i32> [[R]]
195;
196  %sel1 = shufflevector <4 x i32> %x, <4 x i32> %y, <4 x i32> <i32 0, i32 1, i32 6, i32 7>
197  %sel2 = shufflevector <4 x i32> %y, <4 x i32> %x, <4 x i32> <i32 0, i32 1, i32 6, i32 7>
198  %r = shl nsw <4 x i32> %sel1, %sel2
199  ret <4 x i32> %r
200}
201
202define <4 x i32> @lshr(<4 x i32> %x, <4 x i32> %y) {
203; CHECK-LABEL: @lshr(
204; CHECK-NEXT:    [[SEL1:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]], <4 x i32> <i32 0, i32 5, i32 6, i32 3>
205; CHECK-NEXT:    [[SEL2:%.*]] = shufflevector <4 x i32> [[Y]], <4 x i32> [[X]], <4 x i32> <i32 0, i32 5, i32 6, i32 3>
206; CHECK-NEXT:    [[R:%.*]] = lshr exact <4 x i32> [[SEL1]], [[SEL2]]
207; CHECK-NEXT:    ret <4 x i32> [[R]]
208;
209  %sel1 = shufflevector <4 x i32> %x, <4 x i32> %y, <4 x i32> <i32 0, i32 5, i32 6, i32 3>
210  %sel2 = shufflevector <4 x i32> %y, <4 x i32> %x, <4 x i32> <i32 0, i32 5, i32 6, i32 3>
211  %r = lshr exact <4 x i32> %sel1, %sel2
212  ret <4 x i32> %r
213}
214
215define <4 x i32> @ashr(<4 x i32> %x, <4 x i32> %y) {
216; CHECK-LABEL: @ashr(
217; CHECK-NEXT:    [[SEL1:%.*]] = shufflevector <4 x i32> [[Y:%.*]], <4 x i32> [[X:%.*]], <4 x i32> <i32 0, i32 5, i32 2, i32 7>
218; CHECK-NEXT:    [[SEL2:%.*]] = shufflevector <4 x i32> [[X]], <4 x i32> [[Y]], <4 x i32> <i32 0, i32 5, i32 2, i32 7>
219; CHECK-NEXT:    [[R:%.*]] = ashr <4 x i32> [[SEL1]], [[SEL2]]
220; CHECK-NEXT:    ret <4 x i32> [[R]]
221;
222  %sel1 = shufflevector <4 x i32> %x, <4 x i32> %y, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
223  %sel2 = shufflevector <4 x i32> %y, <4 x i32> %x, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
224  %r = ashr <4 x i32> %sel1, %sel2
225  ret <4 x i32> %r
226}
227
228define <4 x float> @fadd(<4 x float> %x, <4 x float> %y) {
229; CHECK-LABEL: @fadd(
230; CHECK-NEXT:    [[R:%.*]] = fadd <4 x float> [[Y:%.*]], [[X:%.*]]
231; CHECK-NEXT:    ret <4 x float> [[R]]
232;
233  %sel1 = shufflevector <4 x float> %x, <4 x float> %y, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
234  %sel2 = shufflevector <4 x float> %y, <4 x float> %x, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
235  %r = fadd <4 x float> %sel1, %sel2
236  ret <4 x float> %r
237}
238
239define <4 x float> @fsub(<4 x float> %x, <4 x float> %y) {
240; CHECK-LABEL: @fsub(
241; CHECK-NEXT:    [[SEL1:%.*]] = shufflevector <4 x float> [[Y:%.*]], <4 x float> [[X:%.*]], <4 x i32> <i32 0, i32 5, i32 2, i32 7>
242; CHECK-NEXT:    [[SEL2:%.*]] = shufflevector <4 x float> [[X]], <4 x float> [[Y]], <4 x i32> <i32 0, i32 5, i32 2, i32 7>
243; CHECK-NEXT:    [[R:%.*]] = fsub fast <4 x float> [[SEL1]], [[SEL2]]
244; CHECK-NEXT:    ret <4 x float> [[R]]
245;
246  %sel1 = shufflevector <4 x float> %x, <4 x float> %y, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
247  %sel2 = shufflevector <4 x float> %y, <4 x float> %x, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
248  %r = fsub fast <4 x float> %sel1, %sel2
249  ret <4 x float> %r
250}
251
252define <4 x double> @fmul(<4 x double> %x, <4 x double> %y) {
253; CHECK-LABEL: @fmul(
254; CHECK-NEXT:    [[R:%.*]] = fmul nnan <4 x double> [[Y:%.*]], [[X:%.*]]
255; CHECK-NEXT:    ret <4 x double> [[R]]
256;
257  %sel1 = shufflevector <4 x double> %x, <4 x double> %y, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
258  %sel2 = shufflevector <4 x double> %y, <4 x double> %x, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
259  %r = fmul nnan <4 x double> %sel1, %sel2
260  ret <4 x double> %r
261}
262
263define <4 x double> @fdiv(<4 x double> %x, <4 x double> %y) {
264; CHECK-LABEL: @fdiv(
265; CHECK-NEXT:    [[SEL1:%.*]] = shufflevector <4 x double> [[Y:%.*]], <4 x double> [[X:%.*]], <4 x i32> <i32 0, i32 5, i32 2, i32 7>
266; CHECK-NEXT:    [[SEL2:%.*]] = shufflevector <4 x double> [[X]], <4 x double> [[Y]], <4 x i32> <i32 0, i32 5, i32 2, i32 7>
267; CHECK-NEXT:    [[R:%.*]] = fdiv nnan arcp <4 x double> [[SEL1]], [[SEL2]]
268; CHECK-NEXT:    ret <4 x double> [[R]]
269;
270  %sel1 = shufflevector <4 x double> %x, <4 x double> %y, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
271  %sel2 = shufflevector <4 x double> %y, <4 x double> %x, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
272  %r = fdiv arcp nnan <4 x double> %sel1, %sel2
273  ret <4 x double> %r
274}
275
276define <4 x double> @frem(<4 x double> %x, <4 x double> %y) {
277; CHECK-LABEL: @frem(
278; CHECK-NEXT:    [[SEL1:%.*]] = shufflevector <4 x double> [[Y:%.*]], <4 x double> [[X:%.*]], <4 x i32> <i32 0, i32 5, i32 2, i32 7>
279; CHECK-NEXT:    [[SEL2:%.*]] = shufflevector <4 x double> [[X]], <4 x double> [[Y]], <4 x i32> <i32 0, i32 5, i32 2, i32 7>
280; CHECK-NEXT:    [[R:%.*]] = frem <4 x double> [[SEL1]], [[SEL2]]
281; CHECK-NEXT:    ret <4 x double> [[R]]
282;
283  %sel1 = shufflevector <4 x double> %x, <4 x double> %y, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
284  %sel2 = shufflevector <4 x double> %y, <4 x double> %x, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
285  %r = frem <4 x double> %sel1, %sel2
286  ret <4 x double> %r
287}
288