1 // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --function-signature 2 // RUN: %clang_cc1 -no-opaque-pointers -triple arm64-none-linux-gnu -target-feature +neon \ 3 // RUN: -disable-O0-optnone -ffp-contract=fast -emit-llvm -o - %s | opt -S -mem2reg \ 4 // RUN: | FileCheck %s 5 6 // REQUIRES: aarch64-registered-target 7 8 // Test new aarch64 intrinsics with poly128 9 // FIXME: Currently, poly128_t equals to uint128, which will be spilt into 10 // two 64-bit GPR(eg X0, X1). Now moving data from X0, X1 to FPR128 will 11 // introduce 2 store and 1 load instructions(store X0, X1 to memory and 12 // then load back to Q0). If target has NEON, this is better replaced by 13 // FMOV or INS. 14 15 #include <arm_neon.h> 16 17 // CHECK-LABEL: define {{[^@]+}}@test_vstrq_p128 18 // CHECK-SAME: (i128* noundef [[PTR:%.*]], i128 noundef [[VAL:%.*]]) #[[ATTR0:[0-9]+]] { 19 // CHECK-NEXT: entry: 20 // CHECK-NEXT: [[TMP0:%.*]] = bitcast i128* [[PTR]] to i8* 21 // CHECK-NEXT: [[TMP1:%.*]] = bitcast i8* [[TMP0]] to i128* 22 // CHECK-NEXT: store i128 [[VAL]], i128* [[TMP1]], align 16 23 // CHECK-NEXT: ret void 24 // 25 void test_vstrq_p128(poly128_t * ptr, poly128_t val) { 26 vstrq_p128(ptr, val); 27 28 } 29 30 // CHECK-LABEL: define {{[^@]+}}@test_vldrq_p128 31 // CHECK-SAME: (i128* noundef [[PTR:%.*]]) #[[ATTR0]] { 32 // CHECK-NEXT: entry: 33 // CHECK-NEXT: [[TMP0:%.*]] = bitcast i128* [[PTR]] to i8* 34 // CHECK-NEXT: [[TMP1:%.*]] = bitcast i8* [[TMP0]] to i128* 35 // CHECK-NEXT: [[TMP2:%.*]] = load i128, i128* [[TMP1]], align 16 36 // CHECK-NEXT: ret i128 [[TMP2]] 37 // 38 poly128_t test_vldrq_p128(poly128_t * ptr) { 39 return vldrq_p128(ptr); 40 41 } 42 43 // CHECK-LABEL: define {{[^@]+}}@test_ld_st_p128 44 // CHECK-SAME: (i128* noundef [[PTR:%.*]]) #[[ATTR0]] { 45 // CHECK-NEXT: entry: 46 // CHECK-NEXT: [[TMP0:%.*]] = bitcast i128* [[PTR]] to i8* 47 // CHECK-NEXT: [[TMP1:%.*]] = bitcast i8* [[TMP0]] to i128* 48 // CHECK-NEXT: [[TMP2:%.*]] = load i128, i128* [[TMP1]], align 16 49 // CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i128, i128* [[PTR]], i64 1 50 // CHECK-NEXT: [[TMP3:%.*]] = bitcast i128* [[ADD_PTR]] to i8* 51 // CHECK-NEXT: [[TMP4:%.*]] = bitcast i8* [[TMP3]] to i128* 52 // CHECK-NEXT: store i128 [[TMP2]], i128* [[TMP4]], align 16 53 // CHECK-NEXT: ret void 54 // 55 void test_ld_st_p128(poly128_t * ptr) { 56 vstrq_p128(ptr+1, vldrq_p128(ptr)); 57 58 } 59 60 // CHECK-LABEL: define {{[^@]+}}@test_vmull_p64 61 // CHECK-SAME: (i64 noundef [[A:%.*]], i64 noundef [[B:%.*]]) #[[ATTR0]] { 62 // CHECK-NEXT: entry: 63 // CHECK-NEXT: [[VMULL_P64_I:%.*]] = call <16 x i8> @llvm.aarch64.neon.pmull64(i64 [[A]], i64 [[B]]) 64 // CHECK-NEXT: [[VMULL_P641_I:%.*]] = bitcast <16 x i8> [[VMULL_P64_I]] to i128 65 // CHECK-NEXT: ret i128 [[VMULL_P641_I]] 66 // 67 poly128_t test_vmull_p64(poly64_t a, poly64_t b) { 68 return vmull_p64(a, b); 69 } 70 71 // CHECK-LABEL: define {{[^@]+}}@test_vmull_high_p64 72 // CHECK-SAME: (<2 x i64> noundef [[A:%.*]], <2 x i64> noundef [[B:%.*]]) #[[ATTR1:[0-9]+]] { 73 // CHECK-NEXT: entry: 74 // CHECK-NEXT: [[SHUFFLE_I5:%.*]] = shufflevector <2 x i64> [[A]], <2 x i64> [[A]], <1 x i32> <i32 1> 75 // CHECK-NEXT: [[TMP0:%.*]] = bitcast <1 x i64> [[SHUFFLE_I5]] to i64 76 // CHECK-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <2 x i64> [[B]], <2 x i64> [[B]], <1 x i32> <i32 1> 77 // CHECK-NEXT: [[TMP1:%.*]] = bitcast <1 x i64> [[SHUFFLE_I]] to i64 78 // CHECK-NEXT: [[VMULL_P64_I_I:%.*]] = call <16 x i8> @llvm.aarch64.neon.pmull64(i64 [[TMP0]], i64 [[TMP1]]) 79 // CHECK-NEXT: [[VMULL_P641_I_I:%.*]] = bitcast <16 x i8> [[VMULL_P64_I_I]] to i128 80 // CHECK-NEXT: ret i128 [[VMULL_P641_I_I]] 81 // 82 poly128_t test_vmull_high_p64(poly64x2_t a, poly64x2_t b) { 83 return vmull_high_p64(a, b); 84 } 85 86 // CHECK-LABEL: define {{[^@]+}}@test_vreinterpretq_p128_s8 87 // CHECK-SAME: (<16 x i8> noundef [[A:%.*]]) #[[ATTR1]] { 88 // CHECK-NEXT: entry: 89 // CHECK-NEXT: [[TMP0:%.*]] = bitcast <16 x i8> [[A]] to i128 90 // CHECK-NEXT: ret i128 [[TMP0]] 91 // 92 poly128_t test_vreinterpretq_p128_s8(int8x16_t a) { 93 return vreinterpretq_p128_s8(a); 94 } 95 96 // CHECK-LABEL: define {{[^@]+}}@test_vreinterpretq_p128_s16 97 // CHECK-SAME: (<8 x i16> noundef [[A:%.*]]) #[[ATTR1]] { 98 // CHECK-NEXT: entry: 99 // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x i16> [[A]] to i128 100 // CHECK-NEXT: ret i128 [[TMP0]] 101 // 102 poly128_t test_vreinterpretq_p128_s16(int16x8_t a) { 103 return vreinterpretq_p128_s16(a); 104 } 105 106 // CHECK-LABEL: define {{[^@]+}}@test_vreinterpretq_p128_s32 107 // CHECK-SAME: (<4 x i32> noundef [[A:%.*]]) #[[ATTR1]] { 108 // CHECK-NEXT: entry: 109 // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x i32> [[A]] to i128 110 // CHECK-NEXT: ret i128 [[TMP0]] 111 // 112 poly128_t test_vreinterpretq_p128_s32(int32x4_t a) { 113 return vreinterpretq_p128_s32(a); 114 } 115 116 // CHECK-LABEL: define {{[^@]+}}@test_vreinterpretq_p128_s64 117 // CHECK-SAME: (<2 x i64> noundef [[A:%.*]]) #[[ATTR1]] { 118 // CHECK-NEXT: entry: 119 // CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x i64> [[A]] to i128 120 // CHECK-NEXT: ret i128 [[TMP0]] 121 // 122 poly128_t test_vreinterpretq_p128_s64(int64x2_t a) { 123 return vreinterpretq_p128_s64(a); 124 } 125 126 // CHECK-LABEL: define {{[^@]+}}@test_vreinterpretq_p128_u8 127 // CHECK-SAME: (<16 x i8> noundef [[A:%.*]]) #[[ATTR1]] { 128 // CHECK-NEXT: entry: 129 // CHECK-NEXT: [[TMP0:%.*]] = bitcast <16 x i8> [[A]] to i128 130 // CHECK-NEXT: ret i128 [[TMP0]] 131 // 132 poly128_t test_vreinterpretq_p128_u8(uint8x16_t a) { 133 return vreinterpretq_p128_u8(a); 134 } 135 136 // CHECK-LABEL: define {{[^@]+}}@test_vreinterpretq_p128_u16 137 // CHECK-SAME: (<8 x i16> noundef [[A:%.*]]) #[[ATTR1]] { 138 // CHECK-NEXT: entry: 139 // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x i16> [[A]] to i128 140 // CHECK-NEXT: ret i128 [[TMP0]] 141 // 142 poly128_t test_vreinterpretq_p128_u16(uint16x8_t a) { 143 return vreinterpretq_p128_u16(a); 144 } 145 146 // CHECK-LABEL: define {{[^@]+}}@test_vreinterpretq_p128_u32 147 // CHECK-SAME: (<4 x i32> noundef [[A:%.*]]) #[[ATTR1]] { 148 // CHECK-NEXT: entry: 149 // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x i32> [[A]] to i128 150 // CHECK-NEXT: ret i128 [[TMP0]] 151 // 152 poly128_t test_vreinterpretq_p128_u32(uint32x4_t a) { 153 return vreinterpretq_p128_u32(a); 154 } 155 156 // CHECK-LABEL: define {{[^@]+}}@test_vreinterpretq_p128_u64 157 // CHECK-SAME: (<2 x i64> noundef [[A:%.*]]) #[[ATTR1]] { 158 // CHECK-NEXT: entry: 159 // CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x i64> [[A]] to i128 160 // CHECK-NEXT: ret i128 [[TMP0]] 161 // 162 poly128_t test_vreinterpretq_p128_u64(uint64x2_t a) { 163 return vreinterpretq_p128_u64(a); 164 } 165 166 // CHECK-LABEL: define {{[^@]+}}@test_vreinterpretq_p128_f32 167 // CHECK-SAME: (<4 x float> noundef [[A:%.*]]) #[[ATTR1]] { 168 // CHECK-NEXT: entry: 169 // CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x float> [[A]] to i128 170 // CHECK-NEXT: ret i128 [[TMP0]] 171 // 172 poly128_t test_vreinterpretq_p128_f32(float32x4_t a) { 173 return vreinterpretq_p128_f32(a); 174 } 175 176 // CHECK-LABEL: define {{[^@]+}}@test_vreinterpretq_p128_f64 177 // CHECK-SAME: (<2 x double> noundef [[A:%.*]]) #[[ATTR1]] { 178 // CHECK-NEXT: entry: 179 // CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x double> [[A]] to i128 180 // CHECK-NEXT: ret i128 [[TMP0]] 181 // 182 poly128_t test_vreinterpretq_p128_f64(float64x2_t a) { 183 return vreinterpretq_p128_f64(a); 184 } 185 186 // CHECK-LABEL: define {{[^@]+}}@test_vreinterpretq_p128_p8 187 // CHECK-SAME: (<16 x i8> noundef [[A:%.*]]) #[[ATTR1]] { 188 // CHECK-NEXT: entry: 189 // CHECK-NEXT: [[TMP0:%.*]] = bitcast <16 x i8> [[A]] to i128 190 // CHECK-NEXT: ret i128 [[TMP0]] 191 // 192 poly128_t test_vreinterpretq_p128_p8(poly8x16_t a) { 193 return vreinterpretq_p128_p8(a); 194 } 195 196 // CHECK-LABEL: define {{[^@]+}}@test_vreinterpretq_p128_p16 197 // CHECK-SAME: (<8 x i16> noundef [[A:%.*]]) #[[ATTR1]] { 198 // CHECK-NEXT: entry: 199 // CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x i16> [[A]] to i128 200 // CHECK-NEXT: ret i128 [[TMP0]] 201 // 202 poly128_t test_vreinterpretq_p128_p16(poly16x8_t a) { 203 return vreinterpretq_p128_p16(a); 204 } 205 206 // CHECK-LABEL: define {{[^@]+}}@test_vreinterpretq_p128_p64 207 // CHECK-SAME: (<2 x i64> noundef [[A:%.*]]) #[[ATTR1]] { 208 // CHECK-NEXT: entry: 209 // CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x i64> [[A]] to i128 210 // CHECK-NEXT: ret i128 [[TMP0]] 211 // 212 poly128_t test_vreinterpretq_p128_p64(poly64x2_t a) { 213 return vreinterpretq_p128_p64(a); 214 } 215 216 // CHECK-LABEL: define {{[^@]+}}@test_vreinterpretq_s8_p128 217 // CHECK-SAME: (i128 noundef [[A:%.*]]) #[[ATTR1]] { 218 // CHECK-NEXT: entry: 219 // CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[A]] to <16 x i8> 220 // CHECK-NEXT: ret <16 x i8> [[TMP0]] 221 // 222 int8x16_t test_vreinterpretq_s8_p128(poly128_t a) { 223 return vreinterpretq_s8_p128(a); 224 } 225 226 // CHECK-LABEL: define {{[^@]+}}@test_vreinterpretq_s16_p128 227 // CHECK-SAME: (i128 noundef [[A:%.*]]) #[[ATTR1]] { 228 // CHECK-NEXT: entry: 229 // CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[A]] to <8 x i16> 230 // CHECK-NEXT: ret <8 x i16> [[TMP0]] 231 // 232 int16x8_t test_vreinterpretq_s16_p128(poly128_t a) { 233 return vreinterpretq_s16_p128(a); 234 } 235 236 // CHECK-LABEL: define {{[^@]+}}@test_vreinterpretq_s32_p128 237 // CHECK-SAME: (i128 noundef [[A:%.*]]) #[[ATTR1]] { 238 // CHECK-NEXT: entry: 239 // CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[A]] to <4 x i32> 240 // CHECK-NEXT: ret <4 x i32> [[TMP0]] 241 // 242 int32x4_t test_vreinterpretq_s32_p128(poly128_t a) { 243 return vreinterpretq_s32_p128(a); 244 } 245 246 // CHECK-LABEL: define {{[^@]+}}@test_vreinterpretq_s64_p128 247 // CHECK-SAME: (i128 noundef [[A:%.*]]) #[[ATTR1]] { 248 // CHECK-NEXT: entry: 249 // CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[A]] to <2 x i64> 250 // CHECK-NEXT: ret <2 x i64> [[TMP0]] 251 // 252 int64x2_t test_vreinterpretq_s64_p128(poly128_t a) { 253 return vreinterpretq_s64_p128(a); 254 } 255 256 // CHECK-LABEL: define {{[^@]+}}@test_vreinterpretq_u8_p128 257 // CHECK-SAME: (i128 noundef [[A:%.*]]) #[[ATTR1]] { 258 // CHECK-NEXT: entry: 259 // CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[A]] to <16 x i8> 260 // CHECK-NEXT: ret <16 x i8> [[TMP0]] 261 // 262 uint8x16_t test_vreinterpretq_u8_p128(poly128_t a) { 263 return vreinterpretq_u8_p128(a); 264 } 265 266 // CHECK-LABEL: define {{[^@]+}}@test_vreinterpretq_u16_p128 267 // CHECK-SAME: (i128 noundef [[A:%.*]]) #[[ATTR1]] { 268 // CHECK-NEXT: entry: 269 // CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[A]] to <8 x i16> 270 // CHECK-NEXT: ret <8 x i16> [[TMP0]] 271 // 272 uint16x8_t test_vreinterpretq_u16_p128(poly128_t a) { 273 return vreinterpretq_u16_p128(a); 274 } 275 276 // CHECK-LABEL: define {{[^@]+}}@test_vreinterpretq_u32_p128 277 // CHECK-SAME: (i128 noundef [[A:%.*]]) #[[ATTR1]] { 278 // CHECK-NEXT: entry: 279 // CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[A]] to <4 x i32> 280 // CHECK-NEXT: ret <4 x i32> [[TMP0]] 281 // 282 uint32x4_t test_vreinterpretq_u32_p128(poly128_t a) { 283 return vreinterpretq_u32_p128(a); 284 } 285 286 // CHECK-LABEL: define {{[^@]+}}@test_vreinterpretq_u64_p128 287 // CHECK-SAME: (i128 noundef [[A:%.*]]) #[[ATTR1]] { 288 // CHECK-NEXT: entry: 289 // CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[A]] to <2 x i64> 290 // CHECK-NEXT: ret <2 x i64> [[TMP0]] 291 // 292 uint64x2_t test_vreinterpretq_u64_p128(poly128_t a) { 293 return vreinterpretq_u64_p128(a); 294 } 295 296 // CHECK-LABEL: define {{[^@]+}}@test_vreinterpretq_f32_p128 297 // CHECK-SAME: (i128 noundef [[A:%.*]]) #[[ATTR1]] { 298 // CHECK-NEXT: entry: 299 // CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[A]] to <4 x float> 300 // CHECK-NEXT: ret <4 x float> [[TMP0]] 301 // 302 float32x4_t test_vreinterpretq_f32_p128(poly128_t a) { 303 return vreinterpretq_f32_p128(a); 304 } 305 306 // CHECK-LABEL: define {{[^@]+}}@test_vreinterpretq_f64_p128 307 // CHECK-SAME: (i128 noundef [[A:%.*]]) #[[ATTR1]] { 308 // CHECK-NEXT: entry: 309 // CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[A]] to <2 x double> 310 // CHECK-NEXT: ret <2 x double> [[TMP0]] 311 // 312 float64x2_t test_vreinterpretq_f64_p128(poly128_t a) { 313 return vreinterpretq_f64_p128(a); 314 } 315 316 // CHECK-LABEL: define {{[^@]+}}@test_vreinterpretq_p8_p128 317 // CHECK-SAME: (i128 noundef [[A:%.*]]) #[[ATTR1]] { 318 // CHECK-NEXT: entry: 319 // CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[A]] to <16 x i8> 320 // CHECK-NEXT: ret <16 x i8> [[TMP0]] 321 // 322 poly8x16_t test_vreinterpretq_p8_p128(poly128_t a) { 323 return vreinterpretq_p8_p128(a); 324 } 325 326 // CHECK-LABEL: define {{[^@]+}}@test_vreinterpretq_p16_p128 327 // CHECK-SAME: (i128 noundef [[A:%.*]]) #[[ATTR1]] { 328 // CHECK-NEXT: entry: 329 // CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[A]] to <8 x i16> 330 // CHECK-NEXT: ret <8 x i16> [[TMP0]] 331 // 332 poly16x8_t test_vreinterpretq_p16_p128(poly128_t a) { 333 return vreinterpretq_p16_p128(a); 334 } 335 336 // CHECK-LABEL: define {{[^@]+}}@test_vreinterpretq_p64_p128 337 // CHECK-SAME: (i128 noundef [[A:%.*]]) #[[ATTR1]] { 338 // CHECK-NEXT: entry: 339 // CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[A]] to <2 x i64> 340 // CHECK-NEXT: ret <2 x i64> [[TMP0]] 341 // 342 poly64x2_t test_vreinterpretq_p64_p128(poly128_t a) { 343 return vreinterpretq_p64_p128(a); 344 } 345 346 347