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

Reply via email to