Fix issues with ISD::FNEG and ISD::FMA SDNodes where they would not be constant-folded
authorOwen Anderson <resistor@mac.com>
Sat, 2 Aug 2014 08:45:33 +0000 (08:45 +0000)
committerOwen Anderson <resistor@mac.com>
Sat, 2 Aug 2014 08:45:33 +0000 (08:45 +0000)
during DAGCombine in certain circumstances.  Unfortunately, the circumstances required
to trigger the issue seem to require a pretty specific interaction of DAGCombines,
and I haven't been able to find a testcase that reproduces on X86, ARM, or AArch64.
The functionality added here is replicated in essentially every other DAG combine,
so it seems pretty obviously correct.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@214622 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/SelectionDAG/DAGCombiner.cpp

index 445b4e0204306e3f6363db2e0337ce361a3028a7..8b1762a82ed99cd600850a63a4bebe6e59bcd6e1 100644 (file)
@@ -6893,6 +6893,14 @@ SDValue DAGCombiner::visitFMA(SDNode *N) {
   EVT VT = N->getValueType(0);
   SDLoc dl(N);
 
+
+  // Constant fold FMA.
+  if (isa<ConstantFPSDNode>(N0) &&
+      isa<ConstantFPSDNode>(N1) &&
+      isa<ConstantFPSDNode>(N2)) {
+    return DAG.getNode(ISD::FMA, dl, VT, N0, N1, N2);
+  }
+
   if (DAG.getTarget().Options.UnsafeFPMath) {
     if (N0CFP && N0CFP->isZero())
       return N2;
@@ -7293,6 +7301,10 @@ SDValue DAGCombiner::visitFNEG(SDNode *N) {
   SDValue N0 = N->getOperand(0);
   EVT VT = N->getValueType(0);
 
+  // Constant fold FNEG.
+  if (isa<ConstantFPSDNode>(N0))
+    return DAG.getNode(ISD::FNEG, SDLoc(N), VT, N->getOperand(0));
+
   if (VT.isVector()) {
     SDValue FoldedVOp = SimplifyVUnaryOp(N);
     if (FoldedVOp.getNode()) return FoldedVOp;