xref: /llvm-project/llvm/test/CodeGen/AArch64/ushl_sat.ll (revision b4f591363c834a0914da9ede2c581eafc0743936)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=aarch64-- | FileCheck %s
3
4declare i16 @llvm.ushl.sat.i16(i16, i16)
5declare <2 x i16> @llvm.ushl.sat.v2i16(<2 x i16>, <2 x i16>)
6
7; fold (shlsat undef, x) -> 0
8define i16 @combine_shl_undef(i16 %x, i16 %y) nounwind {
9; CHECK-LABEL: combine_shl_undef:
10; CHECK:       // %bb.0:
11; CHECK-NEXT:    mov w0, wzr
12; CHECK-NEXT:    ret
13  %tmp = call i16 @llvm.ushl.sat.i16(i16 undef, i16 %y)
14  ret i16 %tmp
15}
16
17; fold (shlsat x, undef) -> undef
18define i16 @combine_shl_by_undef(i16 %x, i16 %y) nounwind {
19; CHECK-LABEL: combine_shl_by_undef:
20; CHECK:       // %bb.0:
21; CHECK-NEXT:    ret
22  %tmp = call i16 @llvm.ushl.sat.i16(i16 %x, i16 undef)
23  ret i16 %tmp
24}
25
26; fold (shlsat poison, x) -> 0
27define i16 @combine_shl_poison(i16 %x, i16 %y) nounwind {
28; CHECK-LABEL: combine_shl_poison:
29; CHECK:       // %bb.0:
30; CHECK-NEXT:    mov w0, wzr
31; CHECK-NEXT:    ret
32  %tmp = call i16 @llvm.ushl.sat.i16(i16 poison, i16 %y)
33  ret i16 %tmp
34}
35
36; fold (shlsat x, poison) -> undef
37define i16 @combine_shl_by_poison(i16 %x, i16 %y) nounwind {
38; CHECK-LABEL: combine_shl_by_poison:
39; CHECK:       // %bb.0:
40; CHECK-NEXT:    ret
41  %tmp = call i16 @llvm.ushl.sat.i16(i16 %x, i16 poison)
42  ret i16 %tmp
43}
44
45; fold (shlsat x, bitwidth) -> undef
46define i16 @combine_shl_by_bitwidth(i16 %x, i16 %y) nounwind {
47; CHECK-LABEL: combine_shl_by_bitwidth:
48; CHECK:       // %bb.0:
49; CHECK-NEXT:    ret
50  %tmp = call i16 @llvm.ushl.sat.i16(i16 %x, i16 16)
51  ret i16 %tmp
52}
53
54; fold (ushlsat 0, x) -> 0
55define i16 @combine_shl_zero(i16 %x, i16 %y) nounwind {
56; CHECK-LABEL: combine_shl_zero:
57; CHECK:       // %bb.0:
58; CHECK-NEXT:    mov w0, wzr
59; CHECK-NEXT:    ret
60  %tmp = call i16 @llvm.ushl.sat.i16(i16 0, i16 %y)
61  ret i16 %tmp
62}
63
64; fold (ushlsat x, 0) -> x
65define i16 @combine_shlsat_by_zero(i16 %x, i16 %y) nounwind {
66; CHECK-LABEL: combine_shlsat_by_zero:
67; CHECK:       // %bb.0:
68; CHECK-NEXT:    ret
69  %tmp = call i16 @llvm.ushl.sat.i16(i16 %x, i16 0)
70  ret i16 %tmp
71}
72
73; fold (ushlsat c1, c2) -> c3
74define i16 @combine_shlsat_constfold(i16 %x, i16 %y) nounwind {
75; CHECK-LABEL: combine_shlsat_constfold:
76; CHECK:       // %bb.0:
77; CHECK-NEXT:    mov w0, #32 // =0x20
78; CHECK-NEXT:    ret
79  %tmp = call i16 @llvm.ushl.sat.i16(i16 8, i16 2)
80  ret i16 %tmp
81}
82
83; fold (ushlsat c1, c2) -> sat max
84define i16 @combine_shlsat_satmax(i16 %x, i16 %y) nounwind {
85; CHECK-LABEL: combine_shlsat_satmax:
86; CHECK:       // %bb.0:
87; CHECK-NEXT:    mov w0, #65535 // =0xffff
88; CHECK-NEXT:    ret
89  %tmp = call i16 @llvm.ushl.sat.i16(i16 8, i16 15)
90  ret i16 %tmp
91}
92
93
94declare void @sink2xi16(i16, i16)
95
96; fold (ushlsat c1, c2) -> c3 , c1/c2/c3 being vectors
97define void @combine_shlsat_vector() nounwind {
98; CHECK-LABEL: combine_shlsat_vector:
99; CHECK:       // %bb.0:
100; CHECK-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
101; CHECK-NEXT:    mov w0, #32 // =0x20
102; CHECK-NEXT:    mov w1, #65535 // =0xffff
103; CHECK-NEXT:    bl sink2xi16
104; CHECK-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
105; CHECK-NEXT:    ret
106  %tmp = call <2 x i16> @llvm.ushl.sat.v2i16(<2 x i16><i16 8, i16 8>,
107                                             <2 x i16><i16 2, i16 15>)
108  ; Pass elements as arguments in a call to get CHECK statements that verify
109  ; the constant folding.
110  %e0 = extractelement <2 x i16> %tmp, i16 0
111  %e1 = extractelement <2 x i16> %tmp, i16 1
112  call void @sink2xi16(i16 %e0, i16 %e1)
113  ret void
114}
115
116; Fold shlsat -> shl, if known not to saturate.
117define i16 @combine_shlsat_to_shl(i16 %x) nounwind {
118; CHECK-LABEL: combine_shlsat_to_shl:
119; CHECK:       // %bb.0:
120; CHECK-NEXT:    and w0, w0, #0xfffffffc
121; CHECK-NEXT:    ret
122  %x2 = lshr i16 %x, 2
123  %tmp = call i16 @llvm.ushl.sat.i16(i16 %x2, i16 2)
124  ret i16 %tmp
125}
126
127; Do not fold shlsat -> shl.
128define i16 @combine_shlsat_to_shl_no_fold(i16 %x) nounwind {
129; CHECK-LABEL: combine_shlsat_to_shl_no_fold:
130; CHECK:       // %bb.0:
131; CHECK-NEXT:    lsl w8, w0, #14
132; CHECK-NEXT:    and w8, w8, #0x3fff0000
133; CHECK-NEXT:    lsl w9, w8, #3
134; CHECK-NEXT:    cmp w8, w9, lsr #3
135; CHECK-NEXT:    csinv w8, w9, wzr, eq
136; CHECK-NEXT:    lsr w0, w8, #16
137; CHECK-NEXT:    ret
138  %x2 = lshr i16 %x, 2
139  %tmp = call i16 @llvm.ushl.sat.i16(i16 %x2, i16 3)
140  ret i16 %tmp
141}
142
143; Fold shlsat -> shl, if known not to saturate.
144define <2 x i16> @combine_shlsat_to_shl_vec(<2 x i8> %a) nounwind {
145; CHECK-LABEL: combine_shlsat_to_shl_vec:
146; CHECK:       // %bb.0:
147; CHECK-NEXT:    shl v0.2s, v0.2s, #8
148; CHECK-NEXT:    ret
149  %ext = zext <2 x i8> %a to <2 x i16>
150  %tmp = call <2 x i16> @llvm.ushl.sat.v2i16(
151                          <2 x i16> %ext,
152                          <2 x i16> <i16 8, i16 8>)
153  ret <2 x i16> %tmp
154}
155