[llvm] 1d782c2 - [PowerPC] Pass nofpexcept flag to custom lowered constrained ops

Qiu Chaofan via llvm-commits llvm-commits at lists.llvm.org
Sun Sep 20 19:44:40 PDT 2020


Author: Qiu Chaofan
Date: 2020-09-21T10:44:25+08:00
New Revision: 1d782c29872ce3dcc4b64bfde97e197e9042fbfb

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

LOG: [PowerPC] Pass nofpexcept flag to custom lowered constrained ops

This is a follow-up of D86605. For strict DAG FP node, if its FP
exception behavior metadata is ignore, it should have nofpexcept flag.
But during custom lowering, this flag isn't passed down.

This is also seen on X86 target.

Reviewed By: uweigand

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

Added: 
    

Modified: 
    llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
    llvm/lib/Target/PowerPC/PPCISelLowering.cpp
    llvm/test/CodeGen/PowerPC/fp-strict-conv-f128.ll
    llvm/test/CodeGen/PowerPC/fp-strict-conv.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
index 27105060c785..9ab5e3865efd 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
@@ -1620,6 +1620,10 @@ void DAGTypeLegalizer::ExpandFloatRes_XINT_TO_FP(SDNode *N, SDValue &Lo,
   SDLoc dl(N);
   SDValue Chain = Strict ? N->getOperand(0) : DAG.getEntryNode();
 
+  // TODO: Any other flags to propagate?
+  SDNodeFlags Flags;
+  Flags.setNoFPExcept(N->getFlags().hasNoFPExcept());
+
   // First do an SINT_TO_FP, whether the original was signed or unsigned.
   // When promoting partial word types to i32 we must honor the signedness,
   // though.
@@ -1630,8 +1634,8 @@ void DAGTypeLegalizer::ExpandFloatRes_XINT_TO_FP(SDNode *N, SDValue &Lo,
     Lo = DAG.getConstantFP(APFloat(DAG.EVTToAPFloatSemantics(NVT),
                                    APInt(NVT.getSizeInBits(), 0)), dl, NVT);
     if (Strict) {
-      Hi = DAG.getNode(ISD::STRICT_SINT_TO_FP, dl, {NVT, MVT::Other},
-                       {Chain, Src});
+      Hi = DAG.getNode(ISD::STRICT_SINT_TO_FP, dl,
+                       DAG.getVTList(NVT, MVT::Other), {Chain, Src}, Flags);
       Chain = Hi.getValue(1);
     } else
       Hi = DAG.getNode(ISD::SINT_TO_FP, dl, NVT, Src);
@@ -1690,12 +1694,12 @@ void DAGTypeLegalizer::ExpandFloatRes_XINT_TO_FP(SDNode *N, SDValue &Lo,
     break;
   }
 
-  // TODO: Are there fast-math-flags to propagate to this FADD?
+  // TODO: Are there other fast-math-flags to propagate to this FADD?
   SDValue NewLo = DAG.getConstantFP(
       APFloat(APFloat::PPCDoubleDouble(), APInt(128, Parts)), dl, MVT::ppcf128);
   if (Strict) {
-    Lo = DAG.getNode(ISD::STRICT_FADD, dl, {VT, MVT::Other},
-                     {Chain, Hi, NewLo});
+    Lo = DAG.getNode(ISD::STRICT_FADD, dl, DAG.getVTList(VT, MVT::Other),
+                     {Chain, Hi, NewLo}, Flags);
     Chain = Lo.getValue(1);
     ReplaceValueWith(SDValue(N, 1), Chain);
   } else

diff  --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index 6bdebf9111d6..706ccb60e1a6 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -8090,14 +8090,20 @@ static SDValue convertFPToInt(SDValue Op, SelectionDAG &DAG,
   bool IsStrict = Op->isStrictFPOpcode();
   bool IsSigned = Op.getOpcode() == ISD::FP_TO_SINT ||
                   Op.getOpcode() == ISD::STRICT_FP_TO_SINT;
+
+  // TODO: Any other flags to propagate?
+  SDNodeFlags Flags;
+  Flags.setNoFPExcept(Op->getFlags().hasNoFPExcept());
+
   // For strict nodes, source is the second operand.
   SDValue Src = Op.getOperand(IsStrict ? 1 : 0);
   SDValue Chain = IsStrict ? Op.getOperand(0) : SDValue();
   assert(Src.getValueType().isFloatingPoint());
   if (Src.getValueType() == MVT::f32) {
     if (IsStrict) {
-      Src = DAG.getNode(ISD::STRICT_FP_EXTEND, dl, {MVT::f64, MVT::Other},
-                        {Chain, Src});
+      Src =
+          DAG.getNode(ISD::STRICT_FP_EXTEND, dl,
+                      DAG.getVTList(MVT::f64, MVT::Other), {Chain, Src}, Flags);
       Chain = Src.getValue(1);
     } else
       Src = DAG.getNode(ISD::FP_EXTEND, dl, MVT::f64, Src);
@@ -8117,7 +8123,8 @@ static SDValue convertFPToInt(SDValue Op, SelectionDAG &DAG,
   }
   if (IsStrict) {
     Opc = getPPCStrictOpcode(Opc);
-    Conv = DAG.getNode(Opc, dl, {MVT::f64, MVT::Other}, {Chain, Src});
+    Conv = DAG.getNode(Opc, dl, DAG.getVTList(MVT::f64, MVT::Other),
+                       {Chain, Src}, Flags);
   } else {
     Conv = DAG.getNode(Opc, dl, MVT::f64, Src);
   }
@@ -8398,6 +8405,11 @@ static SDValue convertIntToFP(SDValue Op, SDValue Src, SelectionDAG &DAG,
   bool IsSigned = Op.getOpcode() == ISD::SINT_TO_FP ||
                   Op.getOpcode() == ISD::STRICT_SINT_TO_FP;
   SDLoc dl(Op);
+
+  // TODO: Any other flags to propagate?
+  SDNodeFlags Flags;
+  Flags.setNoFPExcept(Op->getFlags().hasNoFPExcept());
+
   // If we have FCFIDS, then use it when converting to single-precision.
   // Otherwise, convert to double-precision and then round.
   bool IsSingle = Op.getValueType() == MVT::f32 && Subtarget.hasFPCVT();
@@ -8407,8 +8419,8 @@ static SDValue convertIntToFP(SDValue Op, SDValue Src, SelectionDAG &DAG,
   if (Op->isStrictFPOpcode()) {
     if (!Chain)
       Chain = Op.getOperand(0);
-    return DAG.getNode(getPPCStrictOpcode(ConvOpc), dl, {ConvTy, MVT::Other},
-                       {Chain, Src});
+    return DAG.getNode(getPPCStrictOpcode(ConvOpc), dl,
+                       DAG.getVTList(ConvTy, MVT::Other), {Chain, Src}, Flags);
   } else
     return DAG.getNode(ConvOpc, dl, ConvTy, Src);
 }
@@ -8464,6 +8476,10 @@ SDValue PPCTargetLowering::LowerINT_TO_FPVector(SDValue Op, SelectionDAG &DAG,
   assert((Op.getValueType() == MVT::v2f64 || Op.getValueType() == MVT::v4f32) &&
          "Supports conversions to v2f64/v4f32 only.");
 
+  // TODO: Any other flags to propagate?
+  SDNodeFlags Flags;
+  Flags.setNoFPExcept(Op->getFlags().hasNoFPExcept());
+
   bool SignedConv = Opc == ISD::SINT_TO_FP || Opc == ISD::STRICT_SINT_TO_FP;
   bool FourEltRes = Op.getValueType() == MVT::v4f32;
 
@@ -8503,8 +8519,8 @@ SDValue PPCTargetLowering::LowerINT_TO_FPVector(SDValue Op, SelectionDAG &DAG,
     Extend = DAG.getNode(ISD::BITCAST, dl, IntermediateVT, Arrange);
 
   if (IsStrict)
-    return DAG.getNode(Opc, dl, {Op.getValueType(), MVT::Other},
-                       {Op.getOperand(0), Extend});
+    return DAG.getNode(Opc, dl, DAG.getVTList(Op.getValueType(), MVT::Other),
+                       {Op.getOperand(0), Extend}, Flags);
 
   return DAG.getNode(Opc, dl, Op.getValueType(), Extend);
 }
@@ -8518,6 +8534,10 @@ SDValue PPCTargetLowering::LowerINT_TO_FP(SDValue Op,
   SDValue Src = Op.getOperand(IsStrict ? 1 : 0);
   SDValue Chain = IsStrict ? Op.getOperand(0) : DAG.getEntryNode();
 
+  // TODO: Any other flags to propagate?
+  SDNodeFlags Flags;
+  Flags.setNoFPExcept(Op->getFlags().hasNoFPExcept());
+
   EVT InVT = Src.getValueType();
   EVT OutVT = Op.getValueType();
   if (OutVT.isVector() && OutVT.isFloatingPoint() &&
@@ -8667,8 +8687,9 @@ SDValue PPCTargetLowering::LowerINT_TO_FP(SDValue Op,
 
     if (Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
       if (IsStrict)
-        FP = DAG.getNode(ISD::STRICT_FP_ROUND, dl, {MVT::f32, MVT::Other},
-                         {Chain, FP, DAG.getIntPtrConstant(0, dl)});
+        FP = DAG.getNode(ISD::STRICT_FP_ROUND, dl,
+                         DAG.getVTList(MVT::f32, MVT::Other),
+                         {Chain, FP, DAG.getIntPtrConstant(0, dl)}, Flags);
       else
         FP = DAG.getNode(ISD::FP_ROUND, dl, MVT::f32, FP,
                          DAG.getIntPtrConstant(0, dl));
@@ -8747,8 +8768,9 @@ SDValue PPCTargetLowering::LowerINT_TO_FP(SDValue Op,
     Chain = FP.getValue(1);
   if (Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
     if (IsStrict)
-      FP = DAG.getNode(ISD::STRICT_FP_ROUND, dl, {MVT::f32, MVT::Other},
-                       {Chain, FP, DAG.getIntPtrConstant(0, dl)});
+      FP = DAG.getNode(ISD::STRICT_FP_ROUND, dl,
+                       DAG.getVTList(MVT::f32, MVT::Other),
+                       {Chain, FP, DAG.getIntPtrConstant(0, dl)}, Flags);
     else
       FP = DAG.getNode(ISD::FP_ROUND, dl, MVT::f32, FP,
                        DAG.getIntPtrConstant(0, dl));

diff  --git a/llvm/test/CodeGen/PowerPC/fp-strict-conv-f128.ll b/llvm/test/CodeGen/PowerPC/fp-strict-conv-f128.ll
index b4927f3da063..57f73e995b25 100644
--- a/llvm/test/CodeGen/PowerPC/fp-strict-conv-f128.ll
+++ b/llvm/test/CodeGen/PowerPC/fp-strict-conv-f128.ll
@@ -835,9 +835,9 @@ define void @fptoint_nofpexcept(ppc_fp128 %p, fp128 %m, i32* %addr1, i64* %addr2
 ; MIR: renamable $v{{[0-9]+}} = nofpexcept XSCVQPUDZ
 ;
 ; MIR: renamable $f{{[0-9]+}} = nofpexcept FADD
-; MIR: renamable $f{{[0-9]+}} = XSCVDPSXWS
+; MIR: renamable $f{{[0-9]+}} = nofpexcept XSCVDPSXWS
 ; MIR: renamable $f{{[0-9]+}} = nofpexcept FADD
-; MIR: renamable $f{{[0-9]+}} = XSCVDPSXWS
+; MIR: renamable $f{{[0-9]+}} = nofpexcept XSCVDPSXWS
 entry:
   %conv1 = tail call i32 @llvm.experimental.constrained.fptosi.i32.f128(fp128 %m, metadata !"fpexcept.ignore") #0
   store volatile i32 %conv1, i32* %addr1, align 4

diff  --git a/llvm/test/CodeGen/PowerPC/fp-strict-conv.ll b/llvm/test/CodeGen/PowerPC/fp-strict-conv.ll
index 0d932016274c..3e26f417ceab 100644
--- a/llvm/test/CodeGen/PowerPC/fp-strict-conv.ll
+++ b/llvm/test/CodeGen/PowerPC/fp-strict-conv.ll
@@ -6,6 +6,8 @@
 ; RUN: llc -verify-machineinstrs -ppc-asm-full-reg-names -ppc-vsr-nums-as-vr \
 ; RUN:   < %s -mtriple=powerpc64le-unknown-linux -mcpu=pwr8 -mattr=-vsx | \
 ; RUN:   FileCheck %s -check-prefix=NOVSX
+; RUN: llc -mtriple=powerpc64le-unknown-linux -mcpu=pwr9 < %s -simplify-mir \
+; RUN:   -stop-after=machine-cp | FileCheck %s -check-prefix=MIR
 
 declare i32 @llvm.experimental.constrained.fptosi.i32.f64(double, metadata)
 declare i64 @llvm.experimental.constrained.fptosi.i64.f64(double, metadata)
@@ -326,4 +328,86 @@ entry:
   ret float %conv
 }
 
+define void @fptoint_nofpexcept_f64(double %m, i32* %addr1, i64* %addr2) {
+; MIR-LABEL: name: fptoint_nofpexcept_f64
+; MIR: renamable $f{{[0-9]+}} = nofpexcept XSCVDPSXWS
+; MIR: renamable $f{{[0-9]+}} = nofpexcept XSCVDPUXWS
+; MIR: renamable $f{{[0-9]+}} = nofpexcept XSCVDPSXDS
+; MIR: renamable $f{{[0-9]+}} = nofpexcept XSCVDPUXDS
+entry:
+  %conv1 = tail call i32 @llvm.experimental.constrained.fptosi.i32.f64(double %m, metadata !"fpexcept.ignore") #0
+  %conv2 = tail call i32 @llvm.experimental.constrained.fptoui.i32.f64(double %m, metadata !"fpexcept.ignore") #0
+  %conv3 = tail call i64 @llvm.experimental.constrained.fptosi.i64.f64(double %m, metadata !"fpexcept.ignore") #0
+  %conv4 = tail call i64 @llvm.experimental.constrained.fptoui.i64.f64(double %m, metadata !"fpexcept.ignore") #0
+  store volatile i32 %conv1, i32* %addr1, align 4
+  store volatile i32 %conv2, i32* %addr1, align 4
+  store volatile i64 %conv3, i64* %addr2, align 8
+  store volatile i64 %conv4, i64* %addr2, align 8
+  ret void
+}
+
+define void @fptoint_nofpexcept_f32(float %m, i32* %addr1, i64* %addr2) {
+; MIR-LABEL: name: fptoint_nofpexcept_f32
+; MIR: renamable $f{{[0-9]+}} = nofpexcept XSCVDPSXWS
+; MIR: renamable $f{{[0-9]+}} = nofpexcept XSCVDPUXWS
+; MIR: renamable $f{{[0-9]+}} = nofpexcept XSCVDPSXDS
+; MIR: renamable $f{{[0-9]+}} = nofpexcept XSCVDPUXDS
+entry:
+  %conv1 = tail call i32 @llvm.experimental.constrained.fptosi.i32.f32(float %m, metadata !"fpexcept.ignore") #0
+  %conv2 = tail call i32 @llvm.experimental.constrained.fptoui.i32.f32(float %m, metadata !"fpexcept.ignore") #0
+  %conv3 = tail call i64 @llvm.experimental.constrained.fptosi.i64.f32(float %m, metadata !"fpexcept.ignore") #0
+  %conv4 = tail call i64 @llvm.experimental.constrained.fptoui.i64.f32(float %m, metadata !"fpexcept.ignore") #0
+  store volatile i32 %conv1, i32* %addr1, align 4
+  store volatile i32 %conv2, i32* %addr1, align 4
+  store volatile i64 %conv3, i64* %addr2, align 8
+  store volatile i64 %conv4, i64* %addr2, align 8
+  ret void
+}
+
+define void @inttofp_nofpexcept_i32(i32 %m, float* %addr1, double* %addr2) {
+; MIR-LABEL: name: inttofp_nofpexcept_i32
+; MIR: renamable $f{{[0-9]+}} = nofpexcept XSCVSXDSP
+; MIR: renamable $f{{[0-9]+}} = nofpexcept XSCVUXDSP
+; MIR: renamable $f{{[0-9]+}} = nofpexcept XSCVSXDDP
+; MIR: renamable $f{{[0-9]+}} = nofpexcept XSCVUXDDP
+entry:
+  %conv1 = tail call float  @llvm.experimental.constrained.sitofp.f32.i32(i32 %m, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
+  %conv2 = tail call float  @llvm.experimental.constrained.uitofp.f32.i32(i32 %m, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
+  %conv3 = tail call double @llvm.experimental.constrained.sitofp.f64.i32(i32 %m, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
+  %conv4 = tail call double @llvm.experimental.constrained.uitofp.f64.i32(i32 %m, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
+  store volatile float  %conv1, float*  %addr1, align 4
+  store volatile float  %conv2, float*  %addr1, align 4
+  store volatile double %conv3, double* %addr2, align 8
+  store volatile double %conv4, double* %addr2, align 8
+  ret void
+}
+
+define void @inttofp_nofpexcept_i64(i64 %m, float* %addr1, double* %addr2) {
+; MIR-LABEL: name: inttofp_nofpexcept_i64
+; MIR: renamable $f{{[0-9]+}} = nofpexcept XSCVSXDSP
+; MIR: renamable $f{{[0-9]+}} = nofpexcept XSCVUXDSP
+; MIR: renamable $f{{[0-9]+}} = nofpexcept XSCVSXDDP
+; MIR: renamable $f{{[0-9]+}} = nofpexcept XSCVUXDDP
+entry:
+  %conv1 = tail call float  @llvm.experimental.constrained.sitofp.f32.i64(i64 %m, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
+  %conv2 = tail call float  @llvm.experimental.constrained.uitofp.f32.i64(i64 %m, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
+  %conv3 = tail call double @llvm.experimental.constrained.sitofp.f64.i64(i64 %m, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
+  %conv4 = tail call double @llvm.experimental.constrained.uitofp.f64.i64(i64 %m, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
+  store volatile float  %conv1, float*  %addr1, align 4
+  store volatile float  %conv2, float*  %addr1, align 4
+  store volatile double %conv3, double* %addr2, align 8
+  store volatile double %conv4, double* %addr2, align 8
+  ret void
+}
+
+define <2 x double> @inttofp_nofpexcept_vec(<2 x i16> %m) {
+; MIR-LABEL: name: inttofp_nofpexcept_vec
+; MIR: renamable $v{{[0-9]+}} = nofpexcept XVCVSXDDP
+entry:
+  %conv = tail call <2 x double> @llvm.experimental.constrained.sitofp.v2f64.v2i16(<2 x i16> %m, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
+  ret <2 x double> %conv
+}
+
+declare <2 x double> @llvm.experimental.constrained.sitofp.v2f64.v2i16(<2 x i16>, metadata, metadata)
+
 attributes #0 = { strictfp }


        


More information about the llvm-commits mailing list