Skip to content

Commit 8a61a2b

Browse files
ghehglanza
authored andcommitted
[CIR][CIRGen][Builtin][Neon] Lower neon_vqaddq_v, neon_vqsubq and neon_vqsub (#988)
1 parent 70c24e5 commit 8a61a2b

File tree

2 files changed

+294
-12
lines changed

2 files changed

+294
-12
lines changed

clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2212,7 +2212,7 @@ static int64_t getIntValueFromConstOp(mlir::Value val) {
22122212
/// expression type.
22132213
/// 2. Function arg types are given, not deduced from actual arg types.
22142214
static mlir::Value
2215-
buildCommonNeonCallPattern0(CIRGenFunction &cgf, std::string &intrincsName,
2215+
buildCommonNeonCallPattern0(CIRGenFunction &cgf, llvm::StringRef intrincsName,
22162216
llvm::SmallVector<mlir::Type> argTypes,
22172217
llvm::SmallVectorImpl<mlir::Value> &ops,
22182218
mlir::Type funcResTy, const clang::CallExpr *e) {
@@ -2328,29 +2328,35 @@ mlir::Value CIRGenFunction::buildCommonNeonBuiltinExpr(
23282328

23292329
// This second switch is for the intrinsics that might have a more generic
23302330
// codegen solution so we can use the common codegen in future.
2331+
llvm::StringRef intrincsName;
23312332
switch (builtinID) {
23322333
default:
23332334
llvm::errs() << getAArch64SIMDIntrinsicString(builtinID) << " ";
23342335
llvm_unreachable("NYI");
23352336

23362337
case NEON::BI__builtin_neon_vpadd_v:
23372338
case NEON::BI__builtin_neon_vpaddq_v: {
2338-
std::string intrincsName = mlir::isa<mlir::FloatType>(vTy.getEltType())
2339-
? "llvm.aarch64.neon.faddp"
2340-
: "llvm.aarch64.neon.addp";
2341-
return buildCommonNeonCallPattern0(*this, intrincsName, {vTy, vTy}, ops,
2342-
vTy, e);
2339+
intrincsName = mlir::isa<mlir::FloatType>(vTy.getEltType())
2340+
? "llvm.aarch64.neon.faddp"
2341+
: "llvm.aarch64.neon.addp";
23432342
break;
23442343
}
2345-
case NEON::BI__builtin_neon_vqadd_v: {
2346-
std::string intrincsName = (intrinicId != altLLVMIntrinsic)
2347-
? "llvm.aarch64.neon.uqadd"
2348-
: "llvm.aarch64.neon.sqadd";
2349-
return buildCommonNeonCallPattern0(*this, intrincsName, {vTy, vTy}, ops,
2350-
vTy, e);
2344+
case NEON::BI__builtin_neon_vqadd_v:
2345+
case NEON::BI__builtin_neon_vqaddq_v: {
2346+
intrincsName = (intrinicId != altLLVMIntrinsic) ? "llvm.aarch64.neon.uqadd"
2347+
: "llvm.aarch64.neon.sqadd";
2348+
break;
2349+
}
2350+
case NEON::BI__builtin_neon_vqsub_v:
2351+
case NEON::BI__builtin_neon_vqsubq_v: {
2352+
intrincsName = (intrinicId != altLLVMIntrinsic) ? "llvm.aarch64.neon.uqsub"
2353+
: "llvm.aarch64.neon.sqsub";
23512354
break;
23522355
}
23532356
}
2357+
if (!intrincsName.empty())
2358+
return buildCommonNeonCallPattern0(*this, intrincsName, {vTy, vTy}, ops,
2359+
vTy, e);
23542360
return nullptr;
23552361
}
23562362

clang/test/CIR/CodeGen/AArch64/neon-arith.c

Lines changed: 276 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,3 +331,279 @@ int32x4_t test_vqrdmulhq_lane_s32(int32x4_t a, int32x2_t v) {
331331
// LLVM: [[RES:%.*]] = call <4 x i32> @llvm.aarch64.neon.sqrdmulh.lane.v4i32.v2i32
332332
// LLVM-SAME: (<4 x i32> [[A]], <2 x i32> [[V]], i32 1)
333333
// LLVM: ret <4 x i32> [[RES]]
334+
335+
int8x16_t test_vqaddq_s8(int8x16_t a, int8x16_t b) {
336+
return vqaddq_s8(a, b);
337+
}
338+
339+
// CIR-LABEL: vqaddq_s8
340+
// CIR: {{%.*}} = cir.llvm.intrinsic "llvm.aarch64.neon.sqadd" {{%.*}}, {{%.*}} :
341+
// CIR-SAME: (!cir.vector<!s8i x 16>, !cir.vector<!s8i x 16>) -> !cir.vector<!s8i x 16>
342+
343+
// LLVM: {{.*}}test_vqaddq_s8(<16 x i8>{{.*}} [[A:%.*]], <16 x i8>{{.*}} [[B:%.*]])
344+
// LLVM: [[RES:%.*]] = call <16 x i8> @llvm.aarch64.neon.sqadd.v16i8(<16 x i8> [[A]], <16 x i8> [[B]])
345+
// LLVM: ret <16 x i8> [[RES]]
346+
347+
uint8x16_t test_vqaddq_u8(uint8x16_t a, uint8x16_t b) {
348+
return vqaddq_u8(a, b);
349+
}
350+
351+
// CIR-LABEL: vqaddq_u8
352+
// CIR: {{%.*}} = cir.llvm.intrinsic "llvm.aarch64.neon.uqadd" {{%.*}}, {{%.*}} :
353+
// CIR-SAME: (!cir.vector<!u8i x 16>, !cir.vector<!u8i x 16>) -> !cir.vector<!u8i x 16>
354+
355+
// LLVM: {{.*}}test_vqaddq_u8(<16 x i8>{{.*}} [[A:%.*]], <16 x i8>{{.*}} [[B:%.*]])
356+
// LLVM: [[RES:%.*]] = call <16 x i8> @llvm.aarch64.neon.uqadd.v16i8(<16 x i8> [[A]], <16 x i8> [[B]])
357+
// LLVM: ret <16 x i8> [[RES]]
358+
359+
int16x8_t test_vqaddq_s16(int16x8_t a, int16x8_t b) {
360+
return vqaddq_s16(a, b);
361+
}
362+
363+
// CIR-LABEL: vqaddq_s16
364+
// CIR: {{%.*}} = cir.llvm.intrinsic "llvm.aarch64.neon.sqadd" {{%.*}}, {{%.*}} :
365+
// CIR-SAME: (!cir.vector<!s16i x 8>, !cir.vector<!s16i x 8>) -> !cir.vector<!s16i x 8>
366+
367+
// LLVM: {{.*}}test_vqaddq_s16(<8 x i16>{{.*}} [[A:%.*]], <8 x i16>{{.*}} [[B:%.*]])
368+
// LLVM: [[RES:%.*]] = call <8 x i16> @llvm.aarch64.neon.sqadd.v8i16(<8 x i16> [[A]], <8 x i16> [[B]])
369+
// LLVM: ret <8 x i16> [[RES]]
370+
371+
uint16x8_t test_vqaddq_u16(uint16x8_t a, uint16x8_t b) {
372+
return vqaddq_u16(a, b);
373+
}
374+
375+
// CIR-LABEL: vqaddq_u16
376+
// CIR: {{%.*}} = cir.llvm.intrinsic "llvm.aarch64.neon.uqadd" {{%.*}}, {{%.*}} :
377+
// CIR-SAME: (!cir.vector<!u16i x 8>, !cir.vector<!u16i x 8>) -> !cir.vector<!u16i x 8>
378+
379+
// LLVM: {{.*}}test_vqaddq_u16(<8 x i16>{{.*}} [[A:%.*]], <8 x i16>{{.*}} [[B:%.*]])
380+
// LLVM: [[RES:%.*]] = call <8 x i16> @llvm.aarch64.neon.uqadd.v8i16(<8 x i16> [[A]], <8 x i16> [[B]])
381+
// LLVM: ret <8 x i16> [[RES]]
382+
383+
int32x4_t test_vqaddq_s32(int32x4_t a, int32x4_t b) {
384+
return vqaddq_s32(a, b);
385+
}
386+
387+
// CIR-LABEL: vqaddq_s32
388+
// CIR: {{%.*}} = cir.llvm.intrinsic "llvm.aarch64.neon.sqadd" {{%.*}}, {{%.*}} :
389+
// CIR-SAME: (!cir.vector<!s32i x 4>, !cir.vector<!s32i x 4>) -> !cir.vector<!s32i x 4>
390+
391+
// LLVM: {{.*}}test_vqaddq_s32(<4 x i32>{{.*}} [[A:%.*]], <4 x i32>{{.*}} [[B:%.*]])
392+
// LLVM: [[RES:%.*]] = call <4 x i32> @llvm.aarch64.neon.sqadd.v4i32(<4 x i32> [[A]], <4 x i32> [[B]])
393+
// LLVM: ret <4 x i32> [[RES]]
394+
395+
int64x2_t test_vqaddq_s64(int64x2_t a, int64x2_t b) {
396+
return vqaddq_s64(a, b);
397+
}
398+
399+
// CIR-LABEL: vqaddq_s64
400+
// CIR: {{%.*}} = cir.llvm.intrinsic "llvm.aarch64.neon.sqadd" {{%.*}}, {{%.*}} :
401+
// CIR-SAME: (!cir.vector<!s64i x 2>, !cir.vector<!s64i x 2>) -> !cir.vector<!s64i x 2>
402+
403+
// LLVM: {{.*}}test_vqaddq_s64(<2 x i64>{{.*}} [[A:%.*]], <2 x i64>{{.*}} [[B:%.*]])
404+
// LLVM: [[RES:%.*]] = call <2 x i64> @llvm.aarch64.neon.sqadd.v2i64(<2 x i64> [[A]], <2 x i64> [[B]])
405+
// LLVM: ret <2 x i64> [[RES]]
406+
407+
uint64x2_t test_vqaddq_u64(uint64x2_t a, uint64x2_t b) {
408+
return vqaddq_u64(a, b);
409+
}
410+
411+
// CIR-LABEL: vqaddq_u64
412+
// CIR: {{%.*}} = cir.llvm.intrinsic "llvm.aarch64.neon.uqadd" {{%.*}}, {{%.*}} :
413+
// CIR-SAME: (!cir.vector<!u64i x 2>, !cir.vector<!u64i x 2>) -> !cir.vector<!u64i x 2>
414+
415+
// LLVM: {{.*}}test_vqaddq_u64(<2 x i64>{{.*}} [[A:%.*]], <2 x i64>{{.*}} [[B:%.*]])
416+
// LLVM: [[RES:%.*]] = call <2 x i64> @llvm.aarch64.neon.uqadd.v2i64(<2 x i64> [[A]], <2 x i64> [[B]])
417+
// LLVM: ret <2 x i64> [[RES]]
418+
419+
int8x8_t test_vqsub_s8(int8x8_t a, int8x8_t b) {
420+
return vqsub_s8(a, b);
421+
}
422+
423+
// CIR-LABEL: vqsub_s8
424+
// CIR: {{%.*}} = cir.llvm.intrinsic "llvm.aarch64.neon.sqsub" {{%.*}}, {{%.*}} :
425+
// CIR-SAME: (!cir.vector<!s8i x 8>, !cir.vector<!s8i x 8>) -> !cir.vector<!s8i x 8>
426+
427+
// LLVM: {{.*}}test_vqsub_s8(<8 x i8>{{.*}} [[A:%.*]], <8 x i8>{{.*}} [[B:%.*]])
428+
// LLVM: [[RES:%.*]] = call <8 x i8> @llvm.aarch64.neon.sqsub.v8i8(<8 x i8> [[A]], <8 x i8> [[B]])
429+
// LLVM: ret <8 x i8> [[RES]]
430+
431+
uint8x8_t test_vqsub_u8(uint8x8_t a, uint8x8_t b) {
432+
return vqsub_u8(a, b);
433+
}
434+
435+
// CIR-LABEL: vqsub_u8
436+
// CIR: {{%.*}} = cir.llvm.intrinsic "llvm.aarch64.neon.uqsub" {{%.*}}, {{%.*}} :
437+
// CIR-SAME: (!cir.vector<!u8i x 8>, !cir.vector<!u8i x 8>) -> !cir.vector<!u8i x 8>
438+
439+
// LLVM: {{.*}}test_vqsub_u8(<8 x i8>{{.*}} [[A:%.*]], <8 x i8>{{.*}} [[B:%.*]])
440+
// LLVM: [[RES:%.*]] = call <8 x i8> @llvm.aarch64.neon.uqsub.v8i8(<8 x i8> [[A]], <8 x i8> [[B]])
441+
// LLVM: ret <8 x i8> [[RES]]
442+
443+
int16x4_t test_vqsub_s16(int16x4_t a, int16x4_t b) {
444+
return vqsub_s16(a, b);
445+
}
446+
447+
// CIR-LABEL: vqsub_s16
448+
// CIR: {{%.*}} = cir.llvm.intrinsic "llvm.aarch64.neon.sqsub" {{%.*}}, {{%.*}} :
449+
// CIR-SAME: (!cir.vector<!s16i x 4>, !cir.vector<!s16i x 4>) -> !cir.vector<!s16i x 4>
450+
451+
// LLVM: {{.*}}test_vqsub_s16(<4 x i16>{{.*}} [[A:%.*]], <4 x i16>{{.*}} [[B:%.*]])
452+
// LLVM: [[RES:%.*]] = call <4 x i16> @llvm.aarch64.neon.sqsub.v4i16(<4 x i16> [[A]], <4 x i16> [[B]])
453+
// LLVM: ret <4 x i16> [[RES]]
454+
455+
uint16x4_t test_vqsub_u16(uint16x4_t a, uint16x4_t b) {
456+
return vqsub_u16(a, b);
457+
}
458+
459+
// CIR-LABEL: vqsub_u16
460+
// CIR: {{%.*}} = cir.llvm.intrinsic "llvm.aarch64.neon.uqsub" {{%.*}}, {{%.*}} :
461+
// CIR-SAME: (!cir.vector<!u16i x 4>, !cir.vector<!u16i x 4>) -> !cir.vector<!u16i x 4>
462+
463+
// LLVM: {{.*}}test_vqsub_u16(<4 x i16>{{.*}} [[A:%.*]], <4 x i16>{{.*}} [[B:%.*]])
464+
// LLVM: [[RES:%.*]] = call <4 x i16> @llvm.aarch64.neon.uqsub.v4i16(<4 x i16> [[A]], <4 x i16> [[B]])
465+
// LLVM: ret <4 x i16> [[RES]]
466+
467+
int32x2_t test_vqsub_s32(int32x2_t a, int32x2_t b) {
468+
return vqsub_s32(a, b);
469+
}
470+
471+
// CIR-LABEL: vqsub_s32
472+
// CIR: {{%.*}} = cir.llvm.intrinsic "llvm.aarch64.neon.sqsub" {{%.*}}, {{%.*}} :
473+
// CIR-SAME: (!cir.vector<!s32i x 2>, !cir.vector<!s32i x 2>) -> !cir.vector<!s32i x 2>
474+
475+
// LLVM: {{.*}}test_vqsub_s32(<2 x i32>{{.*}} [[A:%.*]], <2 x i32>{{.*}} [[B:%.*]])
476+
// LLVM: [[RES:%.*]] = call <2 x i32> @llvm.aarch64.neon.sqsub.v2i32(<2 x i32> [[A]], <2 x i32> [[B]])
477+
// LLVM: ret <2 x i32> [[RES]]
478+
479+
uint32x2_t test_vqsub_u32(uint32x2_t a, uint32x2_t b) {
480+
return vqsub_u32(a, b);
481+
}
482+
483+
// CIR-LABEL: vqsub_u32
484+
// CIR: {{%.*}} = cir.llvm.intrinsic "llvm.aarch64.neon.uqsub" {{%.*}}, {{%.*}} :
485+
// CIR-SAME: (!cir.vector<!u32i x 2>, !cir.vector<!u32i x 2>) -> !cir.vector<!u32i x 2>
486+
487+
// LLVM: {{.*}}test_vqsub_u32(<2 x i32>{{.*}} [[A:%.*]], <2 x i32>{{.*}} [[B:%.*]])
488+
// LLVM: [[RES:%.*]] = call <2 x i32> @llvm.aarch64.neon.uqsub.v2i32(<2 x i32> [[A]], <2 x i32> [[B]])
489+
// LLVM: ret <2 x i32> [[RES]]
490+
491+
int64x1_t test_vqsub_s64(int64x1_t a, int64x1_t b) {
492+
return vqsub_s64(a, b);
493+
}
494+
495+
// CIR-LABEL: vqsub_s64
496+
// CIR: {{%.*}} = cir.llvm.intrinsic "llvm.aarch64.neon.sqsub" {{%.*}}, {{%.*}} :
497+
// CIR-SAME: (!cir.vector<!s64i x 1>, !cir.vector<!s64i x 1>) -> !cir.vector<!s64i x 1>
498+
499+
// LLVM: {{.*}}test_vqsub_s64(<1 x i64>{{.*}} [[A:%.*]], <1 x i64>{{.*}} [[B:%.*]])
500+
// LLVM: [[RES:%.*]] = call <1 x i64> @llvm.aarch64.neon.sqsub.v1i64(<1 x i64> [[A]], <1 x i64> [[B]])
501+
// LLVM: ret <1 x i64> [[RES]]
502+
503+
uint64x1_t test_vqsub_u64(uint64x1_t a, uint64x1_t b) {
504+
return vqsub_u64(a, b);
505+
}
506+
507+
// CIR-LABEL: vqsub_u64
508+
// CIR: {{%.*}} = cir.llvm.intrinsic "llvm.aarch64.neon.uqsub" {{%.*}}, {{%.*}} :
509+
// CIR-SAME: (!cir.vector<!u64i x 1>, !cir.vector<!u64i x 1>) -> !cir.vector<!u64i x 1>
510+
511+
// LLVM: {{.*}}test_vqsub_u64(<1 x i64>{{.*}} [[A:%.*]], <1 x i64>{{.*}} [[B:%.*]])
512+
// LLVM: [[RES:%.*]] = call <1 x i64> @llvm.aarch64.neon.uqsub.v1i64(<1 x i64> [[A]], <1 x i64> [[B]])
513+
// LLVM: ret <1 x i64> [[RES]]
514+
515+
int8x16_t test_vqsubq_s8(int8x16_t a, int8x16_t b) {
516+
return vqsubq_s8(a, b);
517+
}
518+
519+
// CIR-LABEL: vqsubq_s8
520+
// CIR: {{%.*}} = cir.llvm.intrinsic "llvm.aarch64.neon.sqsub" {{%.*}}, {{%.*}} :
521+
// CIR-SAME: (!cir.vector<!s8i x 16>, !cir.vector<!s8i x 16>) -> !cir.vector<!s8i x 16>
522+
523+
// LLVM: {{.*}}test_vqsubq_s8(<16 x i8>{{.*}} [[A:%.*]], <16 x i8>{{.*}} [[B:%.*]])
524+
// LLVM: [[RES:%.*]] = call <16 x i8> @llvm.aarch64.neon.sqsub.v16i8(<16 x i8> [[A]], <16 x i8> [[B]])
525+
// LLVM: ret <16 x i8> [[RES]]
526+
527+
uint8x16_t test_vqsubq_u8(uint8x16_t a, uint8x16_t b) {
528+
return vqsubq_u8(a, b);
529+
}
530+
531+
// CIR-LABEL: vqsubq_u8
532+
// CIR: {{%.*}} = cir.llvm.intrinsic "llvm.aarch64.neon.uqsub" {{%.*}}, {{%.*}} :
533+
// CIR-SAME: (!cir.vector<!u8i x 16>, !cir.vector<!u8i x 16>) -> !cir.vector<!u8i x 16>
534+
535+
// LLVM: {{.*}}test_vqsubq_u8(<16 x i8>{{.*}} [[A:%.*]], <16 x i8>{{.*}} [[B:%.*]])
536+
// LLVM: [[RES:%.*]] = call <16 x i8> @llvm.aarch64.neon.uqsub.v16i8(<16 x i8> [[A]], <16 x i8> [[B]])
537+
// LLVM: ret <16 x i8> [[RES]]
538+
539+
int16x8_t test_vqsubq_s16(int16x8_t a, int16x8_t b) {
540+
return vqsubq_s16(a, b);
541+
}
542+
543+
// CIR-LABEL: vqsubq_s16
544+
// CIR: {{%.*}} = cir.llvm.intrinsic "llvm.aarch64.neon.sqsub" {{%.*}}, {{%.*}} :
545+
// CIR-SAME: (!cir.vector<!s16i x 8>, !cir.vector<!s16i x 8>) -> !cir.vector<!s16i x 8>
546+
547+
// LLVM: {{.*}}test_vqsubq_s16(<8 x i16>{{.*}} [[A:%.*]], <8 x i16>{{.*}} [[B:%.*]])
548+
// LLVM: [[RES:%.*]] = call <8 x i16> @llvm.aarch64.neon.sqsub.v8i16(<8 x i16> [[A]], <8 x i16> [[B]])
549+
// LLVM: ret <8 x i16> [[RES]]
550+
551+
uint16x8_t test_vqsubq_u16(uint16x8_t a, uint16x8_t b) {
552+
return vqsubq_u16(a, b);
553+
}
554+
555+
// CIR-LABEL: vqsubq_u16
556+
// CIR: {{%.*}} = cir.llvm.intrinsic "llvm.aarch64.neon.uqsub" {{%.*}}, {{%.*}} :
557+
// CIR-SAME: (!cir.vector<!u16i x 8>, !cir.vector<!u16i x 8>) -> !cir.vector<!u16i x 8>
558+
559+
// LLVM: {{.*}}test_vqsubq_u16(<8 x i16>{{.*}} [[A:%.*]], <8 x i16>{{.*}} [[B:%.*]])
560+
// LLVM: [[RES:%.*]] = call <8 x i16> @llvm.aarch64.neon.uqsub.v8i16(<8 x i16> [[A]], <8 x i16> [[B]])
561+
// LLVM: ret <8 x i16> [[RES]]
562+
563+
int32x4_t test_vqsubq_s32(int32x4_t a, int32x4_t b) {
564+
return vqsubq_s32(a, b);
565+
}
566+
567+
// CIR-LABEL: vqsubq_s32
568+
// CIR: {{%.*}} = cir.llvm.intrinsic "llvm.aarch64.neon.sqsub" {{%.*}}, {{%.*}} :
569+
// CIR-SAME: (!cir.vector<!s32i x 4>, !cir.vector<!s32i x 4>) -> !cir.vector<!s32i x 4>
570+
571+
// LLVM: {{.*}}test_vqsubq_s32(<4 x i32>{{.*}} [[A:%.*]], <4 x i32>{{.*}} [[B:%.*]])
572+
// LLVM: [[RES:%.*]] = call <4 x i32> @llvm.aarch64.neon.sqsub.v4i32(<4 x i32> [[A]], <4 x i32> [[B]])
573+
// LLVM: ret <4 x i32> [[RES]]
574+
575+
uint32x4_t test_vqsubq_u32(uint32x4_t a, uint32x4_t b) {
576+
return vqsubq_u32(a, b);
577+
}
578+
579+
// CIR-LABEL: vqsubq_u32
580+
// CIR: {{%.*}} = cir.llvm.intrinsic "llvm.aarch64.neon.uqsub" {{%.*}}, {{%.*}} :
581+
// CIR-SAME: (!cir.vector<!u32i x 4>, !cir.vector<!u32i x 4>) -> !cir.vector<!u32i x 4>
582+
583+
// LLVM: {{.*}}test_vqsubq_u32(<4 x i32>{{.*}} [[A:%.*]], <4 x i32>{{.*}} [[B:%.*]])
584+
// LLVM: [[RES:%.*]] = call <4 x i32> @llvm.aarch64.neon.uqsub.v4i32(<4 x i32> [[A]], <4 x i32> [[B]])
585+
// LLVM: ret <4 x i32> [[RES]]
586+
587+
int64x2_t test_vqsubq_s64(int64x2_t a, int64x2_t b) {
588+
return vqsubq_s64(a, b);
589+
}
590+
591+
// CIR-LABEL: vqsubq_s64
592+
// CIR: {{%.*}} = cir.llvm.intrinsic "llvm.aarch64.neon.sqsub" {{%.*}}, {{%.*}} :
593+
// CIR-SAME: (!cir.vector<!s64i x 2>, !cir.vector<!s64i x 2>) -> !cir.vector<!s64i x 2>
594+
595+
// LLVM: {{.*}}test_vqsubq_s64(<2 x i64>{{.*}} [[A:%.*]], <2 x i64>{{.*}} [[B:%.*]])
596+
// LLVM: [[RES:%.*]] = call <2 x i64> @llvm.aarch64.neon.sqsub.v2i64(<2 x i64> [[A]], <2 x i64> [[B]])
597+
// LLVM: ret <2 x i64> [[RES]]
598+
599+
uint64x2_t test_vqsubq_u64(uint64x2_t a, uint64x2_t b) {
600+
return vqsubq_u64(a, b);
601+
}
602+
603+
// CIR-LABEL: vqsubq_u64
604+
// CIR: {{%.*}} = cir.llvm.intrinsic "llvm.aarch64.neon.uqsub" {{%.*}}, {{%.*}} :
605+
// CIR-SAME: (!cir.vector<!u64i x 2>, !cir.vector<!u64i x 2>) -> !cir.vector<!u64i x 2>
606+
607+
// LLVM: {{.*}}test_vqsubq_u64(<2 x i64>{{.*}} [[A:%.*]], <2 x i64>{{.*}} [[B:%.*]])
608+
// LLVM: [[RES:%.*]] = call <2 x i64> @llvm.aarch64.neon.uqsub.v2i64(<2 x i64> [[A]], <2 x i64> [[B]])
609+
// LLVM: ret <2 x i64> [[RES]]

0 commit comments

Comments
 (0)