Author: Andrzej WarzyĆski Date: 2026-07-14T10:10:26Z New Revision: b3f5986138f2f6a65072b6822892afa5d8859cf7
URL: https://github.com/llvm/llvm-project/commit/b3f5986138f2f6a65072b6822892afa5d8859cf7 DIFF: https://github.com/llvm/llvm-project/commit/b3f5986138f2f6a65072b6822892afa5d8859cf7.diff LOG: [clang][CIR][AArch64] Add lowering for conversion intrinsics (#209252) This PR adds lowering for intrinsic from the following groups: * https://arm-software.github.io/acle/neon_intrinsics/advsimd.html#conversions It continues the work started in #190961, #193273 and #199990. This PR implements the remaining conversions truncating to zero: * vcvtd_s32_f64 * vcvtd_s64_f64 * vcvtd_u32_f64 * vcvtd_u64_f64 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/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp clang/test/CodeGen/AArch64/neon-fcvt-intrinsics.c clang/test/CodeGen/AArch64/neon/intrinsics.c Removed: ################################################################################ diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp index 1f488dfa9383a..9a50acece4d2c 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp @@ -354,8 +354,17 @@ static mlir::Value emitCommonNeonSISDBuiltinExpr( break; } - llvm::StringRef llvmIntrName = getLLVMIntrNameNoPrefix( - static_cast<llvm::Intrinsic::ID>(info.LLVMIntrinsic)); + unsigned intr = info.LLVMIntrinsic; + + // Use fptosi.sat/fptoui.sat unless under strict FP. + assert(!cir::MissingFeatures::emitConstrainedFPCall()); + if (intr == Intrinsic::aarch64_neon_fcvtzs) + intr = Intrinsic::fptosi_sat; + else if (intr == Intrinsic::aarch64_neon_fcvtzu) + intr = Intrinsic::fptoui_sat; + + llvm::StringRef llvmIntrName = + getLLVMIntrNameNoPrefix(static_cast<llvm::Intrinsic::ID>(intr)); mlir::Location loc = cgf.getLoc(expr->getExprLoc()); // The switch stmt is intended to help catch NYI cases and will be removed @@ -393,6 +402,10 @@ static mlir::Value emitCommonNeonSISDBuiltinExpr( case NEON::BI__builtin_neon_vpminqd_f64: case NEON::BI__builtin_neon_vpminnms_f32: case NEON::BI__builtin_neon_vpminnmqd_f64: + case NEON::BI__builtin_neon_vcvtd_s32_f64: + case NEON::BI__builtin_neon_vcvtd_s64_f64: + case NEON::BI__builtin_neon_vcvtd_u64_f64: + case NEON::BI__builtin_neon_vcvtd_u32_f64: case NEON::BI__builtin_neon_vcvts_n_f32_s32: case NEON::BI__builtin_neon_vcvts_n_f32_u32: case NEON::BI__builtin_neon_vcvts_n_s32_f32: diff --git a/clang/test/CodeGen/AArch64/neon-fcvt-intrinsics.c b/clang/test/CodeGen/AArch64/neon-fcvt-intrinsics.c index f14df46b89177..5a59f80cb0363 100644 --- a/clang/test/CodeGen/AArch64/neon-fcvt-intrinsics.c +++ b/clang/test/CodeGen/AArch64/neon-fcvt-intrinsics.c @@ -346,16 +346,6 @@ int32_t test_vcvts_s32_f32(float32_t a) { return (int32_t)vcvts_s32_f32(a); } -// CHECK-LABEL: define {{[^@]+}}@test_vcvtd_s64_f64 -// CHECK-SAME: (double noundef [[A:%.*]]) #[[ATTR0]] { -// CHECK-NEXT: entry: -// CHECK-NEXT: [[VCVTD_S64_F64_I:%.*]] = call i64 @llvm.fptosi.sat.i64.f64(double [[A]]) -// CHECK-NEXT: ret i64 [[VCVTD_S64_F64_I]] -// -int64_t test_vcvtd_s64_f64(float64_t a) { - return (int64_t)vcvtd_s64_f64(a); -} - // CHECK-LABEL: define {{[^@]+}}@test_vcvts_s64_f32 // CHECK-SAME: (float noundef [[A:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: @@ -366,16 +356,6 @@ int64_t test_vcvts_s64_f32(float32_t a) { return (int64_t)vcvts_s64_f32(a); } -// CHECK-LABEL: define {{[^@]+}}@test_vcvtd_s32_f64 -// CHECK-SAME: (double noundef [[A:%.*]]) #[[ATTR0]] { -// CHECK-NEXT: entry: -// CHECK-NEXT: [[VCVTD_S32_F64_I:%.*]] = call i32 @llvm.fptosi.sat.i32.f64(double [[A]]) -// CHECK-NEXT: ret i32 [[VCVTD_S32_F64_I]] -// -int32_t test_vcvtd_s32_f64(float64_t a) { - return (int32_t)vcvtd_s32_f64(a); -} - // CHECK-LABEL: define {{[^@]+}}@test_vcvts_u32_f32 // CHECK-SAME: (float noundef [[A:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: @@ -386,16 +366,6 @@ uint32_t test_vcvts_u32_f32(float32_t a) { return (uint32_t)vcvts_u32_f32(a); } -// CHECK-LABEL: define {{[^@]+}}@test_vcvtd_u64_f64 -// CHECK-SAME: (double noundef [[A:%.*]]) #[[ATTR0]] { -// CHECK-NEXT: entry: -// CHECK-NEXT: [[VCVTD_U64_F64_I:%.*]] = call i64 @llvm.fptoui.sat.i64.f64(double [[A]]) -// CHECK-NEXT: ret i64 [[VCVTD_U64_F64_I]] -// -uint64_t test_vcvtd_u64_f64(float64_t a) { - return (uint64_t)vcvtd_u64_f64(a); -} - // CHECK-LABEL: define {{[^@]+}}@test_vcvts_u64_f32 // CHECK-SAME: (float noundef [[A:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: @@ -406,13 +376,3 @@ uint64_t test_vcvts_u64_f32(float32_t a) { return (uint64_t)vcvts_u64_f32(a); } -// CHECK-LABEL: define {{[^@]+}}@test_vcvtd_u32_f64 -// CHECK-SAME: (double noundef [[A:%.*]]) #[[ATTR0]] { -// CHECK-NEXT: entry: -// CHECK-NEXT: [[VCVTD_U32_F64_I:%.*]] = call i32 @llvm.fptoui.sat.i32.f64(double [[A]]) -// CHECK-NEXT: ret i32 [[VCVTD_U32_F64_I]] -// -uint32_t test_vcvtd_u32_f64(float64_t a) { - return (uint32_t)vcvtd_u32_f64(a); -} - diff --git a/clang/test/CodeGen/AArch64/neon/intrinsics.c b/clang/test/CodeGen/AArch64/neon/intrinsics.c index eea4ace984870..0e15488aede6b 100644 --- a/clang/test/CodeGen/AArch64/neon/intrinsics.c +++ b/clang/test/CodeGen/AArch64/neon/intrinsics.c @@ -4590,6 +4590,50 @@ uint64x2_t test_vcvtq_u64_f64(float64x2_t a) { return vcvtq_u64_f64(a); } +// LLVM-LABEL: @test_vcvtd_s32_f64 +// CIR-LABEL: @vcvtd_s32_f64 +int32_t test_vcvtd_s32_f64(float64_t a) { +// CIR: cir.call_llvm_intrinsic "fptosi.sat + +// LLVM-SAME: double {{.*}} [[A:%.*]]) +// LLVM: [[VCVTD_S32_F64_I:%.*]] = call i32 @llvm.fptosi.sat.i32.f64(double [[A]]) +// LLVM-NEXT: ret i32 [[VCVTD_S32_F64_I]] + return (int32_t)vcvtd_s32_f64(a); +} + +// LLVM-LABEL: @test_vcvtd_s64_f64 +// CIR-LABEL: @vcvtd_s64_f64 +int64_t test_vcvtd_s64_f64(float64_t a) { +// CIR: cir.call_llvm_intrinsic "fptosi.sat + +// LLVM-SAME: double {{.*}} [[A:%.*]]) +// LLVM: [[VCVTD_S64_F64_I:%.*]] = call i64 @llvm.fptosi.sat.i64.f64(double [[A]]) +// LLVM-NEXT: ret i64 [[VCVTD_S64_F64_I]] + return (int64_t)vcvtd_s64_f64(a); +} + +// LLVM-LABEL: @test_vcvtd_u32_f64 +// CIR-LABEL: @vcvtd_u32_f64 +uint32_t test_vcvtd_u32_f64(float64_t a) { +// CIR: cir.call_llvm_intrinsic "fptoui.sat + +// LLVM-SAME: double {{.*}} [[A:%.*]]) +// LLVM: [[VCVTD_U32_F64_I:%.*]] = call i32 @llvm.fptoui.sat.i32.f64(double [[A]]) +// LLVM-NEXT: ret i32 [[VCVTD_U32_F64_I]] + return (uint32_t)vcvtd_u32_f64(a); +} + +// LLVM-LABEL: @test_vcvtd_u64_f64 +// CIR-LABEL: @vcvtd_u64_f64 +uint64_t test_vcvtd_u64_f64(float64_t a) { +// CIR: cir.call_llvm_intrinsic "fptoui.sat + +// LLVM-SAME: double {{.*}} [[A:%.*]]) +// LLVM: [[VCVTD_U64_F64_I:%.*]] = call i64 @llvm.fptoui.sat.i64.f64(double [[A]]) +// LLVM-NEXT: ret i64 [[VCVTD_U64_F64_I]] + return (uint64_t)vcvtd_u64_f64(a); +} + //===------------------------------------------------------===// // 2.1.3.2.3 Vector shift right and accumulate // https://arm-software.github.io/acle/neon_intrinsics/advsimd.html#vector-shift-right-and-accumulate @@ -7540,4 +7584,4 @@ float64x2_t test_vrndxq_f64(float64x2_t a) { // LLVM: [[VRNDX1_I:%.*]] = call <2 x double> @llvm.rint.v2f64(<2 x double> [[VRNDX_I]]) // LLVM: ret <2 x double> [[VRNDX1_I]] return vrndxq_f64(a); -} \ No newline at end of file +} _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
