Index: lib/Transforms/InstCombine/InstCombineAddSub.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombineAddSub.cpp +++ lib/Transforms/InstCombine/InstCombineAddSub.cpp @@ -1309,6 +1309,14 @@ SQ.getWithInstruction(&I))) return replaceInstUsesWith(I, V); + // (A*B)+(A*C) -> A*(B+C) etc + if (Value *V = SimplifyUsingDistributiveLaws(I)) { + if (Instruction *NewInstr = dyn_cast(V)) + NewInstr->setFastMathFlags(I.getFastMathFlags()); + + return replaceInstUsesWith(I, V); + } + if (isa(RHS)) if (Instruction *FoldedFAdd = foldOpWithConstantIntoOperand(I)) return FoldedFAdd; @@ -1724,6 +1732,13 @@ SQ.getWithInstruction(&I))) return replaceInstUsesWith(I, V); + // (A*B)-(A*C) -> A*(B-C) etc + if (Value *V = SimplifyUsingDistributiveLaws(I)) { + if (Instruction *NewInstr = dyn_cast(V)) + NewInstr->setFastMathFlags(I.getFastMathFlags()); + return replaceInstUsesWith(I, V); + } + // fsub nsz 0, X ==> fsub nsz -0.0, X if (I.getFastMathFlags().noSignedZeros() && match(Op0, m_Zero())) { // Subtraction from -0.0 is the canonical form of fneg. Index: lib/Transforms/InstCombine/InstCombineMulDivRem.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombineMulDivRem.cpp +++ lib/Transforms/InstCombine/InstCombineMulDivRem.cpp @@ -603,6 +603,13 @@ SQ.getWithInstruction(&I))) return replaceInstUsesWith(I, V); + if (Value *V = SimplifyUsingDistributiveLaws(I)) { + if (Instruction *NewInstr = dyn_cast(V)) + NewInstr->setFastMathFlags(I.getFastMathFlags()); + + return replaceInstUsesWith(I, V); + } + bool AllowReassociate = I.hasUnsafeAlgebra(); // Simplify mul instructions with a constant RHS. Index: test/Transforms/InstCombine/select_arithmetic.ll =================================================================== --- /dev/null +++ test/Transforms/InstCombine/select_arithmetic.ll @@ -0,0 +1,33 @@ +; RUN: opt < %s -instcombine -S | FileCheck %s + +target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" + +define float @test1(i1 zeroext) #0 { + %2 = select i1 %0, float 5.000000e+00, float 6.000000e+00 + %3 = select i1 %0, float 1.000000e+00, float 9.000000e+00 + %4 = fadd float %2, %3 + ret float %4 +; CHECK-LABEL: @test1( +; CHECK: %2 = select i1 %0, float 6.000000e+00, float 1.500000e+01 +; CHECK-NOT: fadd +; CHECK: ret float %2 +} + +define float @test2(i1 zeroext) #0 { + %2 = select i1 %0, float 5.000000e+00, float 6.000000e+00 + %3 = select i1 %0, float 1.000000e+00, float 9.000000e+00 + %4 = fmul float %2, %3 + ret float %4 +; CHECK-LABEL: @test2( +; CHECK: %2 = select i1 %0, float 5.000000e+00, float 5.400000e+01 +; CHECK-NOT: fmul +; CHECK: ret float %2 +} + +attributes #0 = { noinline nounwind ssp uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="penryn" "target-features"="+cx16,+fxsr,+mmx,+sse,+sse2,+sse3,+sse4.1,+ssse3,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } + +!llvm.module.flags = !{!0} +!llvm.ident = !{!1} + +!0 = !{i32 1, !"PIC Level", i32 2} +!1 = !{!"Apple LLVM version 9.0.0 (clang-900.0.32)"}