[DAGCombiner] Add target hook function to decide folding (mul (add x, c1), c2)
[llvm-project.git] / llvm / test / Transforms / InstCombine / vec-binop-select.ll
blob415dc5deff16d2fc0cc10d2b77a39546b8202fbf
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -instcombine -S | FileCheck %s
4 ; Non-canonical mask
6 define <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]]
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
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:    [[R:%.*]] = and <vscale x 4 x i32> [[X:%.*]], [[Y:%.*]]
20 ; CHECK-NEXT:    [[S:%.*]] = shufflevector <vscale x 4 x i32> [[R]], <vscale x 4 x i32> undef, <vscale x 4 x i32> zeroinitializer
21 ; CHECK-NEXT:    ret <vscale x 4 x i32> [[S]]
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
29 define <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]]
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
40 ; Non-canonical masks
42 define <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]]
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
53 ; Flags
55 define <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]]
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
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
78   ret <4 x i32> %r
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
93   ret <4 x i32> %r
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 undef, i32 5, i32 2, i32 7>
101 ; CHECK-NEXT:    [[SEL2:%.*]] = shufflevector <4 x i32> [[Y]], <4 x i32> [[X]], <4 x i32> <i32 undef, 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
108   ret <4 x i32> %r
111 ; Non-commutative opcode
113 define <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]]
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
126 define <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]]
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
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
147   ret <4 x i32> %r
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
160   ret <4 x i32> %r
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
173   ret <4 x i32> %r
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
186   ret <4 x i32> %r
189 define <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]]
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
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
212   ret <4 x i32> %r
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
225   ret <4 x i32> %r
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
236   ret <4 x float> %r
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
249   ret <4 x float> %r
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
260   ret <4 x double> %r
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
273   ret <4 x double> %r
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
286   ret <4 x double> %r