Skip to content
Browse files

Disable some unsafe-fp-math DAG-combine transformation after legaliza…

…tion.

For instance, following transformation will be disabled:
    x + x + x => 3.0f * x;

The problem of these transformations is that it introduces a FP constant, which
following Instruction-Selection pass cannot handle.

Reviewed by Nadav, thanks a lot!

rdar://13445387


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@177933 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information...
1 parent 3800f57 commit 1cd1d02141788b212e185d190b4c358e47cc74b4 Shuxin Yang committed Mar 25, 2013
Showing with 31 additions and 5 deletions.
  1. +17 −5 lib/CodeGen/SelectionDAG/DAGCombiner.cpp
  2. +14 −0 test/CodeGen/X86/dagcombine_unsafe_math.ll
View
22 lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -5835,14 +5835,25 @@ SDValue DAGCombiner::visitFADD(SDNode *N) {
DAG.getNode(ISD::FADD, N->getDebugLoc(), VT,
N0.getOperand(1), N1));
+ // No FP constant should be created after legalization as Instruction
+ // Selection pass has hard time in dealing with FP constant.
+ //
+ // We don't need test this condition for transformation like following, as
+ // the DAG being transformed implies it is legal to take FP constant as
+ // operand.
+ //
+ // (fadd (fmul c, x), x) -> (fmul c+1, x)
+ //
+ bool AllowNewFpConst = (Level < AfterLegalizeDAG);
+
// If allow, fold (fadd (fneg x), x) -> 0.0
- if (DAG.getTarget().Options.UnsafeFPMath &&
+ if (AllowNewFpConst && DAG.getTarget().Options.UnsafeFPMath &&
N0.getOpcode() == ISD::FNEG && N0.getOperand(0) == N1) {
return DAG.getConstantFP(0.0, VT);
}
// If allow, fold (fadd x, (fneg x)) -> 0.0
- if (DAG.getTarget().Options.UnsafeFPMath &&
+ if (AllowNewFpConst && DAG.getTarget().Options.UnsafeFPMath &&
N1.getOpcode() == ISD::FNEG && N1.getOperand(0) == N0) {
return DAG.getConstantFP(0.0, VT);
}
@@ -5944,7 +5955,7 @@ SDValue DAGCombiner::visitFADD(SDNode *N) {
}
}
- if (N0.getOpcode() == ISD::FADD) {
+ if (N0.getOpcode() == ISD::FADD && AllowNewFpConst) {
ConstantFPSDNode *CFP = dyn_cast<ConstantFPSDNode>(N0.getOperand(0));
// (fadd (fadd x, x), x) -> (fmul 3.0, x)
if (!CFP && N0.getOperand(0) == N0.getOperand(1) &&
@@ -5954,7 +5965,7 @@ SDValue DAGCombiner::visitFADD(SDNode *N) {
}
}
- if (N1.getOpcode() == ISD::FADD) {
+ if (N1.getOpcode() == ISD::FADD && AllowNewFpConst) {
ConstantFPSDNode *CFP10 = dyn_cast<ConstantFPSDNode>(N1.getOperand(0));
// (fadd x, (fadd x, x)) -> (fmul 3.0, x)
if (!CFP10 && N1.getOperand(0) == N1.getOperand(1) &&
@@ -5965,7 +5976,8 @@ SDValue DAGCombiner::visitFADD(SDNode *N) {
}
// (fadd (fadd x, x), (fadd x, x)) -> (fmul 4.0, x)
- if (N0.getOpcode() == ISD::FADD && N1.getOpcode() == ISD::FADD &&
+ if (AllowNewFpConst &&
+ N0.getOpcode() == ISD::FADD && N1.getOpcode() == ISD::FADD &&
N0.getOperand(0) == N0.getOperand(1) &&
N1.getOperand(0) == N1.getOperand(1) &&
N0.getOperand(0) == N1.getOperand(0)) {
View
14 test/CodeGen/X86/dagcombine_unsafe_math.ll
@@ -40,3 +40,17 @@ define float @test4(float %x, float %y) {
; CHECK: test4
; CHECK: vaddss
}
+
+; rdar://13445387
+; "x + x + x => 3.0 * x" should be disabled after legalization because
+; Instruction-Selection dosen't know how to handle "3.0"
+;
+define float @test5() {
+ %mul.i.i151 = fmul <4 x float> zeroinitializer, zeroinitializer
+ %vecext.i8.i152 = extractelement <4 x float> %mul.i.i151, i32 1
+ %vecext1.i9.i153 = extractelement <4 x float> %mul.i.i151, i32 0
+ %add.i10.i154 = fadd float %vecext1.i9.i153, %vecext.i8.i152
+ %vecext.i7.i155 = extractelement <4 x float> %mul.i.i151, i32 2
+ %add.i.i156 = fadd float %vecext.i7.i155, %add.i10.i154
+ ret float %add.i.i156
+}

0 comments on commit 1cd1d02

Please sign in to comment.
Something went wrong with that request. Please try again.