[DAGCombiner] refactor FP->int->FP folds; NFC
authorSanjay Patel <spatel@rotateright.com>
Thu, 26 Apr 2018 15:20:18 +0000 (15:20 +0000)
committerSanjay Patel <spatel@rotateright.com>
Thu, 26 Apr 2018 15:20:18 +0000 (15:20 +0000)
As discussed in the post-review comments for rL330437,
we need to guard this fold to allow existing code to
keep working with the undefined behavior that they've
come to rely on.

That would mean duplicating more code than we already
have, so let's fix that first.

llvm-svn: 330947

llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp

index e123e81..a897fb5 100644 (file)
@@ -10902,6 +10902,28 @@ SDValue DAGCombiner::visitFCOPYSIGN(SDNode *N) {
   return SDValue();
 }
 
+static SDValue foldFPToIntToFP(SDNode *N, SelectionDAG &DAG,
+                               const TargetLowering &TLI) {
+  // We only do this if the target has legal ftrunc. Otherwise, we'd likely be
+  // replacing casts with a libcall.
+  EVT VT = N->getValueType(0);
+  if (!TLI.isOperationLegal(ISD::FTRUNC, VT))
+    return SDValue();
+
+  // fptosi/fptoui round towards zero, so converting from FP to integer and
+  // back is the same as an 'ftrunc': [us]itofp (fpto[us]i X) --> ftrunc X
+  SDValue N0 = N->getOperand(0);
+  if (N->getOpcode() == ISD::SINT_TO_FP && N0.getOpcode() == ISD::FP_TO_SINT &&
+      N0.getOperand(0).getValueType() == VT)
+    return DAG.getNode(ISD::FTRUNC, SDLoc(N), VT, N0.getOperand(0));
+
+  if (N->getOpcode() == ISD::UINT_TO_FP && N0.getOpcode() == ISD::FP_TO_UINT &&
+      N0.getOperand(0).getValueType() == VT)
+    return DAG.getNode(ISD::FTRUNC, SDLoc(N), VT, N0.getOperand(0));
+
+  return SDValue();
+}
+
 SDValue DAGCombiner::visitSINT_TO_FP(SDNode *N) {
   SDValue N0 = N->getOperand(0);
   EVT VT = N->getValueType(0);
@@ -10953,14 +10975,8 @@ SDValue DAGCombiner::visitSINT_TO_FP(SDNode *N) {
     }
   }
 
-  // fptosi rounds towards zero, so converting from FP to integer and back is
-  // the same as an 'ftrunc': sitofp (fptosi X) --> ftrunc X
-  // We only do this if the target has legal ftrunc, otherwise we'd likely be
-  // replacing casts with a libcall.
-  if (N0.getOpcode() == ISD::FP_TO_SINT &&
-      N0.getOperand(0).getValueType() == VT &&
-      TLI.isOperationLegal(ISD::FTRUNC, VT))
-    return DAG.getNode(ISD::FTRUNC, SDLoc(N), VT, N0.getOperand(0));
+  if (SDValue FTrunc = foldFPToIntToFP(N, DAG, TLI))
+    return FTrunc;
 
   return SDValue();
 }
@@ -11001,14 +11017,8 @@ SDValue DAGCombiner::visitUINT_TO_FP(SDNode *N) {
     }
   }
 
-  // fptoui rounds towards zero, so converting from FP to integer and back is
-  // the same as an 'ftrunc': uitofp (fptoui X) --> ftrunc X
-  // We only do this if the target has legal ftrunc, otherwise we'd likely be
-  // replacing casts with a libcall.
-  if (N0.getOpcode() == ISD::FP_TO_UINT &&
-      N0.getOperand(0).getValueType() == VT &&
-      TLI.isOperationLegal(ISD::FTRUNC, VT))
-    return DAG.getNode(ISD::FTRUNC, SDLoc(N), VT, N0.getOperand(0));
+  if (SDValue FTrunc = foldFPToIntToFP(N, DAG, TLI))
+    return FTrunc;
 
   return SDValue();
 }