[ARM] Better OR's for MVE compares
[llvm-core.git] / test / Transforms / InstCombine / vec-binop-select.ll
blobabf4729e36956e58a73f7204c172984a10074835
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 <4 x i32> @or(<4 x i32> %x, <4 x i32> %y) {
18 ; CHECK-LABEL: @or(
19 ; CHECK-NEXT:    [[R:%.*]] = or <4 x i32> [[X:%.*]], [[Y:%.*]]
20 ; CHECK-NEXT:    ret <4 x i32> [[R]]
22   %sel1 = shufflevector <4 x i32> %x, <4 x i32> %y, <4 x i32> <i32 0, i32 5, i32 6, i32 3>
23   %sel2 = shufflevector <4 x i32> %y, <4 x i32> %x, <4 x i32> <i32 0, i32 5, i32 6, i32 3>
24   %r = or <4 x i32> %sel1, %sel2
25   ret <4 x i32> %r
28 ; Non-canonical masks
30 define <4 x i32> @xor(<4 x i32> %x, <4 x i32> %y) {
31 ; CHECK-LABEL: @xor(
32 ; CHECK-NEXT:    [[R:%.*]] = xor <4 x i32> [[Y:%.*]], [[X:%.*]]
33 ; CHECK-NEXT:    ret <4 x i32> [[R]]
35   %sel1 = shufflevector <4 x i32> %x, <4 x i32> %y, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
36   %sel2 = shufflevector <4 x i32> %y, <4 x i32> %x, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
37   %r = xor <4 x i32> %sel1, %sel2
38   ret <4 x i32> %r
41 ; Flags
43 define <4 x i32> @add(<4 x i32> %x, <4 x i32> %y) {
44 ; CHECK-LABEL: @add(
45 ; CHECK-NEXT:    [[R:%.*]] = add nsw <4 x i32> [[X:%.*]], [[Y:%.*]]
46 ; CHECK-NEXT:    ret <4 x i32> [[R]]
48   %sel1 = shufflevector <4 x i32> %x, <4 x i32> %y, <4 x i32> <i32 0, i32 5, i32 2, i32 7>
49   %sel2 = shufflevector <4 x i32> %y, <4 x i32> %x, <4 x i32> <i32 0, i32 5, i32 2, i32 7>
50   %r = add nsw <4 x i32> %sel1, %sel2
51   ret <4 x i32> %r
54 ; Negative test - wrong operand
56 define <4 x i32> @add_wrong_op(<4 x i32> %x, <4 x i32> %y, <4 x i32> %z) {
57 ; CHECK-LABEL: @add_wrong_op(
58 ; CHECK-NEXT:    [[SEL1:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]], <4 x i32> <i32 0, i32 5, i32 2, i32 7>
59 ; CHECK-NEXT:    [[SEL2:%.*]] = shufflevector <4 x i32> [[Y]], <4 x i32> [[Z:%.*]], <4 x i32> <i32 0, i32 5, i32 2, i32 7>
60 ; CHECK-NEXT:    [[R:%.*]] = add nsw <4 x i32> [[SEL1]], [[SEL2]]
61 ; CHECK-NEXT:    ret <4 x i32> [[R]]
63   %sel1 = shufflevector <4 x i32> %x, <4 x i32> %y, <4 x i32> <i32 0, i32 5, i32 2, i32 7>
64   %sel2 = shufflevector <4 x i32> %y, <4 x i32> %z, <4 x i32> <i32 0, i32 5, i32 2, i32 7>
65   %r = add nsw <4 x i32> %sel1, %sel2
66   ret <4 x i32> %r
69 ; Negative test - wrong mask (but we could handle this...)
71 define <4 x i32> @add_non_select_mask(<4 x i32> %x, <4 x i32> %y) {
72 ; CHECK-LABEL: @add_non_select_mask(
73 ; CHECK-NEXT:    [[SEL1:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]], <4 x i32> <i32 1, i32 5, i32 2, i32 7>
74 ; CHECK-NEXT:    [[SEL2:%.*]] = shufflevector <4 x i32> [[Y]], <4 x i32> [[X]], <4 x i32> <i32 1, i32 5, i32 2, i32 7>
75 ; CHECK-NEXT:    [[R:%.*]] = add nsw <4 x i32> [[SEL1]], [[SEL2]]
76 ; CHECK-NEXT:    ret <4 x i32> [[R]]
78   %sel1 = shufflevector <4 x i32> %x, <4 x i32> %y, <4 x i32> <i32 1, i32 5, i32 2, i32 7>
79   %sel2 = shufflevector <4 x i32> %y, <4 x i32> %x, <4 x i32> <i32 1, i32 5, i32 2, i32 7>
80   %r = add nsw <4 x i32> %sel1, %sel2
81   ret <4 x i32> %r
84 ; Negative test - wrong mask (but we could handle this...)
86 define <4 x i32> @add_masks_with_undefs(<4 x i32> %x, <4 x i32> %y) {
87 ; CHECK-LABEL: @add_masks_with_undefs(
88 ; CHECK-NEXT:    [[SEL1:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]], <4 x i32> <i32 undef, i32 5, i32 2, i32 7>
89 ; CHECK-NEXT:    [[SEL2:%.*]] = shufflevector <4 x i32> [[Y]], <4 x i32> [[X]], <4 x i32> <i32 undef, i32 5, i32 2, i32 7>
90 ; CHECK-NEXT:    [[R:%.*]] = add nsw <4 x i32> [[SEL1]], [[SEL2]]
91 ; CHECK-NEXT:    ret <4 x i32> [[R]]
93   %sel1 = shufflevector <4 x i32> %x, <4 x i32> %y, <4 x i32> <i32 undef, i32 5, i32 2, i32 7>
94   %sel2 = shufflevector <4 x i32> %y, <4 x i32> %x, <4 x i32> <i32 undef, i32 5, i32 2, i32 7>
95   %r = add nsw <4 x i32> %sel1, %sel2
96   ret <4 x i32> %r
99 ; Non-commutative opcode
101 define <4 x i32> @sub(<4 x i32> %x, <4 x i32> %y) {
102 ; CHECK-LABEL: @sub(
103 ; CHECK-NEXT:    [[SEL1:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]], <4 x i32> <i32 0, i32 1, i32 6, i32 3>
104 ; CHECK-NEXT:    [[SEL2:%.*]] = shufflevector <4 x i32> [[Y]], <4 x i32> [[X]], <4 x i32> <i32 0, i32 1, i32 6, i32 3>
105 ; CHECK-NEXT:    [[R:%.*]] = sub <4 x i32> [[SEL1]], [[SEL2]]
106 ; CHECK-NEXT:    ret <4 x i32> [[R]]
108   %sel1 = shufflevector <4 x i32> %x, <4 x i32> %y, <4 x i32> <i32 0, i32 1, i32 6, i32 3>
109   %sel2 = shufflevector <4 x i32> %y, <4 x i32> %x, <4 x i32> <i32 0, i32 1, i32 6, i32 3>
110   %r = sub <4 x i32> %sel1, %sel2
111   ret <4 x i32> %r
114 define <4 x i32> @mul(<4 x i32> %x, <4 x i32> %y) {
115 ; CHECK-LABEL: @mul(
116 ; CHECK-NEXT:    [[R:%.*]] = mul nuw <4 x i32> [[X:%.*]], [[Y:%.*]]
117 ; CHECK-NEXT:    ret <4 x i32> [[R]]
119   %sel1 = shufflevector <4 x i32> %x, <4 x i32> %y, <4 x i32> <i32 0, i32 1, i32 6, i32 3>
120   %sel2 = shufflevector <4 x i32> %y, <4 x i32> %x, <4 x i32> <i32 0, i32 1, i32 6, i32 3>
121   %r = mul nuw <4 x i32> %sel1, %sel2
122   ret <4 x i32> %r
125 define <4 x i32> @sdiv(<4 x i32> %x, <4 x i32> %y) {
126 ; CHECK-LABEL: @sdiv(
127 ; CHECK-NEXT:    [[SEL1:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]], <4 x i32> <i32 0, i32 1, i32 6, i32 7>
128 ; CHECK-NEXT:    [[SEL2:%.*]] = shufflevector <4 x i32> [[Y]], <4 x i32> [[X]], <4 x i32> <i32 0, i32 1, i32 6, i32 7>
129 ; CHECK-NEXT:    [[R:%.*]] = sdiv <4 x i32> [[SEL1]], [[SEL2]]
130 ; CHECK-NEXT:    ret <4 x i32> [[R]]
132   %sel1 = shufflevector <4 x i32> %x, <4 x i32> %y, <4 x i32> <i32 0, i32 1, i32 6, i32 7>
133   %sel2 = shufflevector <4 x i32> %y, <4 x i32> %x, <4 x i32> <i32 0, i32 1, i32 6, i32 7>
134   %r = sdiv <4 x i32> %sel1, %sel2
135   ret <4 x i32> %r
138 define <4 x i32> @udiv(<4 x i32> %x, <4 x i32> %y) {
139 ; CHECK-LABEL: @udiv(
140 ; CHECK-NEXT:    [[SEL1:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]], <4 x i32> <i32 0, i32 1, i32 6, i32 3>
141 ; CHECK-NEXT:    [[SEL2:%.*]] = shufflevector <4 x i32> [[Y]], <4 x i32> [[X]], <4 x i32> <i32 0, i32 1, i32 6, i32 3>
142 ; CHECK-NEXT:    [[R:%.*]] = udiv <4 x i32> [[SEL1]], [[SEL2]]
143 ; CHECK-NEXT:    ret <4 x i32> [[R]]
145   %sel1 = shufflevector <4 x i32> %x, <4 x i32> %y, <4 x i32> <i32 0, i32 1, i32 6, i32 3>
146   %sel2 = shufflevector <4 x i32> %y, <4 x i32> %x, <4 x i32> <i32 0, i32 1, i32 6, i32 3>
147   %r = udiv <4 x i32> %sel1, %sel2
148   ret <4 x i32> %r
151 define <4 x i32> @srem(<4 x i32> %x, <4 x i32> %y) {
152 ; CHECK-LABEL: @srem(
153 ; CHECK-NEXT:    [[SEL1:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]], <4 x i32> <i32 0, i32 1, i32 6, i32 7>
154 ; CHECK-NEXT:    [[SEL2:%.*]] = shufflevector <4 x i32> [[Y]], <4 x i32> [[X]], <4 x i32> <i32 0, i32 1, i32 6, i32 7>
155 ; CHECK-NEXT:    [[R:%.*]] = srem <4 x i32> [[SEL1]], [[SEL2]]
156 ; CHECK-NEXT:    ret <4 x i32> [[R]]
158   %sel1 = shufflevector <4 x i32> %x, <4 x i32> %y, <4 x i32> <i32 0, i32 1, i32 6, i32 7>
159   %sel2 = shufflevector <4 x i32> %y, <4 x i32> %x, <4 x i32> <i32 0, i32 1, i32 6, i32 7>
160   %r = srem <4 x i32> %sel1, %sel2
161   ret <4 x i32> %r
164 define <4 x i32> @urem(<4 x i32> %x, <4 x i32> %y) {
165 ; CHECK-LABEL: @urem(
166 ; CHECK-NEXT:    [[SEL1:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]], <4 x i32> <i32 0, i32 1, i32 6, i32 3>
167 ; CHECK-NEXT:    [[SEL2:%.*]] = shufflevector <4 x i32> [[Y]], <4 x i32> [[X]], <4 x i32> <i32 0, i32 1, i32 6, i32 3>
168 ; CHECK-NEXT:    [[R:%.*]] = urem <4 x i32> [[SEL1]], [[SEL2]]
169 ; CHECK-NEXT:    ret <4 x i32> [[R]]
171   %sel1 = shufflevector <4 x i32> %x, <4 x i32> %y, <4 x i32> <i32 0, i32 1, i32 6, i32 3>
172   %sel2 = shufflevector <4 x i32> %y, <4 x i32> %x, <4 x i32> <i32 0, i32 1, i32 6, i32 3>
173   %r = urem <4 x i32> %sel1, %sel2
174   ret <4 x i32> %r
177 define <4 x i32> @shl(<4 x i32> %x, <4 x i32> %y) {
178 ; CHECK-LABEL: @shl(
179 ; CHECK-NEXT:    [[SEL1:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]], <4 x i32> <i32 0, i32 1, i32 6, i32 7>
180 ; CHECK-NEXT:    [[SEL2:%.*]] = shufflevector <4 x i32> [[Y]], <4 x i32> [[X]], <4 x i32> <i32 0, i32 1, i32 6, i32 7>
181 ; CHECK-NEXT:    [[R:%.*]] = shl nsw <4 x i32> [[SEL1]], [[SEL2]]
182 ; CHECK-NEXT:    ret <4 x i32> [[R]]
184   %sel1 = shufflevector <4 x i32> %x, <4 x i32> %y, <4 x i32> <i32 0, i32 1, i32 6, i32 7>
185   %sel2 = shufflevector <4 x i32> %y, <4 x i32> %x, <4 x i32> <i32 0, i32 1, i32 6, i32 7>
186   %r = shl nsw <4 x i32> %sel1, %sel2
187   ret <4 x i32> %r
190 define <4 x i32> @lshr(<4 x i32> %x, <4 x i32> %y) {
191 ; CHECK-LABEL: @lshr(
192 ; CHECK-NEXT:    [[SEL1:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]], <4 x i32> <i32 0, i32 5, i32 6, i32 3>
193 ; CHECK-NEXT:    [[SEL2:%.*]] = shufflevector <4 x i32> [[Y]], <4 x i32> [[X]], <4 x i32> <i32 0, i32 5, i32 6, i32 3>
194 ; CHECK-NEXT:    [[R:%.*]] = lshr exact <4 x i32> [[SEL1]], [[SEL2]]
195 ; CHECK-NEXT:    ret <4 x i32> [[R]]
197   %sel1 = shufflevector <4 x i32> %x, <4 x i32> %y, <4 x i32> <i32 0, i32 5, i32 6, i32 3>
198   %sel2 = shufflevector <4 x i32> %y, <4 x i32> %x, <4 x i32> <i32 0, i32 5, i32 6, i32 3>
199   %r = lshr exact <4 x i32> %sel1, %sel2
200   ret <4 x i32> %r
203 define <4 x i32> @ashr(<4 x i32> %x, <4 x i32> %y) {
204 ; CHECK-LABEL: @ashr(
205 ; CHECK-NEXT:    [[SEL1:%.*]] = shufflevector <4 x i32> [[Y:%.*]], <4 x i32> [[X:%.*]], <4 x i32> <i32 0, i32 5, i32 2, i32 7>
206 ; CHECK-NEXT:    [[SEL2:%.*]] = shufflevector <4 x i32> [[X]], <4 x i32> [[Y]], <4 x i32> <i32 0, i32 5, i32 2, i32 7>
207 ; CHECK-NEXT:    [[R:%.*]] = ashr <4 x i32> [[SEL1]], [[SEL2]]
208 ; CHECK-NEXT:    ret <4 x i32> [[R]]
210   %sel1 = shufflevector <4 x i32> %x, <4 x i32> %y, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
211   %sel2 = shufflevector <4 x i32> %y, <4 x i32> %x, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
212   %r = ashr <4 x i32> %sel1, %sel2
213   ret <4 x i32> %r
216 define <4 x float> @fadd(<4 x float> %x, <4 x float> %y) {
217 ; CHECK-LABEL: @fadd(
218 ; CHECK-NEXT:    [[R:%.*]] = fadd <4 x float> [[Y:%.*]], [[X:%.*]]
219 ; CHECK-NEXT:    ret <4 x float> [[R]]
221   %sel1 = shufflevector <4 x float> %x, <4 x float> %y, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
222   %sel2 = shufflevector <4 x float> %y, <4 x float> %x, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
223   %r = fadd <4 x float> %sel1, %sel2
224   ret <4 x float> %r
227 define <4 x float> @fsub(<4 x float> %x, <4 x float> %y) {
228 ; CHECK-LABEL: @fsub(
229 ; CHECK-NEXT:    [[SEL1:%.*]] = shufflevector <4 x float> [[Y:%.*]], <4 x float> [[X:%.*]], <4 x i32> <i32 0, i32 5, i32 2, i32 7>
230 ; CHECK-NEXT:    [[SEL2:%.*]] = shufflevector <4 x float> [[X]], <4 x float> [[Y]], <4 x i32> <i32 0, i32 5, i32 2, i32 7>
231 ; CHECK-NEXT:    [[R:%.*]] = fsub fast <4 x float> [[SEL1]], [[SEL2]]
232 ; CHECK-NEXT:    ret <4 x float> [[R]]
234   %sel1 = shufflevector <4 x float> %x, <4 x float> %y, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
235   %sel2 = shufflevector <4 x float> %y, <4 x float> %x, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
236   %r = fsub fast <4 x float> %sel1, %sel2
237   ret <4 x float> %r
240 define <4 x double> @fmul(<4 x double> %x, <4 x double> %y) {
241 ; CHECK-LABEL: @fmul(
242 ; CHECK-NEXT:    [[R:%.*]] = fmul nnan <4 x double> [[Y:%.*]], [[X:%.*]]
243 ; CHECK-NEXT:    ret <4 x double> [[R]]
245   %sel1 = shufflevector <4 x double> %x, <4 x double> %y, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
246   %sel2 = shufflevector <4 x double> %y, <4 x double> %x, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
247   %r = fmul nnan <4 x double> %sel1, %sel2
248   ret <4 x double> %r
251 define <4 x double> @fdiv(<4 x double> %x, <4 x double> %y) {
252 ; CHECK-LABEL: @fdiv(
253 ; CHECK-NEXT:    [[SEL1:%.*]] = shufflevector <4 x double> [[Y:%.*]], <4 x double> [[X:%.*]], <4 x i32> <i32 0, i32 5, i32 2, i32 7>
254 ; CHECK-NEXT:    [[SEL2:%.*]] = shufflevector <4 x double> [[X]], <4 x double> [[Y]], <4 x i32> <i32 0, i32 5, i32 2, i32 7>
255 ; CHECK-NEXT:    [[R:%.*]] = fdiv nnan arcp <4 x double> [[SEL1]], [[SEL2]]
256 ; CHECK-NEXT:    ret <4 x double> [[R]]
258   %sel1 = shufflevector <4 x double> %x, <4 x double> %y, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
259   %sel2 = shufflevector <4 x double> %y, <4 x double> %x, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
260   %r = fdiv arcp nnan <4 x double> %sel1, %sel2
261   ret <4 x double> %r
264 define <4 x double> @frem(<4 x double> %x, <4 x double> %y) {
265 ; CHECK-LABEL: @frem(
266 ; CHECK-NEXT:    [[SEL1:%.*]] = shufflevector <4 x double> [[Y:%.*]], <4 x double> [[X:%.*]], <4 x i32> <i32 0, i32 5, i32 2, i32 7>
267 ; CHECK-NEXT:    [[SEL2:%.*]] = shufflevector <4 x double> [[X]], <4 x double> [[Y]], <4 x i32> <i32 0, i32 5, i32 2, i32 7>
268 ; CHECK-NEXT:    [[R:%.*]] = frem <4 x double> [[SEL1]], [[SEL2]]
269 ; CHECK-NEXT:    ret <4 x double> [[R]]
271   %sel1 = shufflevector <4 x double> %x, <4 x double> %y, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
272   %sel2 = shufflevector <4 x double> %y, <4 x double> %x, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
273   %r = frem <4 x double> %sel1, %sel2
274   ret <4 x double> %r