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