1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
6 define <4 x i32> @and(<4 x i32> %x, <4 x i32> %y) {
8 ; CHECK-NEXT: [[R:%.*]] = and <4 x i32> [[X:%.*]], [[Y:%.*]]
9 ; CHECK-NEXT: ret <4 x i32> [[R]]
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
17 define <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]]
23 %sel1 = shufflevector <vscale x 4 x i32> %x, <vscale x 4 x i32> poison, <vscale x 4 x i32> zeroinitializer
24 %sel2 = shufflevector <vscale x 4 x i32> %y, <vscale x 4 x i32> poison, <vscale x 4 x i32> zeroinitializer
25 %r = and <vscale x 4 x i32> %sel1, %sel2
26 ret <vscale x 4 x i32> %r
29 define <4 x i32> @or(<4 x i32> %x, <4 x i32> %y) {
31 ; CHECK-NEXT: [[R:%.*]] = or <4 x i32> [[X:%.*]], [[Y:%.*]]
32 ; CHECK-NEXT: ret <4 x i32> [[R]]
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
42 define <4 x i32> @xor(<4 x i32> %x, <4 x i32> %y) {
44 ; CHECK-NEXT: [[R:%.*]] = xor <4 x i32> [[Y:%.*]], [[X:%.*]]
45 ; CHECK-NEXT: ret <4 x i32> [[R]]
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
55 define <4 x i32> @add(<4 x i32> %x, <4 x i32> %y) {
57 ; CHECK-NEXT: [[R:%.*]] = add nsw <4 x i32> [[X:%.*]], [[Y:%.*]]
58 ; CHECK-NEXT: ret <4 x i32> [[R]]
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
66 ; Negative test - wrong operand
68 define <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]]
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
81 ; Negative test - wrong mask (but we could handle this...)
83 define <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]]
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
96 ; Negative test - wrong mask (but we could handle this...)
98 define <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]]
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
111 ; Non-commutative opcode
113 define <4 x i32> @sub(<4 x i32> %x, <4 x i32> %y) {
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]]
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
126 define <4 x i32> @mul(<4 x i32> %x, <4 x i32> %y) {
128 ; CHECK-NEXT: [[R:%.*]] = mul nuw <4 x i32> [[X:%.*]], [[Y:%.*]]
129 ; CHECK-NEXT: ret <4 x i32> [[R]]
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
137 define <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]]
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
150 define <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]]
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
163 define <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]]
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
176 define <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]]
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
189 define <4 x i32> @shl(<4 x i32> %x, <4 x i32> %y) {
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]]
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
202 define <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]]
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
215 define <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]]
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
228 define <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]]
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
239 define <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]]
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
252 define <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]]
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
263 define <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]]
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
276 define <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]]
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