[ARM] Better OR's for MVE compares
[llvm-core.git] / test / Transforms / InstCombine / trunc-binop-ext.ll
blob40d58f31458eb2b81b2834d83cb14858a68028d7
1 ; RUN: opt < %s -instcombine -S | FileCheck %s
3 define i16 @narrow_sext_and(i16 %x16, i32 %y32) {
4 ; CHECK-LABEL: @narrow_sext_and(
5 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 %y32 to i16
6 ; CHECK-NEXT:    [[R:%.*]] = and i16 [[TMP1]], %x16
7 ; CHECK-NEXT:    ret i16 [[R]]
9   %x32 = sext i16 %x16 to i32
10   %b = and i32 %x32, %y32
11   %r = trunc i32 %b to i16
12   ret i16 %r
15 define i16 @narrow_zext_and(i16 %x16, i32 %y32) {
16 ; CHECK-LABEL: @narrow_zext_and(
17 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 %y32 to i16
18 ; CHECK-NEXT:    [[R:%.*]] = and i16 [[TMP1]], %x16
19 ; CHECK-NEXT:    ret i16 [[R]]
21   %x32 = zext i16 %x16 to i32
22   %b = and i32 %x32, %y32
23   %r = trunc i32 %b to i16
24   ret i16 %r
27 define i16 @narrow_sext_or(i16 %x16, i32 %y32) {
28 ; CHECK-LABEL: @narrow_sext_or(
29 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 %y32 to i16
30 ; CHECK-NEXT:    [[R:%.*]] = or i16 [[TMP1]], %x16
31 ; CHECK-NEXT:    ret i16 [[R]]
33   %x32 = sext i16 %x16 to i32
34   %b = or i32 %x32, %y32
35   %r = trunc i32 %b to i16
36   ret i16 %r
39 define i16 @narrow_zext_or(i16 %x16, i32 %y32) {
40 ; CHECK-LABEL: @narrow_zext_or(
41 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 %y32 to i16
42 ; CHECK-NEXT:    [[R:%.*]] = or i16 [[TMP1]], %x16
43 ; CHECK-NEXT:    ret i16 [[R]]
45   %x32 = zext i16 %x16 to i32
46   %b = or i32 %x32, %y32
47   %r = trunc i32 %b to i16
48   ret i16 %r
51 define i16 @narrow_sext_xor(i16 %x16, i32 %y32) {
52 ; CHECK-LABEL: @narrow_sext_xor(
53 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 %y32 to i16
54 ; CHECK-NEXT:    [[R:%.*]] = xor i16 [[TMP1]], %x16
55 ; CHECK-NEXT:    ret i16 [[R]]
57   %x32 = sext i16 %x16 to i32
58   %b = xor i32 %x32, %y32
59   %r = trunc i32 %b to i16
60   ret i16 %r
63 define i16 @narrow_zext_xor(i16 %x16, i32 %y32) {
64 ; CHECK-LABEL: @narrow_zext_xor(
65 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 %y32 to i16
66 ; CHECK-NEXT:    [[R:%.*]] = xor i16 [[TMP1]], %x16
67 ; CHECK-NEXT:    ret i16 [[R]]
69   %x32 = zext i16 %x16 to i32
70   %b = xor i32 %x32, %y32
71   %r = trunc i32 %b to i16
72   ret i16 %r
75 define i16 @narrow_sext_add(i16 %x16, i32 %y32) {
76 ; CHECK-LABEL: @narrow_sext_add(
77 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 %y32 to i16
78 ; CHECK-NEXT:    [[R:%.*]] = add i16 [[TMP1]], %x16
79 ; CHECK-NEXT:    ret i16 [[R]]
81   %x32 = sext i16 %x16 to i32
82   %b = add i32 %x32, %y32
83   %r = trunc i32 %b to i16
84   ret i16 %r
87 define i16 @narrow_zext_add(i16 %x16, i32 %y32) {
88 ; CHECK-LABEL: @narrow_zext_add(
89 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 %y32 to i16
90 ; CHECK-NEXT:    [[R:%.*]] = add i16 [[TMP1]], %x16
91 ; CHECK-NEXT:    ret i16 [[R]]
93   %x32 = zext i16 %x16 to i32
94   %b = add i32 %x32, %y32
95   %r = trunc i32 %b to i16
96   ret i16 %r
99 define i16 @narrow_sext_sub(i16 %x16, i32 %y32) {
100 ; CHECK-LABEL: @narrow_sext_sub(
101 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 %y32 to i16
102 ; CHECK-NEXT:    [[R:%.*]] = sub i16 %x16, [[TMP1]]
103 ; CHECK-NEXT:    ret i16 [[R]]
105   %x32 = sext i16 %x16 to i32
106   %b = sub i32 %x32, %y32
107   %r = trunc i32 %b to i16
108   ret i16 %r
111 define i16 @narrow_zext_sub(i16 %x16, i32 %y32) {
112 ; CHECK-LABEL: @narrow_zext_sub(
113 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 %y32 to i16
114 ; CHECK-NEXT:    [[R:%.*]] = sub i16 %x16, [[TMP1]]
115 ; CHECK-NEXT:    ret i16 [[R]]
117   %x32 = zext i16 %x16 to i32
118   %b = sub i32 %x32, %y32
119   %r = trunc i32 %b to i16
120   ret i16 %r
123 define i16 @narrow_sext_mul(i16 %x16, i32 %y32) {
124 ; CHECK-LABEL: @narrow_sext_mul(
125 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 %y32 to i16
126 ; CHECK-NEXT:    [[R:%.*]] = mul i16 [[TMP1]], %x16
127 ; CHECK-NEXT:    ret i16 [[R]]
129   %x32 = sext i16 %x16 to i32
130   %b = mul i32 %x32, %y32
131   %r = trunc i32 %b to i16
132   ret i16 %r
135 define i16 @narrow_zext_mul(i16 %x16, i32 %y32) {
136 ; CHECK-LABEL: @narrow_zext_mul(
137 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 %y32 to i16
138 ; CHECK-NEXT:    [[R:%.*]] = mul i16 [[TMP1]], %x16
139 ; CHECK-NEXT:    ret i16 [[R]]
141   %x32 = zext i16 %x16 to i32
142   %b = mul i32 %x32, %y32
143   %r = trunc i32 %b to i16
144   ret i16 %r
147 ; Verify that the commuted patterns work. The div is to ensure that complexity-based
148 ; canonicalization doesn't swap the binop operands. Use vector types to show those work too.
150 define <2 x i16> @narrow_sext_and_commute(<2 x i16> %x16, <2 x i32> %y32) {
151 ; CHECK-LABEL: @narrow_sext_and_commute(
152 ; CHECK-NEXT:    [[Y32OP0:%.*]] = sdiv <2 x i32> %y32, <i32 7, i32 -17>
153 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc <2 x i32> [[Y32OP0]] to <2 x i16>
154 ; CHECK-NEXT:    [[R:%.*]] = and <2 x i16> [[TMP1]], %x16
155 ; CHECK-NEXT:    ret <2 x i16> [[R]]
157   %y32op0 = sdiv <2 x i32> %y32, <i32 7, i32 -17>
158   %x32 = sext <2 x i16> %x16 to <2 x i32>
159   %b = and <2 x i32> %y32op0, %x32
160   %r = trunc <2 x i32> %b to <2 x i16>
161   ret <2 x i16> %r
164 define <2 x i16> @narrow_zext_and_commute(<2 x i16> %x16, <2 x i32> %y32) {
165 ; CHECK-LABEL: @narrow_zext_and_commute(
166 ; CHECK-NEXT:    [[Y32OP0:%.*]] = sdiv <2 x i32> %y32, <i32 7, i32 -17>
167 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc <2 x i32> [[Y32OP0]] to <2 x i16>
168 ; CHECK-NEXT:    [[R:%.*]] = and <2 x i16> [[TMP1]], %x16
169 ; CHECK-NEXT:    ret <2 x i16> [[R]]
171   %y32op0 = sdiv <2 x i32> %y32, <i32 7, i32 -17>
172   %x32 = zext <2 x i16> %x16 to <2 x i32>
173   %b = and <2 x i32> %y32op0, %x32
174   %r = trunc <2 x i32> %b to <2 x i16>
175   ret <2 x i16> %r
178 define <2 x i16> @narrow_sext_or_commute(<2 x i16> %x16, <2 x i32> %y32) {
179 ; CHECK-LABEL: @narrow_sext_or_commute(
180 ; CHECK-NEXT:    [[Y32OP0:%.*]] = sdiv <2 x i32> %y32, <i32 7, i32 -17>
181 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc <2 x i32> [[Y32OP0]] to <2 x i16>
182 ; CHECK-NEXT:    [[R:%.*]] = or <2 x i16> [[TMP1]], %x16
183 ; CHECK-NEXT:    ret <2 x i16> [[R]]
185   %y32op0 = sdiv <2 x i32> %y32, <i32 7, i32 -17>
186   %x32 = sext <2 x i16> %x16 to <2 x i32>
187   %b = or <2 x i32> %y32op0, %x32
188   %r = trunc <2 x i32> %b to <2 x i16>
189   ret <2 x i16> %r
192 define <2 x i16> @narrow_zext_or_commute(<2 x i16> %x16, <2 x i32> %y32) {
193 ; CHECK-LABEL: @narrow_zext_or_commute(
194 ; CHECK-NEXT:    [[Y32OP0:%.*]] = sdiv <2 x i32> %y32, <i32 7, i32 -17>
195 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc <2 x i32> [[Y32OP0]] to <2 x i16>
196 ; CHECK-NEXT:    [[R:%.*]] = or <2 x i16> [[TMP1]], %x16
197 ; CHECK-NEXT:    ret <2 x i16> [[R]]
199   %y32op0 = sdiv <2 x i32> %y32, <i32 7, i32 -17>
200   %x32 = zext <2 x i16> %x16 to <2 x i32>
201   %b = or <2 x i32> %y32op0, %x32
202   %r = trunc <2 x i32> %b to <2 x i16>
203   ret <2 x i16> %r
206 define <2 x i16> @narrow_sext_xor_commute(<2 x i16> %x16, <2 x i32> %y32) {
207 ; CHECK-LABEL: @narrow_sext_xor_commute(
208 ; CHECK-NEXT:    [[Y32OP0:%.*]] = sdiv <2 x i32> %y32, <i32 7, i32 -17>
209 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc <2 x i32> [[Y32OP0]] to <2 x i16>
210 ; CHECK-NEXT:    [[R:%.*]] = xor <2 x i16> [[TMP1]], %x16
211 ; CHECK-NEXT:    ret <2 x i16> [[R]]
213   %y32op0 = sdiv <2 x i32> %y32, <i32 7, i32 -17>
214   %x32 = sext <2 x i16> %x16 to <2 x i32>
215   %b = xor <2 x i32> %y32op0, %x32
216   %r = trunc <2 x i32> %b to <2 x i16>
217   ret <2 x i16> %r
220 define <2 x i16> @narrow_zext_xor_commute(<2 x i16> %x16, <2 x i32> %y32) {
221 ; CHECK-LABEL: @narrow_zext_xor_commute(
222 ; CHECK-NEXT:    [[Y32OP0:%.*]] = sdiv <2 x i32> %y32, <i32 7, i32 -17>
223 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc <2 x i32> [[Y32OP0]] to <2 x i16>
224 ; CHECK-NEXT:    [[R:%.*]] = xor <2 x i16> [[TMP1]], %x16
225 ; CHECK-NEXT:    ret <2 x i16> [[R]]
227   %y32op0 = sdiv <2 x i32> %y32, <i32 7, i32 -17>
228   %x32 = zext <2 x i16> %x16 to <2 x i32>
229   %b = xor <2 x i32> %y32op0, %x32
230   %r = trunc <2 x i32> %b to <2 x i16>
231   ret <2 x i16> %r
234 define <2 x i16> @narrow_sext_add_commute(<2 x i16> %x16, <2 x i32> %y32) {
235 ; CHECK-LABEL: @narrow_sext_add_commute(
236 ; CHECK-NEXT:    [[Y32OP0:%.*]] = sdiv <2 x i32> %y32, <i32 7, i32 -17>
237 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc <2 x i32> [[Y32OP0]] to <2 x i16>
238 ; CHECK-NEXT:    [[R:%.*]] = add <2 x i16> [[TMP1]], %x16
239 ; CHECK-NEXT:    ret <2 x i16> [[R]]
241   %y32op0 = sdiv <2 x i32> %y32, <i32 7, i32 -17>
242   %x32 = sext <2 x i16> %x16 to <2 x i32>
243   %b = add <2 x i32> %y32op0, %x32
244   %r = trunc <2 x i32> %b to <2 x i16>
245   ret <2 x i16> %r
248 define <2 x i16> @narrow_zext_add_commute(<2 x i16> %x16, <2 x i32> %y32) {
249 ; CHECK-LABEL: @narrow_zext_add_commute(
250 ; CHECK-NEXT:    [[Y32OP0:%.*]] = sdiv <2 x i32> %y32, <i32 7, i32 -17>
251 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc <2 x i32> [[Y32OP0]] to <2 x i16>
252 ; CHECK-NEXT:    [[R:%.*]] = add <2 x i16> [[TMP1]], %x16
253 ; CHECK-NEXT:    ret <2 x i16> [[R]]
255   %y32op0 = sdiv <2 x i32> %y32, <i32 7, i32 -17>
256   %x32 = zext <2 x i16> %x16 to <2 x i32>
257   %b = add <2 x i32> %y32op0, %x32
258   %r = trunc <2 x i32> %b to <2 x i16>
259   ret <2 x i16> %r
262 define <2 x i16> @narrow_sext_sub_commute(<2 x i16> %x16, <2 x i32> %y32) {
263 ; CHECK-LABEL: @narrow_sext_sub_commute(
264 ; CHECK-NEXT:    [[Y32OP0:%.*]] = sdiv <2 x i32> %y32, <i32 7, i32 -17>
265 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc <2 x i32> [[Y32OP0]] to <2 x i16>
266 ; CHECK-NEXT:    [[R:%.*]] = sub <2 x i16> [[TMP1]], %x16
267 ; CHECK-NEXT:    ret <2 x i16> [[R]]
269   %y32op0 = sdiv <2 x i32> %y32, <i32 7, i32 -17>
270   %x32 = sext <2 x i16> %x16 to <2 x i32>
271   %b = sub <2 x i32> %y32op0, %x32
272   %r = trunc <2 x i32> %b to <2 x i16>
273   ret <2 x i16> %r
276 define <2 x i16> @narrow_zext_sub_commute(<2 x i16> %x16, <2 x i32> %y32) {
277 ; CHECK-LABEL: @narrow_zext_sub_commute(
278 ; CHECK-NEXT:    [[Y32OP0:%.*]] = sdiv <2 x i32> %y32, <i32 7, i32 -17>
279 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc <2 x i32> [[Y32OP0]] to <2 x i16>
280 ; CHECK-NEXT:    [[R:%.*]] = sub <2 x i16> [[TMP1]], %x16
281 ; CHECK-NEXT:    ret <2 x i16> [[R]]
283   %y32op0 = sdiv <2 x i32> %y32, <i32 7, i32 -17>
284   %x32 = zext <2 x i16> %x16 to <2 x i32>
285   %b = sub <2 x i32> %y32op0, %x32
286   %r = trunc <2 x i32> %b to <2 x i16>
287   ret <2 x i16> %r
290 define <2 x i16> @narrow_sext_mul_commute(<2 x i16> %x16, <2 x i32> %y32) {
291 ; CHECK-LABEL: @narrow_sext_mul_commute(
292 ; CHECK-NEXT:    [[Y32OP0:%.*]] = sdiv <2 x i32> %y32, <i32 7, i32 -17>
293 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc <2 x i32> [[Y32OP0]] to <2 x i16>
294 ; CHECK-NEXT:    [[R:%.*]] = mul <2 x i16> [[TMP1]], %x16
295 ; CHECK-NEXT:    ret <2 x i16> [[R]]
297   %y32op0 = sdiv <2 x i32> %y32, <i32 7, i32 -17>
298   %x32 = sext <2 x i16> %x16 to <2 x i32>
299   %b = mul <2 x i32> %y32op0, %x32
300   %r = trunc <2 x i32> %b to <2 x i16>
301   ret <2 x i16> %r
304 define <2 x i16> @narrow_zext_mul_commute(<2 x i16> %x16, <2 x i32> %y32) {
305 ; CHECK-LABEL: @narrow_zext_mul_commute(
306 ; CHECK-NEXT:    [[Y32OP0:%.*]] = sdiv <2 x i32> %y32, <i32 7, i32 -17>
307 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc <2 x i32> [[Y32OP0]] to <2 x i16>
308 ; CHECK-NEXT:    [[R:%.*]] = mul <2 x i16> [[TMP1]], %x16
309 ; CHECK-NEXT:    ret <2 x i16> [[R]]
311   %y32op0 = sdiv <2 x i32> %y32, <i32 7, i32 -17>
312   %x32 = zext <2 x i16> %x16 to <2 x i32>
313   %b = mul <2 x i32> %y32op0, %x32
314   %r = trunc <2 x i32> %b to <2 x i16>
315   ret <2 x i16> %r