Index: lib/Transforms/InstCombine/InstCombineMulDivRem.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombineMulDivRem.cpp +++ lib/Transforms/InstCombine/InstCombineMulDivRem.cpp @@ -625,6 +625,13 @@ return RI; } + // (fmul X, 2.0) --> (fadd X, X) + if (match(Op1, m_SpecificFP(+2.0))) { + Instruction *RI = BinaryOperator::CreateFAdd(Op0, Op0); + RI->copyFastMathFlags(&I); + return RI; + } + Constant *C = cast(Op1); if (AllowReassociate && isFiniteNonZeroFp(C)) { // Let MDC denote an expression in one of these forms: Index: test/Transforms/InstCombine/fast-math.ll =================================================================== --- test/Transforms/InstCombine/fast-math.ll +++ test/Transforms/InstCombine/fast-math.ll @@ -243,7 +243,7 @@ define float @fmul2_disable(float %f1) { %div = fdiv fast float 1.000000e+00, %f1 store float %div, float* @fmul2_external - %mul = fmul fast float %div, 2.000000e+00 + %mul = fmul fast float %div, 3.000000e+00 ret float %mul ; CHECK-LABEL: @fmul2_disable ; CHECK: store Index: test/Transforms/InstCombine/fmul.ll =================================================================== --- test/Transforms/InstCombine/fmul.ll +++ test/Transforms/InstCombine/fmul.ll @@ -124,6 +124,36 @@ ; CHECK: fadd fast float } +; X * 2.0 => X + X +define float @test12(float %x) { + %mul = fmul float %x, 2.0 + ret float %mul + +; CHECK-LABEL: @test12( +; CHECK: fadd float %x, %x +; CHECK: ret +} + +; X * 2.0 => X + X (w/fast flag) +define float @test13(float %x) { + %mul = fmul fast float %x, 2.0 + ret float %mul + +; CHECK-LABEL: @test13( +; CHECK: fadd fast float %x, %x +; CHECK: ret +} + +; Check to make sure fadd X, X is the canonical form. +define float @test14(float %x) { + %add = fadd float %x, %x + ret float %add + +; CHECK-LABEL: @test14( +; CHECK: fadd float %x, %x +; CHECK: ret +} + ; PR21126: http://llvm.org/bugs/show_bug.cgi?id=21126 ; With unsafe/fast math, sqrt(X) * sqrt(X) is just X. declare double @llvm.sqrt.f64(double) Index: test/Transforms/InstCombine/fold-fops-into-selects.ll =================================================================== --- test/Transforms/InstCombine/fold-fops-into-selects.ll +++ test/Transforms/InstCombine/fold-fops-into-selects.ll @@ -32,11 +32,11 @@ define float @test4(i1 %A, float %B) { EntryBlock: %cf = select i1 %A, float 1.000000e+00, float %B - %op = fmul float 2.000000e+00, %cf + %op = fmul float 3.000000e+00, %cf ret float %op ; CHECK-LABEL: @test4( -; CHECK: [[OP:%.*]] = fmul float %B, 2.000000e+00 -; CHECK: select i1 %A, float 2.000000e+00, float [[OP]] +; CHECK: [[OP:%.*]] = fmul float %B, 3.000000e+00 +; CHECK: select i1 %A, float 3.000000e+00, float [[OP]] } define float @test5(i1 %A, float %B) {