[clang] 25951c5 - [AArch64] Add missing intrinsics for scalar FP rounding

Jingu Kang via cfe-commits cfe-commits at lists.llvm.org
Wed Mar 10 05:41:01 PST 2021


Author: Jingu Kang
Date: 2021-03-10T13:22:29Z
New Revision: 25951c5ab8e9d8e4040de163f06c444c73314551

URL: https://github.com/llvm/llvm-project/commit/25951c5ab8e9d8e4040de163f06c444c73314551
DIFF: https://github.com/llvm/llvm-project/commit/25951c5ab8e9d8e4040de163f06c444c73314551.diff

LOG: [AArch64] Add missing intrinsics for scalar FP rounding

Differential Revision: https://reviews.llvm.org/D98269

Added: 
    clang/test/CodeGen/aarch64-v8.5a-scalar-frint3264-intrinsic.c
    llvm/test/CodeGen/AArch64/v8.5a-scalar-frint3264-intrinsic.ll

Modified: 
    clang/include/clang/Basic/BuiltinsAArch64.def
    clang/lib/CodeGen/CGBuiltin.cpp
    clang/lib/Headers/arm_acle.h
    llvm/include/llvm/IR/IntrinsicsAArch64.td
    llvm/lib/Target/AArch64/AArch64InstrInfo.td

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Basic/BuiltinsAArch64.def b/clang/include/clang/Basic/BuiltinsAArch64.def
index b35510f8b691..cfd6ff7f410b 100644
--- a/clang/include/clang/Basic/BuiltinsAArch64.def
+++ b/clang/include/clang/Basic/BuiltinsAArch64.def
@@ -99,6 +99,16 @@ BUILTIN(__builtin_arm_tcommit, "v", "n")
 BUILTIN(__builtin_arm_tcancel, "vWUIi", "n")
 BUILTIN(__builtin_arm_ttest, "WUi", "nc")
 
+// Armv8.5-A FP rounding intrinsics
+BUILTIN(__builtin_arm_frint32zf, "ff", "")
+BUILTIN(__builtin_arm_frint32z, "dd", "")
+BUILTIN(__builtin_arm_frint64zf, "ff", "")
+BUILTIN(__builtin_arm_frint64z, "dd", "")
+BUILTIN(__builtin_arm_frint32xf, "ff", "")
+BUILTIN(__builtin_arm_frint32x, "dd", "")
+BUILTIN(__builtin_arm_frint64xf, "ff", "")
+BUILTIN(__builtin_arm_frint64x, "dd", "")
+
 // Armv8.7-A load/store 64-byte intrinsics
 BUILTIN(__builtin_arm_ld64b, "vvC*WUi*", "n")
 BUILTIN(__builtin_arm_st64b, "vv*WUiC*", "n")

diff  --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index eb5c430e4df0..d24326162290 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -9149,6 +9149,38 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID,
                               "cls");
   }
 
+  if (BuiltinID == AArch64::BI__builtin_arm_frint32zf ||
+      BuiltinID == AArch64::BI__builtin_arm_frint32z) {
+    llvm::Value *Arg = EmitScalarExpr(E->getArg(0));
+    llvm::Type *Ty = Arg->getType();
+    return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::aarch64_frint32z, Ty),
+                              Arg, "frint32z");
+  }
+
+  if (BuiltinID == AArch64::BI__builtin_arm_frint64zf ||
+      BuiltinID == AArch64::BI__builtin_arm_frint64z) {
+    llvm::Value *Arg = EmitScalarExpr(E->getArg(0));
+    llvm::Type *Ty = Arg->getType();
+    return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::aarch64_frint64z, Ty),
+                              Arg, "frint64z");
+  }
+
+  if (BuiltinID == AArch64::BI__builtin_arm_frint32xf ||
+      BuiltinID == AArch64::BI__builtin_arm_frint32x) {
+    llvm::Value *Arg = EmitScalarExpr(E->getArg(0));
+    llvm::Type *Ty = Arg->getType();
+    return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::aarch64_frint32x, Ty),
+                              Arg, "frint32x");
+  }
+
+  if (BuiltinID == AArch64::BI__builtin_arm_frint64xf ||
+      BuiltinID == AArch64::BI__builtin_arm_frint64x) {
+    llvm::Value *Arg = EmitScalarExpr(E->getArg(0));
+    llvm::Type *Ty = Arg->getType();
+    return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::aarch64_frint64x, Ty),
+                              Arg, "frint64x");
+  }
+
   if (BuiltinID == AArch64::BI__builtin_arm_jcvt) {
     assert((getContext().getTypeSize(E->getType()) == 32) &&
            "__jcvt of unusual size!");

diff  --git a/clang/lib/Headers/arm_acle.h b/clang/lib/Headers/arm_acle.h
index c156d89c1f84..c34cd6403dbc 100644
--- a/clang/lib/Headers/arm_acle.h
+++ b/clang/lib/Headers/arm_acle.h
@@ -639,6 +639,49 @@ __jcvt(double __a) {
 }
 #endif
 
+/* Armv8.5-A FP rounding intrinsics */
+#if __ARM_64BIT_STATE && defined(__ARM_FEATURE_FRINT)
+static __inline__ float __attribute__((__always_inline__, __nodebug__))
+__frint32zf(float __a) {
+  return __builtin_arm_frint32zf(__a);
+}
+
+static __inline__ double __attribute__((__always_inline__, __nodebug__))
+__frint32z(double __a) {
+  return __builtin_arm_frint32z(__a);
+}
+
+static __inline__ float __attribute__((__always_inline__, __nodebug__))
+__frint64zf(float __a) {
+  return __builtin_arm_frint64zf(__a);
+}
+
+static __inline__ double __attribute__((__always_inline__, __nodebug__))
+__frint64z(double __a) {
+  return __builtin_arm_frint64z(__a);
+}
+
+static __inline__ float __attribute__((__always_inline__, __nodebug__))
+__frint32xf(float __a) {
+  return __builtin_arm_frint32xf(__a);
+}
+
+static __inline__ double __attribute__((__always_inline__, __nodebug__))
+__frint32x(double __a) {
+  return __builtin_arm_frint32x(__a);
+}
+
+static __inline__ float __attribute__((__always_inline__, __nodebug__))
+__frint64xf(float __a) {
+  return __builtin_arm_frint64xf(__a);
+}
+
+static __inline__ double __attribute__((__always_inline__, __nodebug__))
+__frint64x(double __a) {
+  return __builtin_arm_frint64x(__a);
+}
+#endif
+
 /* Armv8.7-A load/store 64-byte intrinsics */
 #if __ARM_64BIT_STATE && defined(__ARM_FEATURE_LS64)
 typedef struct {

diff  --git a/clang/test/CodeGen/aarch64-v8.5a-scalar-frint3264-intrinsic.c b/clang/test/CodeGen/aarch64-v8.5a-scalar-frint3264-intrinsic.c
new file mode 100644
index 000000000000..b57e92187129
--- /dev/null
+++ b/clang/test/CodeGen/aarch64-v8.5a-scalar-frint3264-intrinsic.c
@@ -0,0 +1,64 @@
+// RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +v8.5a\
+// RUN: -flax-vector-conversions=none -S -disable-O0-optnone -emit-llvm -o - %s \
+// RUN: | opt -S -mem2reg \
+// RUN: | FileCheck %s
+
+// REQUIRES: aarch64-registered-target
+
+#include <arm_acle.h>
+
+// CHECK-LABEL: test_frint32zf
+// CHECK:  [[RND:%.*]] =  call float @llvm.aarch64.frint32z.f32(float %a)
+// CHECK:  ret float [[RND]]
+float test_frint32zf(float a) {
+  return __frint32zf(a);
+}
+
+// CHECK-LABEL: test_frint32z
+// CHECK:  [[RND:%.*]] =  call double @llvm.aarch64.frint32z.f64(double %a)
+// CHECK:  ret double [[RND]]
+double test_frint32z(double a) {
+  return __frint32z(a);
+}
+
+// CHECK-LABEL: test_frint64zf
+// CHECK:  [[RND:%.*]] =  call float @llvm.aarch64.frint64z.f32(float %a)
+// CHECK:  ret float [[RND]]
+float test_frint64zf(float a) {
+  return __frint64zf(a);
+}
+
+// CHECK-LABEL: test_frint64z
+// CHECK:  [[RND:%.*]] =  call double @llvm.aarch64.frint64z.f64(double %a)
+// CHECK:  ret double [[RND]]
+double test_frint64z(double a) {
+  return __frint64z(a);
+}
+
+// CHECK-LABEL: test_frint32xf
+// CHECK:  [[RND:%.*]] =  call float @llvm.aarch64.frint32x.f32(float %a)
+// CHECK:  ret float [[RND]]
+float test_frint32xf(float a) {
+  return __frint32xf(a);
+}
+
+// CHECK-LABEL: test_frint32x
+// CHECK:  [[RND:%.*]] =  call double @llvm.aarch64.frint32x.f64(double %a)
+// CHECK:  ret double [[RND]]
+double test_frint32x(double a) {
+  return __frint32x(a);
+}
+
+// CHECK-LABEL: test_frint64xf
+// CHECK:  [[RND:%.*]] =  call float @llvm.aarch64.frint64x.f32(float %a)
+// CHECK:  ret float [[RND]]
+float test_frint64xf(float a) {
+  return __frint64xf(a);
+}
+
+// CHECK-LABEL: test_frint64x
+// CHECK:  [[RND:%.*]] =  call double @llvm.aarch64.frint64x.f64(double %a)
+// CHECK:  ret double [[RND]]
+double test_frint64x(double a) {
+  return __frint64x(a);
+}

diff  --git a/llvm/include/llvm/IR/IntrinsicsAArch64.td b/llvm/include/llvm/IR/IntrinsicsAArch64.td
index 0fb021418010..6e739d8df6a9 100644
--- a/llvm/include/llvm/IR/IntrinsicsAArch64.td
+++ b/llvm/include/llvm/IR/IntrinsicsAArch64.td
@@ -44,6 +44,19 @@ def int_aarch64_fjcvtzs : DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_double_ty],
 def int_aarch64_cls: DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrNoMem]>;
 def int_aarch64_cls64: DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i64_ty], [IntrNoMem]>;
 
+def int_aarch64_frint32z
+    : DefaultAttrsIntrinsic<[ llvm_anyfloat_ty ], [ LLVMMatchType<0> ],
+                            [ IntrNoMem ]>;
+def int_aarch64_frint64z
+    : DefaultAttrsIntrinsic<[ llvm_anyfloat_ty ], [ LLVMMatchType<0> ],
+                            [ IntrNoMem ]>;
+def int_aarch64_frint32x
+    : DefaultAttrsIntrinsic<[ llvm_anyfloat_ty ], [ LLVMMatchType<0> ],
+                            [ IntrNoMem ]>;
+def int_aarch64_frint64x
+    : DefaultAttrsIntrinsic<[ llvm_anyfloat_ty ], [ LLVMMatchType<0> ],
+                            [ IntrNoMem ]>;
+
 //===----------------------------------------------------------------------===//
 // HINT
 

diff  --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
index e9f294028a28..89c7234485f5 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
@@ -3805,10 +3805,10 @@ defm FSQRT  : SingleOperandFPData<0b0011, "fsqrt", fsqrt>;
 }
 
 let Predicates = [HasFRInt3264] in {
-  defm FRINT32Z : FRIntNNT<0b00, "frint32z">;
-  defm FRINT64Z : FRIntNNT<0b10, "frint64z">;
-  defm FRINT32X : FRIntNNT<0b01, "frint32x">;
-  defm FRINT64X : FRIntNNT<0b11, "frint64x">;
+  defm FRINT32Z : FRIntNNT<0b00, "frint32z", int_aarch64_frint32z>;
+  defm FRINT64Z : FRIntNNT<0b10, "frint64z", int_aarch64_frint64z>;
+  defm FRINT32X : FRIntNNT<0b01, "frint32x", int_aarch64_frint32x>;
+  defm FRINT64X : FRIntNNT<0b11, "frint64x", int_aarch64_frint64x>;
 } // HasFRInt3264
 
 let Predicates = [HasFullFP16] in {

diff  --git a/llvm/test/CodeGen/AArch64/v8.5a-scalar-frint3264-intrinsic.ll b/llvm/test/CodeGen/AArch64/v8.5a-scalar-frint3264-intrinsic.ll
new file mode 100644
index 000000000000..b4a0f3d557c6
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/v8.5a-scalar-frint3264-intrinsic.ll
@@ -0,0 +1,83 @@
+; RUN: llc < %s -mtriple=aarch64-eabi -mattr=+v8.5a  | FileCheck %s
+
+declare float @llvm.aarch64.frint32z.f32(float)
+declare double @llvm.aarch64.frint32z.f64(double)
+declare float @llvm.aarch64.frint64z.f32(float)
+declare double @llvm.aarch64.frint64z.f64(double)
+
+define dso_local float @t_frint32z(float %a) {
+; CHECK-LABEL: t_frint32z:
+; CHECK:         frint32z s0, s0
+; CHECK-NEXT:    ret
+entry:
+  %val = tail call float @llvm.aarch64.frint32z.f32(float %a)
+  ret float %val
+}
+
+define dso_local double @t_frint32zf(double %a) {
+; CHECK-LABEL: t_frint32zf:
+; CHECK:         frint32z d0, d0
+; CHECK-NEXT:    ret
+entry:
+  %val = tail call double @llvm.aarch64.frint32z.f64(double %a)
+  ret double %val
+}
+
+define dso_local float @t_frint64z(float %a) {
+; CHECK-LABEL: t_frint64z:
+; CHECK:         frint64z s0, s0
+; CHECK-NEXT:    ret
+entry:
+  %val = tail call float @llvm.aarch64.frint64z.f32(float %a)
+  ret float %val
+}
+
+define dso_local double @t_frint64zf(double %a) {
+; CHECK-LABEL: t_frint64zf:
+; CHECK:         frint64z d0, d0
+; CHECK-NEXT:    ret
+entry:
+  %val = tail call double @llvm.aarch64.frint64z.f64(double %a)
+  ret double %val
+}
+
+declare float @llvm.aarch64.frint32x.f32(float)
+declare double @llvm.aarch64.frint32x.f64(double)
+declare float @llvm.aarch64.frint64x.f32(float)
+declare double @llvm.aarch64.frint64x.f64(double)
+
+define dso_local float @t_frint32x(float %a) {
+; CHECK-LABEL: t_frint32x:
+; CHECK:         frint32x s0, s0
+; CHECK-NEXT:    ret
+entry:
+  %val = tail call float @llvm.aarch64.frint32x.f32(float %a)
+  ret float %val
+}
+
+define dso_local double @t_frint32xf(double %a) {
+; CHECK-LABEL: t_frint32xf:
+; CHECK:         frint32x d0, d0
+; CHECK-NEXT:    ret
+entry:
+  %val = tail call double @llvm.aarch64.frint32x.f64(double %a)
+  ret double %val
+}
+
+define dso_local float @t_frint64x(float %a) {
+; CHECK-LABEL: t_frint64x:
+; CHECK:         frint64x s0, s0
+; CHECK-NEXT:    ret
+entry:
+  %val = tail call float @llvm.aarch64.frint64x.f32(float %a)
+  ret float %val
+}
+
+define dso_local double @t_frint64xf(double %a) {
+; CHECK-LABEL: t_frint64xf:
+; CHECK:         frint64x d0, d0
+; CHECK-NEXT:    ret
+entry:
+  %val = tail call double @llvm.aarch64.frint64x.f64(double %a)
+  ret double %val
+}


        


More information about the cfe-commits mailing list