1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=aarch64-- | FileCheck %s
4 declare i16 @llvm.sshl.sat.i16(i16, i16)
5 declare <4 x i16> @llvm.sshl.sat.v4i16(<4 x i16>, <4 x i16>)
7 ; fold (shlsat undef, x) -> 0
8 define i16 @combine_shl_undef(i16 %x, i16 %y) nounwind {
9 ; CHECK-LABEL: combine_shl_undef:
11 ; CHECK-NEXT: mov w0, wzr
13 %tmp = call i16 @llvm.sshl.sat.i16(i16 undef, i16 %y)
17 ; fold (shlsat x, undef) -> undef
18 define i16 @combine_shl_by_undef(i16 %x, i16 %y) nounwind {
19 ; CHECK-LABEL: combine_shl_by_undef:
22 %tmp = call i16 @llvm.sshl.sat.i16(i16 %x, i16 undef)
26 ; fold (shlsat poison, x) -> 0
27 define i16 @combine_shl_poison(i16 %x, i16 %y) nounwind {
28 ; CHECK-LABEL: combine_shl_poison:
30 ; CHECK-NEXT: mov w0, wzr
32 %tmp = call i16 @llvm.sshl.sat.i16(i16 poison, i16 %y)
36 ; fold (shlsat x, poison) -> undef
37 define i16 @combine_shl_by_poison(i16 %x, i16 %y) nounwind {
38 ; CHECK-LABEL: combine_shl_by_poison:
41 %tmp = call i16 @llvm.sshl.sat.i16(i16 %x, i16 poison)
45 ; fold (shlsat x, bitwidth) -> undef
46 define i16 @combine_shl_by_bitwidth(i16 %x, i16 %y) nounwind {
47 ; CHECK-LABEL: combine_shl_by_bitwidth:
50 %tmp = call i16 @llvm.sshl.sat.i16(i16 %x, i16 16)
54 ; fold (shlsat 0, x) -> 0
55 define i16 @combine_shl_zero(i16 %x, i16 %y) nounwind {
56 ; CHECK-LABEL: combine_shl_zero:
58 ; CHECK-NEXT: mov w0, wzr
60 %tmp = call i16 @llvm.sshl.sat.i16(i16 0, i16 %y)
64 ; fold (shlsat x, 0) -> x
65 define i16 @combine_shlsat_by_zero(i16 %x, i16 %y) nounwind {
66 ; CHECK-LABEL: combine_shlsat_by_zero:
69 %tmp = call i16 @llvm.sshl.sat.i16(i16 %x, i16 0)
73 ; fold (shlsat c1, c2) -> c3
74 define i16 @combine_shlsat_constfold(i16 %x, i16 %y) nounwind {
75 ; CHECK-LABEL: combine_shlsat_constfold:
77 ; CHECK-NEXT: mov w0, #32 // =0x20
79 %tmp = call i16 @llvm.sshl.sat.i16(i16 8, i16 2)
83 ; fold (shlsat c1, c2) -> sat max
84 define i16 @combine_shlsat_satmax(i16 %x, i16 %y) nounwind {
85 ; CHECK-LABEL: combine_shlsat_satmax:
87 ; CHECK-NEXT: mov w0, #32767 // =0x7fff
89 %tmp = call i16 @llvm.sshl.sat.i16(i16 8, i16 15)
93 ; fold (shlsat c1, c2) -> sat min
94 define i16 @combine_shlsat_satmin(i16 %x, i16 %y) nounwind {
95 ; CHECK-LABEL: combine_shlsat_satmin:
97 ; CHECK-NEXT: mov w0, #32768 // =0x8000
99 %tmp = call i16 @llvm.sshl.sat.i16(i16 -8, i16 15)
103 declare void @sink4xi16(i16, i16, i16, i16)
105 ; fold (shlsat c1, c2) -> c3 , c1/c2/c3 being vectors
106 define void @combine_shlsat_vector() nounwind {
107 ; CHECK-LABEL: combine_shlsat_vector:
109 ; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
110 ; CHECK-NEXT: mov w0, #32 // =0x20
111 ; CHECK-NEXT: mov w1, #32767 // =0x7fff
112 ; CHECK-NEXT: mov w2, #65504 // =0xffe0
113 ; CHECK-NEXT: mov w3, #32768 // =0x8000
114 ; CHECK-NEXT: bl sink4xi16
115 ; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
117 %tmp = call <4 x i16> @llvm.sshl.sat.v4i16(
118 <4 x i16><i16 8, i16 8, i16 -8, i16 -8>,
119 <4 x i16><i16 2, i16 15, i16 2, i16 15>)
120 ; Pass elements as arguments in a call to get CHECK statements that verify
121 ; the constant folding.
122 %e0 = extractelement <4 x i16> %tmp, i16 0
123 %e1 = extractelement <4 x i16> %tmp, i16 1
124 %e2 = extractelement <4 x i16> %tmp, i16 2
125 %e3 = extractelement <4 x i16> %tmp, i16 3
126 call void @sink4xi16(i16 %e0, i16 %e1, i16 %e2, i16 %e3)
130 ; Fold shlsat -> shl, if known not to saturate.
131 define i16 @combine_shlsat_to_shl(i16 %x) nounwind {
132 ; CHECK-LABEL: combine_shlsat_to_shl:
134 ; CHECK-NEXT: and w0, w0, #0xfffffffc
137 %tmp = call i16 @llvm.sshl.sat.i16(i16 %x2, i16 2)
141 ; Do not fold shlsat -> shl.
142 define i16 @combine_shlsat_to_shl_no_fold(i16 %x) nounwind {
143 ; CHECK-LABEL: combine_shlsat_to_shl_no_fold:
145 ; CHECK-NEXT: sxth w8, w0
146 ; CHECK-NEXT: mov w9, #-65536 // =0xffff0000
147 ; CHECK-NEXT: mov w10, #-2147483648 // =0x80000000
148 ; CHECK-NEXT: ands w8, w9, w8, lsl #14
149 ; CHECK-NEXT: cinv w10, w10, ge
150 ; CHECK-NEXT: lsl w9, w8, #3
151 ; CHECK-NEXT: cmp w8, w9, asr #3
152 ; CHECK-NEXT: csel w8, w10, w9, ne
153 ; CHECK-NEXT: asr w0, w8, #16
156 %tmp = call i16 @llvm.sshl.sat.i16(i16 %x2, i16 3)
160 ; Fold shlsat -> shl, if known not to saturate.
161 define <4 x i16> @combine_shlsat_to_shl_vec(<4 x i8> %a) nounwind {
162 ; CHECK-LABEL: combine_shlsat_to_shl_vec:
164 ; CHECK-NEXT: shl v0.4h, v0.4h, #8
165 ; CHECK-NEXT: sshr v0.4h, v0.4h, #8
166 ; CHECK-NEXT: shl v0.4h, v0.4h, #7
168 %sext = sext <4 x i8> %a to <4 x i16>
169 %tmp = call <4 x i16> @llvm.sshl.sat.v4i16(
171 <4 x i16> <i16 7, i16 7, i16 7, i16 7>)