[llvm] r314320 - [InstCombine] Gating select arithmetic optimization.

Chad Rosier via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 27 10:16:51 PDT 2017


Author: mcrosier
Date: Wed Sep 27 10:16:51 2017
New Revision: 314320

URL: http://llvm.org/viewvc/llvm-project?rev=314320&view=rev
Log:
[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 at apple.com>!

Differential Revision: https://reviews.llvm.org/D38263

Modified:
    llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp
    llvm/trunk/test/Transforms/InstCombine/select_arithmetic.ll

Modified: llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp?rev=314320&r1=314319&r2=314320&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp Wed Sep 27 10:16:51 2017
@@ -731,6 +731,7 @@ Value *InstCombiner::SimplifySelectsFeed
   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::SimplifySelectsFeed
     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)

Modified: llvm/trunk/test/Transforms/InstCombine/select_arithmetic.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/select_arithmetic.ll?rev=314320&r1=314319&r2=314320&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/select_arithmetic.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/select_arithmetic.ll Wed Sep 27 10:16:51 2017
@@ -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]]
+}




More information about the llvm-commits mailing list