[llvm-branch-commits] [llvm] cbac419 - [ARM] Fix infinite loop when lowering STRICT_FP_EXTEND

Hans Wennborg via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Tue Feb 18 07:55:22 PST 2020


Author: John Brawn
Date: 2020-02-18T16:46:43+01:00
New Revision: cbac41966b8f9356a3e69c050b60770108550d1e

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

LOG: [ARM] Fix infinite loop when lowering STRICT_FP_EXTEND

If the target has FP64 but not FP16 then we have custom lowering for FP_EXTEND
and STRICT_FP_EXTEND with type f64. However if the extend is from f32 to f64 the
current implementation will cause in infinite loop for STRICT_FP_EXTEND due to
emitting a merge_values of the original node which after replacement becomes a
merge_values of itself.

Fix this by not doing anything for f32 to f64 extend when we have FP64, though
for STRICT_FP_EXTEND we have to do the strict-to-nonstrict mutation as that
doesn't happen automatically for opcodes with custom lowering.

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

(cherry picked from commit 0ec57972967dfb43fc022c2e3788be041d1db730)

Added: 
    

Modified: 
    llvm/lib/Target/ARM/ARMISelLowering.cpp
    llvm/test/CodeGen/ARM/fp-intrinsics.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp
index 8e4bb91d53b5..559a4e8435cd 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -16380,6 +16380,15 @@ SDValue ARMTargetLowering::LowerFP_EXTEND(SDValue Op, SelectionDAG &DAG) const {
   assert(!(DstSz == 32 && Subtarget->hasFP16()) &&
          "With FP16, 16 to 32 conversion is legal!");
 
+  // Converting from 32 -> 64 is valid if we have FP64.
+  if (SrcSz == 32 && DstSz == 64 && Subtarget->hasFP64()) {
+    // FIXME: Remove this when we have strict fp instruction selection patterns
+    if (IsStrict) {
+      DAG.mutateStrictFPToFP(Op.getNode());
+    }
+    return Op;
+  }
+
   // Either we are converting from 16 -> 64, without FP16 and/or
   // FP.double-precision or without Armv8-fp. So we must do it in two
   // steps.

diff  --git a/llvm/test/CodeGen/ARM/fp-intrinsics.ll b/llvm/test/CodeGen/ARM/fp-intrinsics.ll
index 4352548ef3c8..c5746ef7b307 100644
--- a/llvm/test/CodeGen/ARM/fp-intrinsics.ll
+++ b/llvm/test/CodeGen/ARM/fp-intrinsics.ll
@@ -1,7 +1,11 @@
-; RUN: llc -mtriple=armv8a-none-eabi %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-SP,CHECK-DP
+; RUN: llc -mtriple=armv8a-none-eabi %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-SP,CHECK-DP,CHECK-SP-V8,CHECK-DP-V8
 ; RUN: llc -mtriple=thumbv8m.main-none-eabi %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-NOSP,CHECK-NODP
-; RUN: llc -mtriple=thumbv8m.main-none-eabi %s -o - -mattr=fp-armv8 | FileCheck %s --check-prefixes=CHECK,CHECK-SP,CHECK-DP
-; RUN: llc -mtriple=thumbv8m.main-none-eabi %s -o - -mattr=fp-armv8sp | FileCheck %s --check-prefixes=CHECK,CHECK-SP,CHECK-NODP
+; RUN: llc -mtriple=thumbv8m.main-none-eabi %s -o - -mattr=fp-armv8 | FileCheck %s --check-prefixes=CHECK,CHECK-SP,CHECK-DP,CHECK-SP-V8,CHECK-DP-V8
+; RUN: llc -mtriple=thumbv8m.main-none-eabi %s -o - -mattr=fp-armv8sp | FileCheck %s --check-prefixes=CHECK,CHECK-SP,CHECK-NODP,CHECK-SP-V8
+; RUN: llc -mtriple=armv7a-none-eabi %s -o - -mattr=vfp4 | FileCheck %s --check-prefixes=CHECK,CHECK-SP,CHECK-DP,CHECK-SP-NOV8,CHECK-DP-NOV8
+; RUN: llc -mtriple=thumbv7m-none-eabi %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-NOSP,CHECK-NODP
+; RUN: llc -mtriple=thumbv7m-none-eabi %s -o - -mattr=vfp4 | FileCheck %s --check-prefixes=CHECK,CHECK-SP,CHECK-DP,CHECK-SP-NOV8,CHECK-DP-NOV8
+; RUN: llc -mtriple=thumbv7m-none-eabi %s -o - -mattr=vfp4sp | FileCheck %s --check-prefixes=CHECK,CHECK-SP,CHECK-NODP,CHECK-SP-NOV8
 
 ; Check that constrained fp intrinsics are correctly lowered. In particular
 ; check that the valid combinations of single-precision and double-precision
@@ -149,7 +153,8 @@ define float @exp2_f32(float %x) #0 {
 
 ; CHECK-LABEL: rint_f32:
 ; CHECK-NOSP: bl rintf
-; CHECK-SP: vrintx.f32
+; CHECK-SP-NOV8: bl rintf
+; CHECK-SP-V8: vrintx.f32
 define float @rint_f32(float %x) #0 {
   %val = call float @llvm.experimental.constrained.rint.f32(float %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
   ret float %val
@@ -157,7 +162,8 @@ define float @rint_f32(float %x) #0 {
 
 ; CHECK-LABEL: nearbyint_f32:
 ; CHECK-NOSP: bl nearbyintf
-; CHECK-SP: vrintr.f32
+; CHECK-SP-NOV8: bl nearbyintf
+; CHECK-SP-V8: vrintr.f32
 define float @nearbyint_f32(float %x) #0 {
   %val = call float @llvm.experimental.constrained.nearbyint.f32(float %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
   ret float %val
@@ -179,7 +185,8 @@ define i32 @llrint_f32(float %x) #0 {
 
 ; CHECK-LABEL: maxnum_f32:
 ; CHECK-NOSP: bl fmaxf
-; CHECK-SP: vmaxnm.f32
+; CHECK-SP-NOV8: bl fmaxf
+; CHECK-SP-V8: vmaxnm.f32
 define float @maxnum_f32(float %x, float %y) #0 {
   %val = call float @llvm.experimental.constrained.maxnum.f32(float %x, float %y, metadata !"fpexcept.strict") #0
   ret float %val
@@ -187,7 +194,8 @@ define float @maxnum_f32(float %x, float %y) #0 {
 
 ; CHECK-LABEL: minnum_f32:
 ; CHECK-NOSP: bl fminf
-; CHECK-SP: vminnm.f32
+; CHECK-SP-NOV8: bl fminf
+; CHECK-SP-V8: vminnm.f32
 define float @minnum_f32(float %x, float %y) #0 {
   %val = call float @llvm.experimental.constrained.minnum.f32(float %x, float %y, metadata !"fpexcept.strict") #0
   ret float %val
@@ -195,7 +203,8 @@ define float @minnum_f32(float %x, float %y) #0 {
 
 ; CHECK-LABEL: ceil_f32:
 ; CHECK-NOSP: bl ceilf
-; CHECK-SP: vrintp.f32
+; CHECK-SP-NOV8: bl ceilf
+; CHECK-SP-V8: vrintp.f32
 define float @ceil_f32(float %x) #0 {
   %val = call float @llvm.experimental.constrained.ceil.f32(float %x, metadata !"fpexcept.strict") #0
   ret float %val
@@ -203,7 +212,8 @@ define float @ceil_f32(float %x) #0 {
 
 ; CHECK-LABEL: floor_f32:
 ; CHECK-NOSP: bl floorf
-; CHECK-SP: vrintm.f32
+; CHECK-SP-NOV8: bl floorf
+; CHECK-SP-V8: vrintm.f32
 define float @floor_f32(float %x) #0 {
   %val = call float @llvm.experimental.constrained.floor.f32(float %x, metadata !"fpexcept.strict") #0
   ret float %val
@@ -225,7 +235,8 @@ define i32 @llround_f32(float %x) #0 {
 
 ; CHECK-LABEL: round_f32:
 ; CHECK-NOSP: bl roundf
-; CHECK-SP: vrinta.f32
+; CHECK-SP-NOV8: bl roundf
+; CHECK-SP-V8: vrinta.f32
 define float @round_f32(float %x) #0 {
   %val = call float @llvm.experimental.constrained.round.f32(float %x, metadata !"fpexcept.strict") #0
   ret float %val
@@ -233,7 +244,8 @@ define float @round_f32(float %x) #0 {
 
 ; CHECK-LABEL: trunc_f32:
 ; CHECK-NOSP: bl truncf
-; CHECK-SP: vrintz.f32
+; CHECK-SP-NOV8: bl truncf
+; CHECK-SP-V8: vrintz.f32
 define float @trunc_f32(float %x) #0 {
   %val = call float @llvm.experimental.constrained.trunc.f32(float %x, metadata !"fpexcept.strict") #0
   ret float %val
@@ -598,7 +610,8 @@ define double @exp2_f64(double %x) #0 {
 
 ; CHECK-LABEL: rint_f64:
 ; CHECK-NODP: bl rint
-; CHECK-DP: vrintx.f64
+; CHECK-DP-NOV8: bl rint
+; CHECK-DP-V8: vrintx.f64
 define double @rint_f64(double %x) #0 {
   %val = call double @llvm.experimental.constrained.rint.f64(double %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
   ret double %val
@@ -606,7 +619,8 @@ define double @rint_f64(double %x) #0 {
 
 ; CHECK-LABEL: nearbyint_f64:
 ; CHECK-NODP: bl nearbyint
-; CHECK-DP: vrintr.f64
+; CHECK-DP-NOV8: bl nearbyint
+; CHECK-DP-V8: vrintr.f64
 define double @nearbyint_f64(double %x) #0 {
   %val = call double @llvm.experimental.constrained.nearbyint.f64(double %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
   ret double %val
@@ -628,7 +642,8 @@ define i32 @llrint_f64(double %x) #0 {
 
 ; CHECK-LABEL: maxnum_f64:
 ; CHECK-NODP: bl fmax
-; CHECK-DP: vmaxnm.f64
+; CHECK-DP-NOV8: bl fmax
+; CHECK-DP-V8: vmaxnm.f64
 define double @maxnum_f64(double %x, double %y) #0 {
   %val = call double @llvm.experimental.constrained.maxnum.f64(double %x, double %y, metadata !"fpexcept.strict") #0
   ret double %val
@@ -636,7 +651,8 @@ define double @maxnum_f64(double %x, double %y) #0 {
 
 ; CHECK-LABEL: minnum_f64:
 ; CHECK-NODP: bl fmin
-; CHECK-DP: vminnm.f64
+; CHECK-DP-NOV8: bl fmin
+; CHECK-DP-V8: vminnm.f64
 define double @minnum_f64(double %x, double %y) #0 {
   %val = call double @llvm.experimental.constrained.minnum.f64(double %x, double %y, metadata !"fpexcept.strict") #0
   ret double %val
@@ -644,7 +660,8 @@ define double @minnum_f64(double %x, double %y) #0 {
 
 ; CHECK-LABEL: ceil_f64:
 ; CHECK-NODP: bl ceil
-; CHECK-DP: vrintp.f64
+; CHECK-DP-NOV8: bl ceil
+; CHECK-DP-V8: vrintp.f64
 define double @ceil_f64(double %x) #0 {
   %val = call double @llvm.experimental.constrained.ceil.f64(double %x, metadata !"fpexcept.strict") #0
   ret double %val
@@ -652,7 +669,8 @@ define double @ceil_f64(double %x) #0 {
 
 ; CHECK-LABEL: floor_f64:
 ; CHECK-NODP: bl floor
-; CHECK-DP: vrintm.f64
+; CHECK-DP-NOV8: bl floor
+; CHECK-DP-V8: vrintm.f64
 define double @floor_f64(double %x) #0 {
   %val = call double @llvm.experimental.constrained.floor.f64(double %x, metadata !"fpexcept.strict") #0
   ret double %val
@@ -674,7 +692,8 @@ define i32 @llround_f64(double %x) #0 {
 
 ; CHECK-LABEL: round_f64:
 ; CHECK-NODP: bl round
-; CHECK-DP: vrinta.f64
+; CHECK-DP-NOV8: bl round
+; CHECK-DP-V8: vrinta.f64
 define double @round_f64(double %x) #0 {
   %val = call double @llvm.experimental.constrained.round.f64(double %x, metadata !"fpexcept.strict") #0
   ret double %val
@@ -682,7 +701,8 @@ define double @round_f64(double %x) #0 {
 
 ; CHECK-LABEL: trunc_f64:
 ; CHECK-NODP: bl trunc
-; CHECK-DP: vrintz.f64
+; CHECK-DP-NOV8: bl trunc
+; CHECK-DP-V8: vrintz.f64
 define double @trunc_f64(double %x) #0 {
   %val = call double @llvm.experimental.constrained.trunc.f64(double %x, metadata !"fpexcept.strict") #0
   ret double %val


        


More information about the llvm-branch-commits mailing list