Index: lib/Transforms/InstCombine/InstCombineAddSub.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombineAddSub.cpp +++ lib/Transforms/InstCombine/InstCombineAddSub.cpp @@ -1388,6 +1388,8 @@ } // select C, 0, B + select C, A, 0 -> select C, A, B + // select C, A1, B1 + select C, A2, B2 -> select C, (A1+A2), (B1+B2) + // iff {A1,A2,B1,B2} are all constants { Value *A1, *B1, *C1, *A2, *B2, *C2; if (match(LHS, m_Select(m_Value(C1), m_Value(A1), m_Value(B1))) && @@ -1401,6 +1403,17 @@ } else if (match(B1, m_AnyZero()) && match(A2, m_AnyZero())) { Z1 = dyn_cast(B1); B = B2; Z2 = dyn_cast(A2); A = A1; + } else if (isa(A1) && isa(A2) && + isa(B1) && isa(B2)) { + Value *V0 = Builder.CreateFAdd(A1, A2); + Value *V1 = Builder.CreateFAdd(B1, B2); + if (Instruction *I0 = dyn_cast(V0)) + I0->setFastMathFlags(I.getFastMathFlags()); + + if (Instruction *I1 = dyn_cast(V1)) + I1->setFastMathFlags(I.getFastMathFlags()); + + return SelectInst::Create(C, V0, V1); } if (Z1 && Z2 && @@ -1760,6 +1773,29 @@ } } + // select C, A1, B1 * select C, A2, B2 -> select C, (A1*A2), (B1*B2) + // iff {A1,A2,B1,B2} are all constants + { + Value *A1, *B1, *C1, *A2, *B2, *C2; + if (match(Op0, m_Select(m_Value(C1), m_Value(A1), m_Value(B1))) && + match(Op1, m_Select(m_Value(C2), m_Value(A2), m_Value(B2)))) { + if (C1 == C2) { + if (isa(A1) && isa(A2) && + isa(B1) && isa(B2)) { + Value *V0 = Builder.CreateFSub(A1, A2); + Value *V1 = Builder.CreateFSub(B1, B2); + if (Instruction *I0 = dyn_cast(V0)) + I0->setFastMathFlags(I.getFastMathFlags()); + + if (Instruction *I1 = dyn_cast(V1)) + I1->setFastMathFlags(I.getFastMathFlags()); + + return SelectInst::Create(C1, V0, V1); + } + } + } + } + if (I.hasUnsafeAlgebra()) { if (Value *V = FAddCombine(Builder).simplify(&I)) return replaceInstUsesWith(I, V); Index: lib/Transforms/InstCombine/InstCombineMulDivRem.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombineMulDivRem.cpp +++ lib/Transforms/InstCombine/InstCombineMulDivRem.cpp @@ -736,6 +736,29 @@ } } + // select C, A1, B1 * select C, A2, B2 -> select C, (A1*A2), (B1*B2) + // iff {A1,A2,B1,B2} are all constants + { + Value *A1, *B1, *C1, *A2, *B2, *C2; + if (match(Op0, m_Select(m_Value(C1), m_Value(A1), m_Value(B1))) && + match(Op1, m_Select(m_Value(C2), m_Value(A2), m_Value(B2)))) { + if (C1 == C2) { + if (isa(A1) && isa(A2) && + isa(B1) && isa(B2)) { + Value *V0 = Builder.CreateFMul(A1, A2); + Value *V1 = Builder.CreateFMul(B1, B2); + if (Instruction *I0 = dyn_cast(V0)) + I0->setFastMathFlags(I.getFastMathFlags()); + + if (Instruction *I1 = dyn_cast(V1)) + I1->setFastMathFlags(I.getFastMathFlags()); + + return SelectInst::Create(C1, V0, V1); + } + } + } + } + // (X*Y) * X => (X*X) * Y where Y != X // The purpose is two-fold: // 1) to form a power expression (of X). Index: test/Transforms/InstCombine/select_arithmetic.ll =================================================================== --- /dev/null +++ test/Transforms/InstCombine/select_arithmetic.ll @@ -0,0 +1,44 @@ +; 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 = fsub float %2, %3 + ret float %4 +; CHECK-LABEL: @test2( +; CHECK: %2 = select i1 %0, float 4.000000e+00, float -3.000000e+00 +; CHECK-NOT: fsub +; CHECK: ret float %2 +} + +define float @test3(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: @test3( +; 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)"}