diff options
| author | Sanjay Patel <spatel@rotateright.com> | 2019-08-09 21:37:32 +0000 |
|---|---|---|
| committer | Sanjay Patel <spatel@rotateright.com> | 2019-08-09 21:37:32 +0000 |
| commit | 26b2c114515a8d011a952fe414ac92417298ea00 (patch) | |
| tree | cd545bd820a14edad8ae3414cca1c4c60cbda948 /llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | |
| parent | 0a317df59f2392a2f1ba84e5def398e109d2e47f (diff) | |
| download | bcm5719-llvm-26b2c114515a8d011a952fe414ac92417298ea00.tar.gz bcm5719-llvm-26b2c114515a8d011a952fe414ac92417298ea00.zip | |
[DAGCombiner] exclude x*2.0 from normal negation profitability rules
This is the codegen part of fixing:
https://bugs.llvm.org/show_bug.cgi?id=32939
Even with the optimal/canonical IR that is ideally created by D65954,
we would reverse that transform in DAGCombiner and end up with the same
asm on AArch64 or x86.
I see 2 options for trying to correct this:
1. Limit isNegatibleForFree() by special-casing the fmul pattern (this patch).
2. Avoid creating (fmul X, 2.0) in the 1st place by adding a special-case
transform to SelectionDAG::getNode() and/or SelectionDAGBuilder::visitFMul()
that matches the transform done by DAGCombiner.
This seems like the less intrusive patch, but if there's some other reason to
prefer 1 option over the other, we can change to the other option.
Differential Revision: https://reviews.llvm.org/D66016
llvm-svn: 368490
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp')
| -rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 5 |
1 files changed, 5 insertions, 0 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 63431d5b7ec..d9a77899ca3 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -868,6 +868,11 @@ static char isNegatibleForFree(SDValue Op, bool LegalOperations, Options, ForCodeSize, Depth + 1)) return V; + // Ignore X * 2.0 because that is expected to be canonicalized to X + X. + if (auto *C = isConstOrConstSplatFP(Op.getOperand(1))) + if (C->isExactlyValue(2.0) && Op.getOpcode() == ISD::FMUL) + return 0; + return isNegatibleForFree(Op.getOperand(1), LegalOperations, TLI, Options, ForCodeSize, Depth + 1); |

