[PATCH] D57044: [AArch64] Optimize Inf materialization

Adhemerval Zanella via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 23 08:56:48 PST 2019


zatrazz updated this revision to Diff 183109.
zatrazz added a comment.

Updated patch with additional tests. I added tests for __builtin_isinf expanded builtin for float, double, and long double (the latter still requires loading the constant).


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

https://reviews.llvm.org/D57044

Files:
  lib/Target/AArch64/AArch64ISelLowering.cpp
  test/CodeGen/AArch64/isinf.ll
  test/CodeGen/AArch64/known-never-nan.ll


Index: test/CodeGen/AArch64/known-never-nan.ll
===================================================================
--- test/CodeGen/AArch64/known-never-nan.ll
+++ test/CodeGen/AArch64/known-never-nan.ll
@@ -28,13 +28,13 @@
 define float @not_fmaxnm_maybe_nan(i32 %i1, i32 %i2) #0 {
 ; CHECK-LABEL: not_fmaxnm_maybe_nan:
 ; CHECK:       // %bb.0:
-; CHECK-NEXT:    adrp x8, .LCPI1_0
-; CHECK-NEXT:    ldr s0, [x8, :lo12:.LCPI1_0]
-; CHECK-NEXT:    ucvtf s1, w0
-; CHECK-NEXT:    ucvtf s2, w1
-; CHECK-NEXT:    fmov s3, #17.00000000
-; CHECK-NEXT:    fmul s0, s1, s0
-; CHECK-NEXT:    fadd s1, s2, s3
+; CHECK-NEXT:    orr w8, wzr, #0xff800000
+; CHECK-NEXT:    ucvtf s0, w0
+; CHECK-NEXT:    ucvtf s1, w1
+; CHECK-NEXT:    fmov s2, #17.00000000
+; CHECK-NEXT:    fmov s3, w8
+; CHECK-NEXT:    fmul s0, s0, s3
+; CHECK-NEXT:    fadd s1, s1, s2
 ; CHECK-NEXT:    fcmp s0, s1
 ; CHECK-NEXT:    fcsel s0, s0, s1, pl
 ; CHECK-NEXT:    ret
Index: test/CodeGen/AArch64/isinf.ll
===================================================================
--- /dev/null
+++ test/CodeGen/AArch64/isinf.ll
@@ -0,0 +1,47 @@
+; RUN: llc -mtriple=aarch64-none-linux-gnu -mattr=+neon < %s -o -| FileCheck %s
+
+declare float  @llvm.fabs.f32(float)
+declare double @llvm.fabs.f64(double)
+declare fp128  @llvm.fabs.f128(fp128)
+
+; Check if INFINITY for float is materialized
+define i32 @replace_isinf_call_f32(float %x) {
+; CHECK-LABEL: replace_isinf_call_f32:
+; CHECK:       orr    [[INFSCALARREG:w[0-9]+]], wzr, #0x7f800000
+; CHECK-NEXT:  fabs   [[ABS:s[0-9]+]], s0
+; CHECK-NEXT:  fmov   [[INFREG:s[0-9]+]], [[INFSCALARREG]]
+; CHECK-NEXT:  fcmp   [[ABS]], [[INFREG]]
+; CHECK-NEXT:  cset   w0, eq
+  %abs = tail call float @llvm.fabs.f32(float %x)
+  %cmpinf = fcmp oeq float %abs, 0x7FF0000000000000
+  %ret = zext i1 %cmpinf to i32
+  ret i32 %ret
+}
+
+; Check if INFINITY for double is materialized
+define i32 @replace_isinf_call_f64(double %x) {
+; CHECK-LABEL: replace_isinf_call_f64:
+; CHECK:       orr    [[INFSCALARREG:x[0-9]+]], xzr, #0x7ff0000000000000
+; CHECK-NEXT:  fabs   [[ABS:d[0-9]+]], d0
+; CHECK-NEXT:  fmov   [[INFREG:d[0-9]+]], [[INFSCALARREG]]
+; CHECK-NEXT:  fcmp   [[ABS]], [[INFREG]]
+; CHECK-NEXT:  cset   w0, eq
+  %abs = tail call double @llvm.fabs.f64(double %x)
+  %cmpinf = fcmp oeq double %abs, 0x7FF0000000000000
+  %ret = zext i1 %cmpinf to i32
+  ret i32 %ret
+}
+
+; For long double it still requires loading the constant.
+define i32 @replace_isinf_call_f128(fp128 %x) {
+; CHECK-LABEL: replace_isinf_call_f128:
+; CHECK:       adrp    [[ADDR:x[0-9]+]], [[CSTLABEL:.LCP.*]]
+; CHECK:       ldr     q1, {{[[]}}[[ADDR]], :lo12:[[CSTLABEL]]{{[]]}}
+; CHECK:       bl      __eqtf2
+; CHECK:       cmp     w0, #0
+; CHECK:       cset    w0, eq
+  %abs = tail call fp128 @llvm.fabs.f128(fp128 %x)
+  %cmpinf = fcmp oeq fp128 %abs, 0xL00000000000000007FFF000000000000
+  %ret = zext i1 %cmpinf to i32
+  ret i32 %ret
+}
Index: lib/Target/AArch64/AArch64ISelLowering.cpp
===================================================================
--- lib/Target/AArch64/AArch64ISelLowering.cpp
+++ lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -5426,11 +5426,14 @@
 }
 
 bool AArch64TargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT) const {
-  // We can materialize #0.0 as fmov $Rd, XZR for 64-bit and 32-bit cases.
+  // We can materialize #0.0 and #INF as fmov $Rd, XZR for 64-bit and 32-bit
+  // cases.
   // FIXME: We should be able to handle f128 as well with a clever lowering.
-  if (Imm.isPosZero() && (VT == MVT::f64 || VT == MVT::f32 ||
-                          (VT == MVT::f16 && Subtarget->hasFullFP16()))) {
-    LLVM_DEBUG(dbgs() << "Legal " << VT.getEVTString() << " imm value: 0\n");
+  if ((Imm.isPosZero() || Imm.isInfinity()) &&
+      (VT == MVT::f64 || VT == MVT::f32 ||
+       (VT == MVT::f16 && Subtarget->hasFullFP16()))) {
+    LLVM_DEBUG(dbgs() << "Legal " << VT.getEVTString() << " imm value: "
+                      << (Imm.isPosZero() ? "0" : "Inf") << "\n");
     return true;
   }
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D57044.183109.patch
Type: text/x-patch
Size: 4035 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190123/c43ff34f/attachment.bin>


More information about the llvm-commits mailing list