[clang] b3f5986 - [clang][CIR][AArch64] Add lowering for conversion intrinsics (#209252)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Jul 14 03:10:31 PDT 2026
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
+}
More information about the cfe-commits
mailing list