This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG25951c5ab8e9: [AArch64] Add missing intrinsics for scalar FP 
rounding (authored by jaykang10).
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D98269/new/

https://reviews.llvm.org/D98269

Files:
  clang/include/clang/Basic/BuiltinsAArch64.def
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/Headers/arm_acle.h
  clang/test/CodeGen/aarch64-v8.5a-scalar-frint3264-intrinsic.c
  llvm/include/llvm/IR/IntrinsicsAArch64.td
  llvm/lib/Target/AArch64/AArch64InstrInfo.td
  llvm/test/CodeGen/AArch64/v8.5a-scalar-frint3264-intrinsic.ll

Index: llvm/test/CodeGen/AArch64/v8.5a-scalar-frint3264-intrinsic.ll
===================================================================
--- /dev/null
+++ 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
+}
Index: llvm/lib/Target/AArch64/AArch64InstrInfo.td
===================================================================
--- llvm/lib/Target/AArch64/AArch64InstrInfo.td
+++ llvm/lib/Target/AArch64/AArch64InstrInfo.td
@@ -3805,10 +3805,10 @@
 }
 
 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 {
Index: llvm/include/llvm/IR/IntrinsicsAArch64.td
===================================================================
--- llvm/include/llvm/IR/IntrinsicsAArch64.td
+++ llvm/include/llvm/IR/IntrinsicsAArch64.td
@@ -44,6 +44,19 @@
 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
 
Index: clang/test/CodeGen/aarch64-v8.5a-scalar-frint3264-intrinsic.c
===================================================================
--- /dev/null
+++ 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);
+}
Index: clang/lib/Headers/arm_acle.h
===================================================================
--- clang/lib/Headers/arm_acle.h
+++ clang/lib/Headers/arm_acle.h
@@ -639,6 +639,49 @@
 }
 #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 {
Index: clang/lib/CodeGen/CGBuiltin.cpp
===================================================================
--- clang/lib/CodeGen/CGBuiltin.cpp
+++ clang/lib/CodeGen/CGBuiltin.cpp
@@ -9149,6 +9149,38 @@
                               "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!");
Index: clang/include/clang/Basic/BuiltinsAArch64.def
===================================================================
--- clang/include/clang/Basic/BuiltinsAArch64.def
+++ clang/include/clang/Basic/BuiltinsAArch64.def
@@ -99,6 +99,16 @@
 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")
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to