Author: Andrzej WarzyĆski Date: 2026-09-02T09:20:06+01:00 New Revision: 8efad88ca8cb5d8f27ba683492cd6d2cf2754e4e
URL: https://github.com/llvm/llvm-project/commit/8efad88ca8cb5d8f27ba683492cd6d2cf2754e4e DIFF: https://github.com/llvm/llvm-project/commit/8efad88ca8cb5d8f27ba683492cd6d2cf2754e4e.diff LOG: [clang][CIR][AArch64] Add lowering for SISD variants of rounding intrinsics (#219241) This PR adds lowering for the remaining SISD "Vector saturating rounding shift right and narrow " intrinsic: * https://arm-software.github.io/acle/neon_intrinsics/advsimd.html#vector-saturating-rounding-shift-right-and-narrow The following builtins are added: * __builtin_neon_vqrshrns_n_s32: * __builtin_neon_vqrshrns_n_u32: * __builtin_neon_vqrshrnh_n_s16: * __builtin_neon_vqrshrnh_n_u16: * __builtin_neon_vqrshruns_n_s32: * __builtin_neon_vqrshrunh_n_s16: The corresponding tests are moved from: * clang/test/CodeGen/AArch64/ to: * clang/test/CodeGen/AArch64/neon/ The lowering follows the existing implementation in CodeGen/TargetBuiltins/ARM.cpp. Added: Modified: clang/include/clang/Basic/AArch64CodeGenUtils.h clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp clang/test/CodeGen/AArch64/neon-intrinsics.c clang/test/CodeGen/AArch64/neon/intrinsics.c Removed: ################################################################################ diff --git a/clang/include/clang/Basic/AArch64CodeGenUtils.h b/clang/include/clang/Basic/AArch64CodeGenUtils.h index 90f0b35fb1a98..72b162ec45909 100644 --- a/clang/include/clang/Basic/AArch64CodeGenUtils.h +++ b/clang/include/clang/Basic/AArch64CodeGenUtils.h @@ -585,13 +585,13 @@ const inline ARMNeonVectorIntrinsicInfo AArch64SISDIntrinsicMap[] = { NEONMAP1(vqrshls_u32, aarch64_neon_uqrshl, Add1ArgType), NEONMAP1(vqrshrnd_n_s64, aarch64_neon_sqrshrn, AddRetType), NEONMAP1(vqrshrnd_n_u64, aarch64_neon_uqrshrn, AddRetType), - NEONMAP1(vqrshrnh_n_s16, aarch64_neon_sqrshrn, VectorRet | Use64BitVectors), - NEONMAP1(vqrshrnh_n_u16, aarch64_neon_uqrshrn, VectorRet | Use64BitVectors), - NEONMAP1(vqrshrns_n_s32, aarch64_neon_sqrshrn, VectorRet | Use64BitVectors), - NEONMAP1(vqrshrns_n_u32, aarch64_neon_uqrshrn, VectorRet | Use64BitVectors), + NEONMAP1(vqrshrnh_n_s16, aarch64_neon_sqrshrn, VectorRet | Use64BitVectors | ArgAsWidenedRetType), + NEONMAP1(vqrshrnh_n_u16, aarch64_neon_uqrshrn, VectorRet | Use64BitVectors | ArgAsWidenedRetType), + NEONMAP1(vqrshrns_n_s32, aarch64_neon_sqrshrn, VectorRet | Use64BitVectors | ArgAsWidenedRetType), + NEONMAP1(vqrshrns_n_u32, aarch64_neon_uqrshrn, VectorRet | Use64BitVectors | ArgAsWidenedRetType), NEONMAP1(vqrshrund_n_s64, aarch64_neon_sqrshrun, AddRetType), - NEONMAP1(vqrshrunh_n_s16, aarch64_neon_sqrshrun, VectorRet | Use64BitVectors), - NEONMAP1(vqrshruns_n_s32, aarch64_neon_sqrshrun, VectorRet | Use64BitVectors), + NEONMAP1(vqrshrunh_n_s16, aarch64_neon_sqrshrun, VectorRet | Use64BitVectors | ArgAsWidenedRetType), + NEONMAP1(vqrshruns_n_s32, aarch64_neon_sqrshrun, VectorRet | Use64BitVectors | ArgAsWidenedRetType), NEONMAP1(vqshlb_n_s8, aarch64_neon_sqshl, Vectorize1ArgType | Use64BitVectors), NEONMAP1(vqshlb_n_u8, aarch64_neon_uqshl, Vectorize1ArgType | Use64BitVectors), NEONMAP1(vqshlb_s8, aarch64_neon_sqshl, Vectorize1ArgType | Use64BitVectors), diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp index a8f44917f480d..da23769632a78 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp @@ -573,6 +573,12 @@ emitCommonNeonSISDBuiltinExpr(CIRGenFunction &cgf, case NEON::BI__builtin_neon_vuqaddh_s16: case NEON::BI__builtin_neon_vuqadds_s32: case NEON::BI__builtin_neon_vuqaddd_s64: + case NEON::BI__builtin_neon_vqrshrns_n_s32: + case NEON::BI__builtin_neon_vqrshrns_n_u32: + case NEON::BI__builtin_neon_vqrshrnh_n_s16: + case NEON::BI__builtin_neon_vqrshrnh_n_u16: + case NEON::BI__builtin_neon_vqrshruns_n_s32: + case NEON::BI__builtin_neon_vqrshrunh_n_s16: break; } diff --git a/clang/test/CodeGen/AArch64/neon-intrinsics.c b/clang/test/CodeGen/AArch64/neon-intrinsics.c index 48acff35814ad..7a945abca9a80 100644 --- a/clang/test/CodeGen/AArch64/neon-intrinsics.c +++ b/clang/test/CodeGen/AArch64/neon-intrinsics.c @@ -7645,77 +7645,7 @@ uint64x1_t test_vqshlu_n_s64(int64x1_t a) { return vqshlu_n_s64(a, 1); } -// CHECK-LABEL: define dso_local i8 @test_vqrshrnh_n_s16( -// CHECK-SAME: i16 noundef [[A:%.*]]) #[[ATTR0]] { -// CHECK-NEXT: [[ENTRY:.*:]] -// CHECK-NEXT: [[TMP0:%.*]] = insertelement <8 x i16> poison, i16 [[A]], i64 0 -// CHECK-NEXT: [[VQRSHRNH_N_S16:%.*]] = call <8 x i8> @llvm.aarch64.neon.sqrshrn.v8i8(<8 x i16> [[TMP0]], i32 8) -// CHECK-NEXT: [[TMP1:%.*]] = extractelement <8 x i8> [[VQRSHRNH_N_S16]], i64 0 -// CHECK-NEXT: ret i8 [[TMP1]] -// -int8_t test_vqrshrnh_n_s16(int16_t a) { - return (int8_t)vqrshrnh_n_s16(a, 8); -} - -// CHECK-LABEL: define dso_local i16 @test_vqrshrns_n_s32( -// CHECK-SAME: i32 noundef [[A:%.*]]) #[[ATTR0]] { -// CHECK-NEXT: [[ENTRY:.*:]] -// CHECK-NEXT: [[TMP0:%.*]] = insertelement <4 x i32> poison, i32 [[A]], i64 0 -// CHECK-NEXT: [[VQRSHRNS_N_S32:%.*]] = call <4 x i16> @llvm.aarch64.neon.sqrshrn.v4i16(<4 x i32> [[TMP0]], i32 16) -// CHECK-NEXT: [[TMP1:%.*]] = extractelement <4 x i16> [[VQRSHRNS_N_S32]], i64 0 -// CHECK-NEXT: ret i16 [[TMP1]] -// -int16_t test_vqrshrns_n_s32(int32_t a) { - return (int16_t)vqrshrns_n_s32(a, 16); -} - -// CHECK-LABEL: define dso_local i8 @test_vqrshrnh_n_u16( -// CHECK-SAME: i16 noundef [[A:%.*]]) #[[ATTR0]] { -// CHECK-NEXT: [[ENTRY:.*:]] -// CHECK-NEXT: [[TMP0:%.*]] = insertelement <8 x i16> poison, i16 [[A]], i64 0 -// CHECK-NEXT: [[VQRSHRNH_N_U16:%.*]] = call <8 x i8> @llvm.aarch64.neon.uqrshrn.v8i8(<8 x i16> [[TMP0]], i32 8) -// CHECK-NEXT: [[TMP1:%.*]] = extractelement <8 x i8> [[VQRSHRNH_N_U16]], i64 0 -// CHECK-NEXT: ret i8 [[TMP1]] -// -uint8_t test_vqrshrnh_n_u16(uint16_t a) { - return (uint8_t)vqrshrnh_n_u16(a, 8); -} -// CHECK-LABEL: define dso_local i16 @test_vqrshrns_n_u32( -// CHECK-SAME: i32 noundef [[A:%.*]]) #[[ATTR0]] { -// CHECK-NEXT: [[ENTRY:.*:]] -// CHECK-NEXT: [[TMP0:%.*]] = insertelement <4 x i32> poison, i32 [[A]], i64 0 -// CHECK-NEXT: [[VQRSHRNS_N_U32:%.*]] = call <4 x i16> @llvm.aarch64.neon.uqrshrn.v4i16(<4 x i32> [[TMP0]], i32 16) -// CHECK-NEXT: [[TMP1:%.*]] = extractelement <4 x i16> [[VQRSHRNS_N_U32]], i64 0 -// CHECK-NEXT: ret i16 [[TMP1]] -// -uint16_t test_vqrshrns_n_u32(uint32_t a) { - return (uint16_t)vqrshrns_n_u32(a, 16); -} - -// CHECK-LABEL: define dso_local i8 @test_vqrshrunh_n_s16( -// CHECK-SAME: i16 noundef [[A:%.*]]) #[[ATTR0]] { -// CHECK-NEXT: [[ENTRY:.*:]] -// CHECK-NEXT: [[TMP0:%.*]] = insertelement <8 x i16> poison, i16 [[A]], i64 0 -// CHECK-NEXT: [[VQRSHRUNH_N_S16:%.*]] = call <8 x i8> @llvm.aarch64.neon.sqrshrun.v8i8(<8 x i16> [[TMP0]], i32 8) -// CHECK-NEXT: [[TMP1:%.*]] = extractelement <8 x i8> [[VQRSHRUNH_N_S16]], i64 0 -// CHECK-NEXT: ret i8 [[TMP1]] -// -uint8_t test_vqrshrunh_n_s16(int16_t a) { - return (uint8_t)vqrshrunh_n_s16(a, 8); -} - -// CHECK-LABEL: define dso_local i16 @test_vqrshruns_n_s32( -// CHECK-SAME: i32 noundef [[A:%.*]]) #[[ATTR0]] { -// CHECK-NEXT: [[ENTRY:.*:]] -// CHECK-NEXT: [[TMP0:%.*]] = insertelement <4 x i32> poison, i32 [[A]], i64 0 -// CHECK-NEXT: [[VQRSHRUNS_N_S32:%.*]] = call <4 x i16> @llvm.aarch64.neon.sqrshrun.v4i16(<4 x i32> [[TMP0]], i32 16) -// CHECK-NEXT: [[TMP1:%.*]] = extractelement <4 x i16> [[VQRSHRUNS_N_S32]], i64 0 -// CHECK-NEXT: ret i16 [[TMP1]] -// -uint16_t test_vqrshruns_n_s32(int32_t a) { - return (uint16_t)vqrshruns_n_s32(a, 16); -} // CHECK-LABEL: define dso_local <8 x i8> @test_vreinterpret_s8_s16( // CHECK-SAME: <4 x i16> noundef [[A:%.*]]) #[[ATTR0]] { diff --git a/clang/test/CodeGen/AArch64/neon/intrinsics.c b/clang/test/CodeGen/AArch64/neon/intrinsics.c index 2eeb33d5d99cb..d6da96f368fcc 100644 --- a/clang/test/CodeGen/AArch64/neon/intrinsics.c +++ b/clang/test/CodeGen/AArch64/neon/intrinsics.c @@ -61,9 +61,81 @@ float64_t test_vmaxnmvq_f64(float64x2_t a) { //===------------------------------------------------------===// // 2.1.3.2.7 Vector saturating rounding shift right and narrow -// TODO: Implement SISD variants +// https://arm-software.github.io/acle/neon_intrinsics/advsimd.html#vector-saturating-rounding-shift-right-and-narrow //===------------------------------------------------------===// +// LLVM-LABEL: define dso_local i8 @test_vqrshrunh_n_s16( +uint8_t test_vqrshrunh_n_s16(int16_t a) { + // CIR: {{%.*}} = cir.call_llvm_intrinsic "aarch64.neon.sqrshrun" + + // LLVM-SAME: i16 {{.*}} [[A:%.*]]) + // LLVM: [[TMP0:%.*]] = insertelement <8 x i16> poison, i16 [[A]], i64 0 + // LLVM: [[VQRSHRUNH_N_S16:%.*]] = call <8 x i8> @llvm.aarch64.neon.sqrshrun.v8i8(<8 x i16> [[TMP0]], i32 8) + // LLVM: [[TMP1:%.*]] = extractelement <8 x i8> [[VQRSHRUNH_N_S16]], i64 0 + // LLVM: ret i8 [[TMP1]] + return (uint8_t)vqrshrunh_n_s16(a, 8); +} + +// LLVM-LABEL: define dso_local i16 @test_vqrshruns_n_s32( +uint16_t test_vqrshruns_n_s32(int32_t a) { + // CIR: {{%.*}} = cir.call_llvm_intrinsic "aarch64.neon.sqrshrun" + + // LLVM-SAME: i32 {{.*}} [[A:%.*]]) + // LLVM: [[TMP0:%.*]] = insertelement <4 x i32> poison, i32 [[A]], i64 0 + // LLVM: [[VQRSHRUNS_N_S32:%.*]] = call <4 x i16> @llvm.aarch64.neon.sqrshrun.v4i16(<4 x i32> [[TMP0]], i32 16) + // LLVM: [[TMP1:%.*]] = extractelement <4 x i16> [[VQRSHRUNS_N_S32]], i64 0 + // LLVM: ret i16 [[TMP1]] + return (uint16_t)vqrshruns_n_s32(a, 16); +} + +// LLVM-LABEL: define dso_local i8 @test_vqrshrnh_n_s16( +int8_t test_vqrshrnh_n_s16(int16_t a) { + // CIR: {{%.*}} = cir.call_llvm_intrinsic "aarch64.neon.sqrshrn" + + // LLVM-SAME: i16 {{.*}} [[A:%.*]]) + // LLVM: [[TMP0:%.*]] = insertelement <8 x i16> poison, i16 [[A]], i64 0 + // LLVM: [[VQRSHRNH_N_S16:%.*]] = call <8 x i8> @llvm.aarch64.neon.sqrshrn.v8i8(<8 x i16> [[TMP0]], i32 8) + // LLVM: [[TMP1:%.*]] = extractelement <8 x i8> [[VQRSHRNH_N_S16]], i64 0 + // LLVM: ret i8 [[TMP1]] + return (int8_t)vqrshrnh_n_s16(a, 8); +} + +// LLVM-LABEL: define dso_local i16 @test_vqrshrns_n_s32( +int16_t test_vqrshrns_n_s32(int32_t a) { + // CIR: {{%.*}} = cir.call_llvm_intrinsic "aarch64.neon.sqrshrn" + + // LLVM-SAME: i32 {{.*}} [[A:%.*]]) + // LLVM: [[TMP0:%.*]] = insertelement <4 x i32> poison, i32 [[A]], i64 0 + // LLVM: [[VQRSHRNS_N_S32:%.*]] = call <4 x i16> @llvm.aarch64.neon.sqrshrn.v4i16(<4 x i32> [[TMP0]], i32 16) + // LLVM: [[TMP1:%.*]] = extractelement <4 x i16> [[VQRSHRNS_N_S32]], i64 0 + // LLVM: ret i16 [[TMP1]] + return (int16_t)vqrshrns_n_s32(a, 16); +} + +// LLVM-LABEL: define dso_local i8 @test_vqrshrnh_n_u16( +uint8_t test_vqrshrnh_n_u16(uint16_t a) { + // CIR: {{%.*}} = cir.call_llvm_intrinsic "aarch64.neon.uqrshrn" + + // LLVM-SAME: i16 {{.*}} [[A:%.*]]) + // LLVM: [[TMP0:%.*]] = insertelement <8 x i16> poison, i16 [[A]], i64 0 + // LLVM: [[VQRSHRNH_N_U16:%.*]] = call <8 x i8> @llvm.aarch64.neon.uqrshrn.v8i8(<8 x i16> [[TMP0]], i32 8) + // LLVM: [[TMP1:%.*]] = extractelement <8 x i8> [[VQRSHRNH_N_U16]], i64 0 + // LLVM: ret i8 [[TMP1]] + return (uint8_t)vqrshrnh_n_u16(a, 8); +} + +// LLVM-LABEL: define dso_local i16 @test_vqrshrns_n_u32( +uint16_t test_vqrshrns_n_u32(uint32_t a) { + // CIR: {{%.*}} = cir.call_llvm_intrinsic "aarch64.neon.uqrshrn" + + // LLVM-SAME: i32 {{.*}} [[A:%.*]]) + // LLVM: [[TMP0:%.*]] = insertelement <4 x i32> poison, i32 [[A]], i64 0 + // LLVM: [[VQRSHRNS_N_U32:%.*]] = call <4 x i16> @llvm.aarch64.neon.uqrshrn.v4i16(<4 x i32> [[TMP0]], i32 16) + // LLVM: [[TMP1:%.*]] = extractelement <4 x i16> [[VQRSHRNS_N_U32]], i64 0 + // LLVM: ret i16 [[TMP1]] + return (uint16_t)vqrshrns_n_u32(a, 16); +} + // ALL-LABEL: @test_vqrshrun_n_s16( uint8x8_t test_vqrshrun_n_s16(int16x8_t a) { // CIR: cir.call_llvm_intrinsic "aarch64.neon.sqrshrun" _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
