1 // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
2 // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s
3 
4 #include <arm_mve.h>
5 
6 // CHECK-LABEL: @test_asrl(
7 // CHECK-NEXT:  entry:
8 // CHECK-NEXT:    [[TMP0:%.*]] = lshr i64 [[VALUE:%.*]], 32
9 // CHECK-NEXT:    [[TMP1:%.*]] = trunc i64 [[TMP0]] to i32
10 // CHECK-NEXT:    [[TMP2:%.*]] = trunc i64 [[VALUE]] to i32
11 // CHECK-NEXT:    [[TMP3:%.*]] = call { i32, i32 } @llvm.arm.mve.asrl(i32 [[TMP2]], i32 [[TMP1]], i32 [[SHIFT:%.*]])
12 // CHECK-NEXT:    [[TMP4:%.*]] = extractvalue { i32, i32 } [[TMP3]], 1
13 // CHECK-NEXT:    [[TMP5:%.*]] = zext i32 [[TMP4]] to i64
14 // CHECK-NEXT:    [[TMP6:%.*]] = shl i64 [[TMP5]], 32
15 // CHECK-NEXT:    [[TMP7:%.*]] = extractvalue { i32, i32 } [[TMP3]], 0
16 // CHECK-NEXT:    [[TMP8:%.*]] = zext i32 [[TMP7]] to i64
17 // CHECK-NEXT:    [[TMP9:%.*]] = or i64 [[TMP6]], [[TMP8]]
18 // CHECK-NEXT:    ret i64 [[TMP9]]
19 //
test_asrl(int64_t value,int32_t shift)20 int64_t test_asrl(int64_t value, int32_t shift)
21 {
22     return asrl(value, shift);
23 }
24 
25 // CHECK-LABEL: @test_lsll(
26 // CHECK-NEXT:  entry:
27 // CHECK-NEXT:    [[TMP0:%.*]] = lshr i64 [[VALUE:%.*]], 32
28 // CHECK-NEXT:    [[TMP1:%.*]] = trunc i64 [[TMP0]] to i32
29 // CHECK-NEXT:    [[TMP2:%.*]] = trunc i64 [[VALUE]] to i32
30 // CHECK-NEXT:    [[TMP3:%.*]] = call { i32, i32 } @llvm.arm.mve.lsll(i32 [[TMP2]], i32 [[TMP1]], i32 [[SHIFT:%.*]])
31 // CHECK-NEXT:    [[TMP4:%.*]] = extractvalue { i32, i32 } [[TMP3]], 1
32 // CHECK-NEXT:    [[TMP5:%.*]] = zext i32 [[TMP4]] to i64
33 // CHECK-NEXT:    [[TMP6:%.*]] = shl i64 [[TMP5]], 32
34 // CHECK-NEXT:    [[TMP7:%.*]] = extractvalue { i32, i32 } [[TMP3]], 0
35 // CHECK-NEXT:    [[TMP8:%.*]] = zext i32 [[TMP7]] to i64
36 // CHECK-NEXT:    [[TMP9:%.*]] = or i64 [[TMP6]], [[TMP8]]
37 // CHECK-NEXT:    ret i64 [[TMP9]]
38 //
test_lsll(uint64_t value,int32_t shift)39 uint64_t test_lsll(uint64_t value, int32_t shift)
40 {
41     return lsll(value, shift);
42 }
43 
44 // CHECK-LABEL: @test_sqrshr(
45 // CHECK-NEXT:  entry:
46 // CHECK-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.mve.sqrshr(i32 [[VALUE:%.*]], i32 [[SHIFT:%.*]])
47 // CHECK-NEXT:    ret i32 [[TMP0]]
48 //
test_sqrshr(int32_t value,int32_t shift)49 int32_t test_sqrshr(int32_t value, int32_t shift)
50 {
51     return sqrshr(value, shift);
52 }
53 
54 // CHECK-LABEL: @test_sqrshrl(
55 // CHECK-NEXT:  entry:
56 // CHECK-NEXT:    [[TMP0:%.*]] = lshr i64 [[VALUE:%.*]], 32
57 // CHECK-NEXT:    [[TMP1:%.*]] = trunc i64 [[TMP0]] to i32
58 // CHECK-NEXT:    [[TMP2:%.*]] = trunc i64 [[VALUE]] to i32
59 // CHECK-NEXT:    [[TMP3:%.*]] = call { i32, i32 } @llvm.arm.mve.sqrshrl(i32 [[TMP2]], i32 [[TMP1]], i32 [[SHIFT:%.*]], i32 64)
60 // CHECK-NEXT:    [[TMP4:%.*]] = extractvalue { i32, i32 } [[TMP3]], 1
61 // CHECK-NEXT:    [[TMP5:%.*]] = zext i32 [[TMP4]] to i64
62 // CHECK-NEXT:    [[TMP6:%.*]] = shl i64 [[TMP5]], 32
63 // CHECK-NEXT:    [[TMP7:%.*]] = extractvalue { i32, i32 } [[TMP3]], 0
64 // CHECK-NEXT:    [[TMP8:%.*]] = zext i32 [[TMP7]] to i64
65 // CHECK-NEXT:    [[TMP9:%.*]] = or i64 [[TMP6]], [[TMP8]]
66 // CHECK-NEXT:    ret i64 [[TMP9]]
67 //
test_sqrshrl(int64_t value,int32_t shift)68 int64_t test_sqrshrl(int64_t value, int32_t shift)
69 {
70     return sqrshrl(value, shift);
71 }
72 
73 // CHECK-LABEL: @test_sqrshrl_sat48(
74 // CHECK-NEXT:  entry:
75 // CHECK-NEXT:    [[TMP0:%.*]] = lshr i64 [[VALUE:%.*]], 32
76 // CHECK-NEXT:    [[TMP1:%.*]] = trunc i64 [[TMP0]] to i32
77 // CHECK-NEXT:    [[TMP2:%.*]] = trunc i64 [[VALUE]] to i32
78 // CHECK-NEXT:    [[TMP3:%.*]] = call { i32, i32 } @llvm.arm.mve.sqrshrl(i32 [[TMP2]], i32 [[TMP1]], i32 [[SHIFT:%.*]], i32 48)
79 // CHECK-NEXT:    [[TMP4:%.*]] = extractvalue { i32, i32 } [[TMP3]], 1
80 // CHECK-NEXT:    [[TMP5:%.*]] = zext i32 [[TMP4]] to i64
81 // CHECK-NEXT:    [[TMP6:%.*]] = shl i64 [[TMP5]], 32
82 // CHECK-NEXT:    [[TMP7:%.*]] = extractvalue { i32, i32 } [[TMP3]], 0
83 // CHECK-NEXT:    [[TMP8:%.*]] = zext i32 [[TMP7]] to i64
84 // CHECK-NEXT:    [[TMP9:%.*]] = or i64 [[TMP6]], [[TMP8]]
85 // CHECK-NEXT:    ret i64 [[TMP9]]
86 //
test_sqrshrl_sat48(int64_t value,int32_t shift)87 int64_t test_sqrshrl_sat48(int64_t value, int32_t shift)
88 {
89     return sqrshrl_sat48(value, shift);
90 }
91 
92 // CHECK-LABEL: @test_sqshl(
93 // CHECK-NEXT:  entry:
94 // CHECK-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.mve.sqshl(i32 [[VALUE:%.*]], i32 2)
95 // CHECK-NEXT:    ret i32 [[TMP0]]
96 //
test_sqshl(int32_t value)97 int32_t test_sqshl(int32_t value)
98 {
99     return sqshl(value, 2);
100 }
101 
102 // CHECK-LABEL: @test_sqshll(
103 // CHECK-NEXT:  entry:
104 // CHECK-NEXT:    [[TMP0:%.*]] = lshr i64 [[VALUE:%.*]], 32
105 // CHECK-NEXT:    [[TMP1:%.*]] = trunc i64 [[TMP0]] to i32
106 // CHECK-NEXT:    [[TMP2:%.*]] = trunc i64 [[VALUE]] to i32
107 // CHECK-NEXT:    [[TMP3:%.*]] = call { i32, i32 } @llvm.arm.mve.sqshll(i32 [[TMP2]], i32 [[TMP1]], i32 17)
108 // CHECK-NEXT:    [[TMP4:%.*]] = extractvalue { i32, i32 } [[TMP3]], 1
109 // CHECK-NEXT:    [[TMP5:%.*]] = zext i32 [[TMP4]] to i64
110 // CHECK-NEXT:    [[TMP6:%.*]] = shl i64 [[TMP5]], 32
111 // CHECK-NEXT:    [[TMP7:%.*]] = extractvalue { i32, i32 } [[TMP3]], 0
112 // CHECK-NEXT:    [[TMP8:%.*]] = zext i32 [[TMP7]] to i64
113 // CHECK-NEXT:    [[TMP9:%.*]] = or i64 [[TMP6]], [[TMP8]]
114 // CHECK-NEXT:    ret i64 [[TMP9]]
115 //
test_sqshll(int64_t value)116 int64_t test_sqshll(int64_t value)
117 {
118     return sqshll(value, 17);
119 }
120 
121 // CHECK-LABEL: @test_srshr(
122 // CHECK-NEXT:  entry:
123 // CHECK-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.mve.srshr(i32 [[VALUE:%.*]], i32 6)
124 // CHECK-NEXT:    ret i32 [[TMP0]]
125 //
test_srshr(int32_t value)126 int32_t test_srshr(int32_t value)
127 {
128     return srshr(value, 6);
129 }
130 
131 // CHECK-LABEL: @test_srshrl(
132 // CHECK-NEXT:  entry:
133 // CHECK-NEXT:    [[TMP0:%.*]] = lshr i64 [[VALUE:%.*]], 32
134 // CHECK-NEXT:    [[TMP1:%.*]] = trunc i64 [[TMP0]] to i32
135 // CHECK-NEXT:    [[TMP2:%.*]] = trunc i64 [[VALUE]] to i32
136 // CHECK-NEXT:    [[TMP3:%.*]] = call { i32, i32 } @llvm.arm.mve.srshrl(i32 [[TMP2]], i32 [[TMP1]], i32 26)
137 // CHECK-NEXT:    [[TMP4:%.*]] = extractvalue { i32, i32 } [[TMP3]], 1
138 // CHECK-NEXT:    [[TMP5:%.*]] = zext i32 [[TMP4]] to i64
139 // CHECK-NEXT:    [[TMP6:%.*]] = shl i64 [[TMP5]], 32
140 // CHECK-NEXT:    [[TMP7:%.*]] = extractvalue { i32, i32 } [[TMP3]], 0
141 // CHECK-NEXT:    [[TMP8:%.*]] = zext i32 [[TMP7]] to i64
142 // CHECK-NEXT:    [[TMP9:%.*]] = or i64 [[TMP6]], [[TMP8]]
143 // CHECK-NEXT:    ret i64 [[TMP9]]
144 //
test_srshrl(int64_t value)145 int64_t test_srshrl(int64_t value)
146 {
147     return srshrl(value, 26);
148 }
149 
150 // CHECK-LABEL: @test_uqrshl(
151 // CHECK-NEXT:  entry:
152 // CHECK-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.mve.uqrshl(i32 [[VALUE:%.*]], i32 [[SHIFT:%.*]])
153 // CHECK-NEXT:    ret i32 [[TMP0]]
154 //
test_uqrshl(uint32_t value,int32_t shift)155 uint32_t test_uqrshl(uint32_t value, int32_t shift)
156 {
157     return uqrshl(value, shift);
158 }
159 
160 // CHECK-LABEL: @test_uqrshll(
161 // CHECK-NEXT:  entry:
162 // CHECK-NEXT:    [[TMP0:%.*]] = lshr i64 [[VALUE:%.*]], 32
163 // CHECK-NEXT:    [[TMP1:%.*]] = trunc i64 [[TMP0]] to i32
164 // CHECK-NEXT:    [[TMP2:%.*]] = trunc i64 [[VALUE]] to i32
165 // CHECK-NEXT:    [[TMP3:%.*]] = call { i32, i32 } @llvm.arm.mve.uqrshll(i32 [[TMP2]], i32 [[TMP1]], i32 [[SHIFT:%.*]], i32 64)
166 // CHECK-NEXT:    [[TMP4:%.*]] = extractvalue { i32, i32 } [[TMP3]], 1
167 // CHECK-NEXT:    [[TMP5:%.*]] = zext i32 [[TMP4]] to i64
168 // CHECK-NEXT:    [[TMP6:%.*]] = shl i64 [[TMP5]], 32
169 // CHECK-NEXT:    [[TMP7:%.*]] = extractvalue { i32, i32 } [[TMP3]], 0
170 // CHECK-NEXT:    [[TMP8:%.*]] = zext i32 [[TMP7]] to i64
171 // CHECK-NEXT:    [[TMP9:%.*]] = or i64 [[TMP6]], [[TMP8]]
172 // CHECK-NEXT:    ret i64 [[TMP9]]
173 //
test_uqrshll(uint64_t value,int32_t shift)174 uint64_t test_uqrshll(uint64_t value, int32_t shift)
175 {
176     return uqrshll(value, shift);
177 }
178 
179 // CHECK-LABEL: @test_uqrshll_sat48(
180 // CHECK-NEXT:  entry:
181 // CHECK-NEXT:    [[TMP0:%.*]] = lshr i64 [[VALUE:%.*]], 32
182 // CHECK-NEXT:    [[TMP1:%.*]] = trunc i64 [[TMP0]] to i32
183 // CHECK-NEXT:    [[TMP2:%.*]] = trunc i64 [[VALUE]] to i32
184 // CHECK-NEXT:    [[TMP3:%.*]] = call { i32, i32 } @llvm.arm.mve.uqrshll(i32 [[TMP2]], i32 [[TMP1]], i32 [[SHIFT:%.*]], i32 48)
185 // CHECK-NEXT:    [[TMP4:%.*]] = extractvalue { i32, i32 } [[TMP3]], 1
186 // CHECK-NEXT:    [[TMP5:%.*]] = zext i32 [[TMP4]] to i64
187 // CHECK-NEXT:    [[TMP6:%.*]] = shl i64 [[TMP5]], 32
188 // CHECK-NEXT:    [[TMP7:%.*]] = extractvalue { i32, i32 } [[TMP3]], 0
189 // CHECK-NEXT:    [[TMP8:%.*]] = zext i32 [[TMP7]] to i64
190 // CHECK-NEXT:    [[TMP9:%.*]] = or i64 [[TMP6]], [[TMP8]]
191 // CHECK-NEXT:    ret i64 [[TMP9]]
192 //
test_uqrshll_sat48(uint64_t value,int32_t shift)193 uint64_t test_uqrshll_sat48(uint64_t value, int32_t shift)
194 {
195     return uqrshll_sat48(value, shift);
196 }
197 
198 // CHECK-LABEL: @test_uqshl(
199 // CHECK-NEXT:  entry:
200 // CHECK-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.mve.uqshl(i32 [[VALUE:%.*]], i32 21)
201 // CHECK-NEXT:    ret i32 [[TMP0]]
202 //
test_uqshl(uint32_t value)203 uint32_t test_uqshl(uint32_t value)
204 {
205     return uqshl(value, 21);
206 }
207 
208 // CHECK-LABEL: @test_uqshll(
209 // CHECK-NEXT:  entry:
210 // CHECK-NEXT:    [[TMP0:%.*]] = lshr i64 [[VALUE:%.*]], 32
211 // CHECK-NEXT:    [[TMP1:%.*]] = trunc i64 [[TMP0]] to i32
212 // CHECK-NEXT:    [[TMP2:%.*]] = trunc i64 [[VALUE]] to i32
213 // CHECK-NEXT:    [[TMP3:%.*]] = call { i32, i32 } @llvm.arm.mve.uqshll(i32 [[TMP2]], i32 [[TMP1]], i32 16)
214 // CHECK-NEXT:    [[TMP4:%.*]] = extractvalue { i32, i32 } [[TMP3]], 1
215 // CHECK-NEXT:    [[TMP5:%.*]] = zext i32 [[TMP4]] to i64
216 // CHECK-NEXT:    [[TMP6:%.*]] = shl i64 [[TMP5]], 32
217 // CHECK-NEXT:    [[TMP7:%.*]] = extractvalue { i32, i32 } [[TMP3]], 0
218 // CHECK-NEXT:    [[TMP8:%.*]] = zext i32 [[TMP7]] to i64
219 // CHECK-NEXT:    [[TMP9:%.*]] = or i64 [[TMP6]], [[TMP8]]
220 // CHECK-NEXT:    ret i64 [[TMP9]]
221 //
test_uqshll(uint64_t value)222 uint64_t test_uqshll(uint64_t value)
223 {
224     return uqshll(value, 16);
225 }
226 
227 // CHECK-LABEL: @test_urshr(
228 // CHECK-NEXT:  entry:
229 // CHECK-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.mve.urshr(i32 [[VALUE:%.*]], i32 22)
230 // CHECK-NEXT:    ret i32 [[TMP0]]
231 //
test_urshr(uint32_t value)232 uint32_t test_urshr(uint32_t value)
233 {
234     return urshr(value, 22);
235 }
236 
237 // CHECK-LABEL: @test_urshrl(
238 // CHECK-NEXT:  entry:
239 // CHECK-NEXT:    [[TMP0:%.*]] = lshr i64 [[VALUE:%.*]], 32
240 // CHECK-NEXT:    [[TMP1:%.*]] = trunc i64 [[TMP0]] to i32
241 // CHECK-NEXT:    [[TMP2:%.*]] = trunc i64 [[VALUE]] to i32
242 // CHECK-NEXT:    [[TMP3:%.*]] = call { i32, i32 } @llvm.arm.mve.urshrl(i32 [[TMP2]], i32 [[TMP1]], i32 6)
243 // CHECK-NEXT:    [[TMP4:%.*]] = extractvalue { i32, i32 } [[TMP3]], 1
244 // CHECK-NEXT:    [[TMP5:%.*]] = zext i32 [[TMP4]] to i64
245 // CHECK-NEXT:    [[TMP6:%.*]] = shl i64 [[TMP5]], 32
246 // CHECK-NEXT:    [[TMP7:%.*]] = extractvalue { i32, i32 } [[TMP3]], 0
247 // CHECK-NEXT:    [[TMP8:%.*]] = zext i32 [[TMP7]] to i64
248 // CHECK-NEXT:    [[TMP9:%.*]] = or i64 [[TMP6]], [[TMP8]]
249 // CHECK-NEXT:    ret i64 [[TMP9]]
250 //
test_urshrl(uint64_t value)251 uint64_t test_urshrl(uint64_t value)
252 {
253     return urshrl(value, 6);
254 }
255