forked from OSchip/llvm-project
[InstCombine] Gating select arithmetic optimization.
These changes faciliate positive behavior for arithmetic based select expressions that match its translation criteria, keeping code size gated to neutral or improved scenarios. Patch by Michael Berg <michael_c_berg@apple.com>! Differential Revision: https://reviews.llvm.org/D38263 llvm-svn: 314320
This commit is contained in:
parent
c032b2beb0
commit
d8b4b06f5d
|
@ -731,6 +731,7 @@ Value *InstCombiner::SimplifySelectsFeedingBinaryOp(BinaryOperator &I,
|
|||
Value *SI = nullptr;
|
||||
if (match(LHS, m_Select(m_Value(A), m_Value(B), m_Value(C))) &&
|
||||
match(RHS, m_Select(m_Specific(A), m_Value(D), m_Value(E)))) {
|
||||
bool SelectsHaveOneUse = LHS->hasOneUse() && RHS->hasOneUse();
|
||||
BuilderTy::FastMathFlagGuard Guard(Builder);
|
||||
if (isa<FPMathOperator>(&I))
|
||||
Builder.setFastMathFlags(I.getFastMathFlags());
|
||||
|
@ -739,9 +740,9 @@ Value *InstCombiner::SimplifySelectsFeedingBinaryOp(BinaryOperator &I,
|
|||
Value *V2 = SimplifyBinOp(Opcode, B, D, SQ.getWithInstruction(&I));
|
||||
if (V1 && V2)
|
||||
SI = Builder.CreateSelect(A, V2, V1);
|
||||
else if (V2)
|
||||
else if (V2 && SelectsHaveOneUse)
|
||||
SI = Builder.CreateSelect(A, V2, Builder.CreateBinOp(Opcode, C, E));
|
||||
else if (V1)
|
||||
else if (V1 && SelectsHaveOneUse)
|
||||
SI = Builder.CreateSelect(A, Builder.CreateBinOp(Opcode, B, D), V1);
|
||||
|
||||
if (SI)
|
||||
|
|
|
@ -3,17 +3,32 @@
|
|||
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
|
||||
|
||||
; Tests folding constants from two similar selects that feed a add
|
||||
define float @test1(i1 zeroext %arg) #0 {
|
||||
define float @test1a(i1 zeroext %arg) #0 {
|
||||
%tmp = select i1 %arg, float 5.000000e+00, float 6.000000e+00
|
||||
%tmp1 = select i1 %arg, float 1.000000e+00, float 9.000000e+00
|
||||
%tmp2 = fadd float %tmp, %tmp1
|
||||
ret float %tmp2
|
||||
; CHECK-LABEL: @test1(
|
||||
; CHECK-LABEL: @test1a(
|
||||
; CHECK: %tmp2 = select i1 %arg, float 6.000000e+00, float 1.500000e+01
|
||||
; CHECK-NOT: fadd
|
||||
; CHECK: ret float %tmp2
|
||||
}
|
||||
|
||||
; Tests folding multiple expression constants from similar selects that feed a adds
|
||||
define float @test1b(i1 zeroext %arg) #0 {
|
||||
%tmp = select i1 %arg, float 5.000000e+00, float 6.000000e+00
|
||||
%tmp1 = select i1 %arg, float 1.000000e+00, float 9.000000e+00
|
||||
%tmp2 = select i1 %arg, float 2.500000e-01, float 4.000000e+00
|
||||
%tmp3 = fadd float %tmp, %tmp1
|
||||
%tmp4 = fadd float %tmp2, %tmp1
|
||||
%tmp5 = fadd float %tmp4, %tmp3
|
||||
ret float %tmp5
|
||||
; CHECK-LABEL: @test1b(
|
||||
; CHECK: %tmp5 = select i1 %arg, float 7.250000e+00, float 2.800000e+01
|
||||
; CHECK-NOT: fadd
|
||||
; CHECK: ret float %tmp5
|
||||
}
|
||||
|
||||
; Tests folding constants from two similar selects that feed a sub
|
||||
define float @test2(i1 zeroext %arg) #0 {
|
||||
%tmp = select i1 %arg, float 5.000000e+00, float 6.000000e+00
|
||||
|
@ -38,3 +53,32 @@ define float @test3(i1 zeroext %arg) #0 {
|
|||
; CHECK: ret float %tmp2
|
||||
}
|
||||
|
||||
declare void @use_float(float)
|
||||
|
||||
; Tests folding constants if the selects have multiple uses but
|
||||
; we can fold away the binary op with a select.
|
||||
define float @test4(i1 zeroext %arg) #0 {
|
||||
%tmp = select i1 %arg, float 5.000000e+00, float 6.000000e+00
|
||||
%tmp1 = select i1 %arg, float 1.000000e+00, float 9.000000e+00
|
||||
%tmp2 = fmul float %tmp, %tmp1
|
||||
call void @use_float(float %tmp)
|
||||
ret float %tmp2
|
||||
; CHECK-LABEL: @test4(
|
||||
; CHECK: select i1 %arg, float 5.000000e+00, float 6.000000e+00
|
||||
; CHECK-NEXT: select i1 %arg, float 5.000000e+00, float 5.400000e+01
|
||||
; CHECK-NEXT: call void @use_float(float %tmp)
|
||||
; CHECK: ret float %tmp2
|
||||
}
|
||||
|
||||
; Tests not folding constants if we cannot fold away any of the selects.
|
||||
define float @test5(i1 zeroext %arg, float %div) {
|
||||
%tmp = select i1 %arg, float %div, float 5.000000e+00
|
||||
%mul = fmul contract float %tmp, %tmp
|
||||
call void @use_float(float %tmp)
|
||||
ret float %mul
|
||||
; CHECK-LABEL: @test5(
|
||||
; CHECK: [[TMP:%.*]] = select i1 %arg, float %div, float 5.000000e+00
|
||||
; CHECK-NEXT: [[MUL:%.*]] = fmul contract float [[TMP]], [[TMP]]
|
||||
; CHECK-NOT: fmul contract float %div, %div
|
||||
; CHECK: ret float [[MUL]]
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue