[llvm] r239167 - DAGCombiner: don't duplicate (fmul x, c) in visitFNEG if fneg is free
Fiona Glaser
escha at apple.com
Fri Jun 5 10:52:34 PDT 2015
Author: escha
Date: Fri Jun 5 12:52:34 2015
New Revision: 239167
URL: http://llvm.org/viewvc/llvm-project?rev=239167&view=rev
Log:
DAGCombiner: don't duplicate (fmul x, c) in visitFNEG if fneg is free
For targets with a free fneg, this fold is always a net loss if it
ends up duplicating the multiply, so definitely avoid it.
This might be true for some targets without a free fneg too, but
I'll leave that for future investigation.
Modified:
llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
llvm/trunk/test/CodeGen/R600/fmul.ll
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=239167&r1=239166&r2=239167&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Fri Jun 5 12:52:34 2015
@@ -8781,7 +8781,8 @@ SDValue DAGCombiner::visitFNEG(SDNode *N
}
// (fneg (fmul c, x)) -> (fmul -c, x)
- if (N0.getOpcode() == ISD::FMUL) {
+ if (N0.getOpcode() == ISD::FMUL &&
+ (N0.getNode()->hasOneUse() || !TLI.isFNegFree(VT))) {
ConstantFPSDNode *CFP1 = dyn_cast<ConstantFPSDNode>(N0.getOperand(1));
if (CFP1) {
APFloat CVal = CFP1->getValueAPF();
Modified: llvm/trunk/test/CodeGen/R600/fmul.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/R600/fmul.ll?rev=239167&r1=239166&r2=239167&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/R600/fmul.ll (original)
+++ llvm/trunk/test/CodeGen/R600/fmul.ll Fri Jun 5 12:52:34 2015
@@ -73,4 +73,20 @@ define void @test_mul_2_k_inv(float addr
ret void
}
+; There should be three multiplies here; %a should be used twice (once
+; negated), not duplicated into mul x, 5.0 and mul x, -5.0.
+; FUNC-LABEL: {{^}}test_mul_twouse:
+; SI: v_mul_f32
+; SI: v_mul_f32
+; SI: v_mul_f32
+; SI-NOT: v_mul_f32
+define void @test_mul_twouse(float addrspace(1)* %out, float %x, float %y) #0 {
+ %a = fmul float %x, 5.0
+ %b = fsub float -0.0, %a
+ %c = fmul float %b, %y
+ %d = fmul float %c, %a
+ store float %d, float addrspace(1)* %out
+ ret void
+}
+
attributes #0 = { "less-precise-fpmad"="true" "no-infs-fp-math"="true" "no-nans-fp-math"="true" "unsafe-fp-math"="true" }
More information about the llvm-commits
mailing list