[llvm] r330098 - [DAGCombiner, PowerPC] allow X - (fpext(-Y) --> X + fpext(Y) with multiple uses

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Sun Apr 15 09:43:48 PDT 2018


Author: spatel
Date: Sun Apr 15 09:43:48 2018
New Revision: 330098

URL: http://llvm.org/viewvc/llvm-project?rev=330098&view=rev
Log:
[DAGCombiner, PowerPC] allow X - (fpext(-Y) --> X + fpext(Y) with multiple uses

This is a transform that I limited in instcombine in rL329821 because it was 
creating more instructions in IR when the cast has multiple uses.

But if the cast is free, then we can do the transform regardless of other
uses because it improves the potential throughput of the calculation by
removing a dependency on the fneg.

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

Modified:
    llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
    llvm/trunk/test/CodeGen/PowerPC/fsub-fneg.ll

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=330098&r1=330097&r2=330098&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Sun Apr 15 09:43:48 2018
@@ -667,13 +667,16 @@ static char isNegatibleForFree(SDValue O
   // fneg is removable even if it has multiple uses.
   if (Op.getOpcode() == ISD::FNEG) return 2;
 
-  // Don't allow anything with multiple uses.
-  if (!Op.hasOneUse()) return 0;
+  // Don't allow anything with multiple uses unless we know it is free.
+  EVT VT = Op.getValueType();
+  if (!Op.hasOneUse())
+    if (!(Op.getOpcode() == ISD::FP_EXTEND &&
+          TLI.isFPExtFree(VT, Op.getOperand(0).getValueType())))
+      return 0;
 
   // Don't recurse exponentially.
   if (Depth > 6) return 0;
 
-  EVT VT = Op.getValueType();
   switch (Op.getOpcode()) {
   default: return false;
   case ISD::ConstantFP: {
@@ -736,9 +739,6 @@ static SDValue GetNegatedExpression(SDVa
   // fneg is removable even if it has multiple uses.
   if (Op.getOpcode() == ISD::FNEG) return Op.getOperand(0);
 
-  // Don't allow anything with multiple uses.
-  assert(Op.hasOneUse() && "Unknown reuse!");
-
   assert(Depth <= 6 && "GetNegatedExpression doesn't match isNegatibleForFree");
 
   const SDNodeFlags Flags = Op.getNode()->getFlags();

Modified: llvm/trunk/test/CodeGen/PowerPC/fsub-fneg.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/fsub-fneg.ll?rev=330098&r1=330097&r2=330098&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/PowerPC/fsub-fneg.ll (original)
+++ llvm/trunk/test/CodeGen/PowerPC/fsub-fneg.ll Sun Apr 15 09:43:48 2018
@@ -1,16 +1,16 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
 ; RUN: llc -verify-machineinstrs -mtriple=powerpc64le < %s | FileCheck %s
 
-; FIXME: When fpext is free, we should look through it for optimizations
+; When fpext is free, we should look through it for optimizations
 ; even if it has multiple uses and produce an 'fadd' here.
 ; Y - (fpext(-X)) --> Y + fpext(X)
 
 define double @neg_ext_op1_extra_use(float %x, double %y) nounwind {
 ; CHECK-LABEL: neg_ext_op1_extra_use:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    fneg 0, 1
-; CHECK-NEXT:    xssubdp 1, 2, 0
-; CHECK-NEXT:    xsdivdp 1, 0, 1
+; CHECK-NEXT:    xsadddp 0, 2, 1
+; CHECK-NEXT:    fneg 13, 1
+; CHECK-NEXT:    xsdivdp 1, 13, 0
 ; CHECK-NEXT:    blr
   %t1 = fsub float -0.0, %x
   %t2 = fpext float %t1 to double




More information about the llvm-commits mailing list