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,11 @@ } 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); + return SelectInst::Create(C, V0, V1); } if (Z1 && Z2 && Index: lib/Transforms/InstCombine/InstCombineMulDivRem.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombineMulDivRem.cpp +++ lib/Transforms/InstCombine/InstCombineMulDivRem.cpp @@ -736,6 +736,23 @@ } } + // 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); + 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_01.ll =================================================================== --- /dev/null +++ test/Transforms/InstCombine/select_arithmetic_01.ll @@ -0,0 +1,40 @@ +; RUN: opt < %s -instcombine -S | FileCheck %s + +target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" + +; Function Attrs: noinline nounwind ssp uwtable +define float @_Z16SelectArithmeticb(i1 zeroext) #0 { + %2 = alloca i8, align 1 + %3 = alloca float, align 4 + %4 = alloca float, align 4 + %5 = zext i1 %0 to i8 + store i8 %5, i8* %2, align 1 + %6 = load i8, i8* %2, align 1 + %7 = trunc i8 %6 to i1 + %8 = zext i1 %7 to i64 + %9 = select i1 %7, double 5.000000e+00, double 6.000000e+00 + %10 = fptrunc double %9 to float + store float %10, float* %3, align 4 + %11 = load i8, i8* %2, align 1 + %12 = trunc i8 %11 to i1 + %13 = zext i1 %12 to i64 + %14 = select i1 %12, double 1.000000e+00, double 9.000000e+00 + %15 = fptrunc double %14 to float + store float %15, float* %4, align 4 + %16 = load float, float* %3, align 4 + %17 = load float, float* %4, align 4 + %18 = fadd float %16, %17 + ret float %18 +; CHECK-LABEL: @_Z16SelectArithmeticb( +; CHECK: %2 = select i1 %0, float 6.000000e+00, float 1.500000e+01 +; CHECK-NOT: fadd +; 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)"} Index: test/Transforms/InstCombine/select_arithmetic_02.ll =================================================================== --- /dev/null +++ test/Transforms/InstCombine/select_arithmetic_02.ll @@ -0,0 +1,40 @@ +; RUN: opt < %s -instcombine -S | FileCheck %s + +target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" + +; Function Attrs: noinline nounwind ssp uwtable +define float @_Z16SelectArithmeticb(i1 zeroext) #0 { + %2 = alloca i8, align 1 + %3 = alloca float, align 4 + %4 = alloca float, align 4 + %5 = zext i1 %0 to i8 + store i8 %5, i8* %2, align 1 + %6 = load i8, i8* %2, align 1 + %7 = trunc i8 %6 to i1 + %8 = zext i1 %7 to i64 + %9 = select i1 %7, double 5.000000e+00, double 6.000000e+00 + %10 = fptrunc double %9 to float + store float %10, float* %3, align 4 + %11 = load i8, i8* %2, align 1 + %12 = trunc i8 %11 to i1 + %13 = zext i1 %12 to i64 + %14 = select i1 %12, double 1.000000e+00, double 9.000000e+00 + %15 = fptrunc double %14 to float + store float %15, float* %4, align 4 + %16 = load float, float* %3, align 4 + %17 = load float, float* %4, align 4 + %18 = fmul float %16, %17 + ret float %18 +; CHECK-LABEL: @_Z16SelectArithmeticb( +; 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)"}