https://github.com/banach-space updated 
https://github.com/llvm/llvm-project/pull/207511

From 41c0c74a7fbdb01ce43f92711874029063e7b2f9 Mon Sep 17 00:00:00 2001
From: Andrzej Warzynski <[email protected]>
Date: Sat, 4 Jul 2026 12:55:53 +0000
Subject: [PATCH] [CIR][AArc64] Add lowering for fp16 intrinsics (FP16 step +
 rounding)

This PR adds lowering for the following intrinsic groups:
  * 
https://arm-software.github.io/acle/neon_intrinsics/advsimd.html#markdown-toc-reciprocal-step
  * 
https://arm-software.github.io/acle/neon_intrinsics/advsimd.html#markdown-toc-rounding-1

It also moves the corresponding tests from:

* clang/test/CodeGen/AArch64/v8.2a-fp16-intrinsics.c

to:
* clang/test/CodeGen/AArch64/neon/fullfp16.c

The lowering follows the existing implementation in
CodeGen/TargetBuiltins/ARM.cpp.
---
 .../lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp  | 74 ++++++++++++++--
 clang/test/CodeGen/AArch64/neon/fullfp16.c    | 86 +++++++++++++++++++
 .../CodeGen/AArch64/v8.2a-fp16-intrinsics.c   | 55 ------------
 3 files changed, 151 insertions(+), 64 deletions(-)

diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp 
b/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp
index 8b077620d2bab..bb9647067859e 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp
@@ -649,7 +649,7 @@ static mlir::Value emitCommonNeonBuiltinExpr(
   // getTargetHooks().getABIInfo().allowBFloatArgsAndRet();
 
   cir::VectorType vTy = getNeonType(&cgf, neonType, loc, hasLegalHalfType,
-                                    false, allowBFloatArgsAndRet);
+                                    /*v1Ty=*/false, allowBFloatArgsAndRet);
   cir::VectorType ty = vTy;
   if (!ty)
     return nullptr;
@@ -2830,7 +2830,15 @@ CIRGenFunction::emitAArch64BuiltinExpr(unsigned 
builtinID, const CallExpr *expr,
   case NEON::BI__builtin_neon_vmaxnmh_f16:
   case NEON::BI__builtin_neon_vrecpss_f32:
   case NEON::BI__builtin_neon_vrecpsd_f64:
-  case NEON::BI__builtin_neon_vrecpsh_f16:
+    cgm.errorNYI(expr->getSourceRange(),
+                 std::string("unimplemented AArch64 builtin call: ") +
+                     getContext().BuiltinInfo.getName(builtinID));
+    return mlir::Value{};
+  case NEON::BI__builtin_neon_vrecpsh_f16: {
+    auto halfTy = builder.getFp16Ty();
+    return emitNeonCall(cgm, builder, {halfTy, halfTy}, ops,
+                        "aarch64.neon.frecps", halfTy, loc);
+  }
   case NEON::BI__builtin_neon_vqshrun_n_v:
     cgm.errorNYI(expr->getSourceRange(),
                  std::string("unimplemented AArch64 builtin call: ") +
@@ -2860,24 +2868,72 @@ CIRGenFunction::emitAArch64BuiltinExpr(unsigned 
builtinID, const CallExpr *expr,
     return emitNeonCall(cgm, builder, {argTy, sInt32Ty}, ops, intrName, ty,
                         loc);
   }
-  case NEON::BI__builtin_neon_vrndah_f16:
+  case NEON::BI__builtin_neon_vrndah_f16: {
+    assert(!cir::MissingFeatures::emitConstrainedFPCall());
+    auto halfTy = builder.getFp16Ty();
+    return emitNeonCall(cgm, builder, {halfTy}, ops, "round", halfTy, loc);
+  }
   case NEON::BI__builtin_neon_vrnda_v:
   case NEON::BI__builtin_neon_vrndaq_v:
-  case NEON::BI__builtin_neon_vrndih_f16:
-  case NEON::BI__builtin_neon_vrndmh_f16:
+    cgm.errorNYI(expr->getSourceRange(),
+                 std::string("unimplemented AArch64 builtin call: ") +
+                     getContext().BuiltinInfo.getName(builtinID));
+    return mlir::Value{};
+  case NEON::BI__builtin_neon_vrndih_f16: {
+    assert(!cir::MissingFeatures::emitConstrainedFPCall());
+    auto halfTy = builder.getFp16Ty();
+    return emitNeonCall(cgm, builder, {halfTy}, ops, "nearbyint", halfTy, loc);
+  }
+  case NEON::BI__builtin_neon_vrndmh_f16: {
+    assert(!cir::MissingFeatures::emitConstrainedFPCall());
+    auto halfTy = builder.getFp16Ty();
+    return emitNeonCall(cgm, builder, {halfTy}, ops, "floor", halfTy, loc);
+  }
   case NEON::BI__builtin_neon_vrndm_v:
   case NEON::BI__builtin_neon_vrndmq_v:
-  case NEON::BI__builtin_neon_vrndnh_f16:
+    cgm.errorNYI(expr->getSourceRange(),
+                 std::string("unimplemented AArch64 builtin call: ") +
+                     getContext().BuiltinInfo.getName(builtinID));
+    return mlir::Value{};
+  case NEON::BI__builtin_neon_vrndnh_f16: {
+    assert(!cir::MissingFeatures::emitConstrainedFPCall());
+    auto halfTy = builder.getFp16Ty();
+    return emitNeonCall(cgm, builder, {halfTy}, ops, "roundeven", halfTy, loc);
+  }
   case NEON::BI__builtin_neon_vrndn_v:
   case NEON::BI__builtin_neon_vrndnq_v:
   case NEON::BI__builtin_neon_vrndns_f32:
-  case NEON::BI__builtin_neon_vrndph_f16:
+    cgm.errorNYI(expr->getSourceRange(),
+                 std::string("unimplemented AArch64 builtin call: ") +
+                     getContext().BuiltinInfo.getName(builtinID));
+    return mlir::Value{};
+  case NEON::BI__builtin_neon_vrndph_f16: {
+    assert(!cir::MissingFeatures::emitConstrainedFPCall());
+    auto halfTy = builder.getFp16Ty();
+    return emitNeonCall(cgm, builder, {halfTy}, ops, "ceil", halfTy, loc);
+  }
   case NEON::BI__builtin_neon_vrndp_v:
   case NEON::BI__builtin_neon_vrndpq_v:
-  case NEON::BI__builtin_neon_vrndxh_f16:
+    cgm.errorNYI(expr->getSourceRange(),
+                 std::string("unimplemented AArch64 builtin call: ") +
+                     getContext().BuiltinInfo.getName(builtinID));
+    return mlir::Value{};
+  case NEON::BI__builtin_neon_vrndxh_f16: {
+    assert(!cir::MissingFeatures::emitConstrainedFPCall());
+    auto halfTy = builder.getFp16Ty();
+    return emitNeonCall(cgm, builder, {halfTy}, ops, "rint", halfTy, loc);
+  }
   case NEON::BI__builtin_neon_vrndx_v:
   case NEON::BI__builtin_neon_vrndxq_v:
-  case NEON::BI__builtin_neon_vrndh_f16:
+    cgm.errorNYI(expr->getSourceRange(),
+                 std::string("unimplemented AArch64 builtin call: ") +
+                     getContext().BuiltinInfo.getName(builtinID));
+    return mlir::Value{};
+  case NEON::BI__builtin_neon_vrndh_f16: {
+    assert(!cir::MissingFeatures::emitConstrainedFPCall());
+    auto halfTy = builder.getFp16Ty();
+    return emitNeonCall(cgm, builder, {halfTy}, ops, "trunc", halfTy, loc);
+  }
   case NEON::BI__builtin_neon_vrnd32x_f32:
   case NEON::BI__builtin_neon_vrnd32xq_f32:
   case NEON::BI__builtin_neon_vrnd32x_f64:
diff --git a/clang/test/CodeGen/AArch64/neon/fullfp16.c 
b/clang/test/CodeGen/AArch64/neon/fullfp16.c
index ba65f76e924c4..b9f6269ed836c 100644
--- a/clang/test/CodeGen/AArch64/neon/fullfp16.c
+++ b/clang/test/CodeGen/AArch64/neon/fullfp16.c
@@ -174,6 +174,92 @@ float16_t test_vrsqrtsh_f16(float16_t a, float16_t b) {
   return vrsqrtsh_f16(a, b);
 }
 
+//===------------------------------------------------------===//
+// 2.5.1.2.3.  Reciprocal step
+//===------------------------------------------------------===//
+// ALL-LABEL: test_vrecpsh_f16
+float16_t test_vrecpsh_f16(float16_t a, float16_t b) {
+// CIR: cir.call_llvm_intrinsic "aarch64.neon.frecps"
+
+// LLVM-SAME: half {{.*}} [[A:%.*]], half {{.*}} [[B:%.*]])
+// LLVM: [[RECPS:%.*]] = call half @llvm.aarch64.neon.frecps.f16(half [[A]], 
half [[B]])
+// LLVM: ret half [[RECPS]]
+  return vrecpsh_f16(a, b);
+}
+
+//===------------------------------------------------------===//
+// 2.5.1.3.  Rounding
+//===------------------------------------------------------===//
+// ALL-LABEL: test_vrndh_f16
+float16_t test_vrndh_f16(float16_t a) {
+// CIR: cir.call_llvm_intrinsic "trunc"
+
+// LLVM-SAME: half {{.*}} [[A:%.*]])
+// LLVM:  [[RND:%.*]] =  call half @llvm.trunc.f16(half [[A]])
+// LLVM:  ret half [[RND]]
+  return vrndh_f16(a);
+}
+
+// ALL-LABEL: test_vrndah_f16
+float16_t test_vrndah_f16(float16_t a) {
+// CIR: cir.call_llvm_intrinsic "round"
+
+// LLVM-SAME: half {{.*}} [[A:%.*]])
+// LLVM:  [[RND:%.*]] =  call half @llvm.round.f16(half [[A]])
+// LLVM:  ret half [[RND]]
+  return vrndah_f16(a);
+}
+
+// ALL-LABEL: test_vrndih_f16
+float16_t test_vrndih_f16(float16_t a) {
+// CIR: cir.call_llvm_intrinsic "nearbyint"
+
+// LLVM-SAME: half {{.*}} [[A:%.*]])
+// LLVM:  [[RND:%.*]] =  call half @llvm.nearbyint.f16(half [[A]])
+// LLVM:  ret half [[RND]]
+  return vrndih_f16(a);
+}
+
+// ALL-LABEL: test_vrndmh_f16
+float16_t test_vrndmh_f16(float16_t a) {
+// CIR: cir.call_llvm_intrinsic "floor"
+
+// LLVM-SAME: half {{.*}} [[A:%.*]])
+// LLVM:  [[RND:%.*]] =  call half @llvm.floor.f16(half [[A]])
+// LLVM:  ret half [[RND]]
+  return vrndmh_f16(a);
+}
+
+// ALL-LABEL: test_vrndnh_f16
+float16_t test_vrndnh_f16(float16_t a) {
+// CIR: cir.call_llvm_intrinsic "roundeven"
+
+// LLVM-SAME: half {{.*}} [[A:%.*]])
+// LLVM:  [[RND:%.*]] =  call half @llvm.roundeven.f16(half [[A]])
+// LLVM:  ret half [[RND]]
+  return vrndnh_f16(a);
+}
+
+// ALL-LABEL: test_vrndph_f16
+float16_t test_vrndph_f16(float16_t a) {
+// CIR: cir.call_llvm_intrinsic "ceil"
+
+// LLVM-SAME: half {{.*}} [[A:%.*]])
+// LLVM:  [[RND:%.*]] =  call half @llvm.ceil.f16(half [[A]])
+// LLVM:  ret half [[RND]]
+  return vrndph_f16(a);
+}
+
+// ALL-LABEL: test_vrndxh_f16
+float16_t test_vrndxh_f16(float16_t a) {
+// CIR: cir.call_llvm_intrinsic "rint"
+
+// LLVm-SAME: half {{.*}} [[A:%.*]])
+// LLVM:  [[RND:%.*]] =  call half @llvm.rint.f16(half [[A]])
+// LLVM:  ret half [[RND]]
+  return vrndxh_f16(a);
+}
+
 //===------------------------------------------------------===//
 // 2.5.4.1. Negate
 //===------------------------------------------------------===//
diff --git a/clang/test/CodeGen/AArch64/v8.2a-fp16-intrinsics.c 
b/clang/test/CodeGen/AArch64/v8.2a-fp16-intrinsics.c
index ed6246238bf8e..41021d7d21f7d 100644
--- a/clang/test/CodeGen/AArch64/v8.2a-fp16-intrinsics.c
+++ b/clang/test/CodeGen/AArch64/v8.2a-fp16-intrinsics.c
@@ -291,54 +291,6 @@ uint64_t test_vcvtph_u64_f16 (float16_t a) {
   return vcvtph_u64_f16(a);
 }
 
-// CHECK-LABEL: test_vrndh_f16
-// CHECK:  [[RND:%.*]] =  call half @llvm.trunc.f16(half %a)
-// CHECK:  ret half [[RND]]
-float16_t test_vrndh_f16(float16_t a) {
-  return vrndh_f16(a);
-}
-
-// CHECK-LABEL: test_vrndah_f16
-// CHECK:  [[RND:%.*]] =  call half @llvm.round.f16(half %a)
-// CHECK:  ret half [[RND]]
-float16_t test_vrndah_f16(float16_t a) {
-  return vrndah_f16(a);
-}
-
-// CHECK-LABEL: test_vrndih_f16
-// CHECK:  [[RND:%.*]] =  call half @llvm.nearbyint.f16(half %a)
-// CHECK:  ret half [[RND]]
-float16_t test_vrndih_f16(float16_t a) {
-  return vrndih_f16(a);
-}
-
-// CHECK-LABEL: test_vrndmh_f16
-// CHECK:  [[RND:%.*]] =  call half @llvm.floor.f16(half %a)
-// CHECK:  ret half [[RND]]
-float16_t test_vrndmh_f16(float16_t a) {
-  return vrndmh_f16(a);
-}
-
-// CHECK-LABEL: test_vrndnh_f16
-// CHECK:  [[RND:%.*]] =  call half @llvm.roundeven.f16(half %a)
-// CHECK:  ret half [[RND]]
-float16_t test_vrndnh_f16(float16_t a) {
-  return vrndnh_f16(a);
-}
-
-// CHECK-LABEL: test_vrndph_f16
-// CHECK:  [[RND:%.*]] =  call half @llvm.ceil.f16(half %a)
-// CHECK:  ret half [[RND]]
-float16_t test_vrndph_f16(float16_t a) {
-  return vrndph_f16(a);
-}
-
-// CHECK-LABEL: test_vrndxh_f16
-// CHECK:  [[RND:%.*]] =  call half @llvm.rint.f16(half %a)
-// CHECK:  ret half [[RND]]
-float16_t test_vrndxh_f16(float16_t a) {
-  return vrndxh_f16(a);
-}
 
 // CHECK-LABEL: test_vsqrth_f16
 // CHECK:  [[SQR:%.*]] = call half @llvm.sqrt.f16(half %a)
@@ -541,10 +493,3 @@ float16_t test_vminnmh_f16(float16_t a, float16_t b) {
 float16_t test_vmulxh_f16(float16_t a, float16_t b) {
   return vmulxh_f16(a, b);
 }
-
-// CHECK-LABEL: test_vrecpsh_f16
-// CHECK: [[RECPS:%.*]] = call half @llvm.aarch64.neon.frecps.f16(half %a, 
half %b)
-// CHECK: ret half [[RECPS]]
-float16_t test_vrecpsh_f16(float16_t a, float16_t b) {
-  return vrecpsh_f16(a, b);
-}

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to