[llvm] r277602 - Disable shrinking of SNaN constants

Elliot Colp via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 3 08:09:22 PDT 2016


Author: colpell
Date: Wed Aug  3 10:09:21 2016
New Revision: 277602

URL: http://llvm.org/viewvc/llvm-project?rev=277602&view=rev
Log:
Disable shrinking of SNaN constants

When expanding FP constants, we attempt to shrink doubles to floats and perform an extending load.
However, on SystemZ, and possibly on other targets (I've only confirmed the problem on SystemZ), the FP extending load instruction may convert SNaN into QNaN, or may cause an exception. So in the general case, we would still like to shrink FP constants, but SNaNs should be left as doubles.

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

Added:
    llvm/trunk/test/CodeGen/SystemZ/fp-const-10.ll
Modified:
    llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp?rev=277602&r1=277601&r2=277602&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Wed Aug  3 10:09:21 2016
@@ -259,19 +259,25 @@ SelectionDAGLegalize::ExpandConstantFP(C
                            (VT == MVT::f64) ? MVT::i64 : MVT::i32);
   }
 
+  APFloat APF = CFP->getValueAPF();
   EVT OrigVT = VT;
   EVT SVT = VT;
-  while (SVT != MVT::f32 && SVT != MVT::f16) {
-    SVT = (MVT::SimpleValueType)(SVT.getSimpleVT().SimpleTy - 1);
-    if (ConstantFPSDNode::isValueValidForType(SVT, CFP->getValueAPF()) &&
-        // Only do this if the target has a native EXTLOAD instruction from
-        // smaller type.
-        TLI.isLoadExtLegal(ISD::EXTLOAD, OrigVT, SVT) &&
-        TLI.ShouldShrinkFPConstant(OrigVT)) {
-      Type *SType = SVT.getTypeForEVT(*DAG.getContext());
-      LLVMC = cast<ConstantFP>(ConstantExpr::getFPTrunc(LLVMC, SType));
-      VT = SVT;
-      Extend = true;
+
+  // We don't want to shrink SNaNs. Converting the SNaN back to its real type
+  // can cause it to be changed into a QNaN on some platforms (e.g. on SystemZ).
+  if (!APF.isSignaling()) {
+    while (SVT != MVT::f32 && SVT != MVT::f16) {
+      SVT = (MVT::SimpleValueType)(SVT.getSimpleVT().SimpleTy - 1);
+      if (ConstantFPSDNode::isValueValidForType(SVT, APF) &&
+          // Only do this if the target has a native EXTLOAD instruction from
+          // smaller type.
+          TLI.isLoadExtLegal(ISD::EXTLOAD, OrigVT, SVT) &&
+          TLI.ShouldShrinkFPConstant(OrigVT)) {
+        Type *SType = SVT.getTypeForEVT(*DAG.getContext());
+        LLVMC = cast<ConstantFP>(ConstantExpr::getFPTrunc(LLVMC, SType));
+        VT = SVT;
+        Extend = true;
+      }
     }
   }
 

Added: llvm/trunk/test/CodeGen/SystemZ/fp-const-10.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/SystemZ/fp-const-10.ll?rev=277602&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/SystemZ/fp-const-10.ll (added)
+++ llvm/trunk/test/CodeGen/SystemZ/fp-const-10.ll Wed Aug  3 10:09:21 2016
@@ -0,0 +1,15 @@
+; Test loads of SNaN.
+;
+; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
+
+; Test that we don't do an FP extending load, as this would result in a
+; converstion to QNaN.
+define double @f1() {
+; CHECK-LABEL: .LCPI0_0
+; CHECK:      .quad   9219994337134247936
+; CHECK-LABEL: f1:
+; CHECK:      larl    %r1, .LCPI0_0
+; CHECK-NOT:  ldeb    %f0, 0(%r1)
+; CHECK:      ld      %f0, 0(%r1)
+  ret double 0x7FF4000000000000
+}




More information about the llvm-commits mailing list