[llvm] r344237 - [InstCombine] Demand bits of UMax

David Green via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 11 04:04:10 PDT 2018


Author: dmgreen
Date: Thu Oct 11 04:04:09 2018
New Revision: 344237

URL: http://llvm.org/viewvc/llvm-project?rev=344237&view=rev
Log:
[InstCombine] Demand bits of UMax

Use the demanded bits of umax(A,C) to prove we can just use A so long as the
lowest non-zero bit of DemandMask is higher than the highest non-zero bit of C

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

Modified:
    llvm/trunk/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
    llvm/trunk/test/Transforms/InstCombine/minmax-demandbits.ll

Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp?rev=344237&r1=344236&r2=344237&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp Thu Oct 11 04:04:09 2018
@@ -314,11 +314,22 @@ Value *InstCombiner::SimplifyDemandedUse
     Known.One  = std::move(IKnownOne);
     break;
   }
-  case Instruction::Select:
-    // If this is a select as part of a min/max pattern, don't simplify any
-    // further in case we break the structure.
+  case Instruction::Select: {
     Value *LHS, *RHS;
-    if (matchSelectPattern(I, LHS, RHS).Flavor != SPF_UNKNOWN)
+    SelectPatternFlavor SPF = matchSelectPattern(I, LHS, RHS).Flavor;
+    if (SPF == SPF_UMAX) {
+      // UMax(A, C) == A if ...
+      // The lowest non-zero bit of DemandMask is higher than the highest
+      // non-zero bit of C.
+      const APInt *C;
+      unsigned CTZ = DemandedMask.countTrailingZeros();
+      if (match(RHS, m_APInt(C)) && CTZ >= C->getActiveBits())
+        return LHS;
+    }
+
+    // If this is a select as part of any other min/max pattern, don't simplify
+    // any further in case we break the structure.
+    if (SPF != SPF_UNKNOWN)
       return nullptr;
 
     if (SimplifyDemandedBits(I, 2, DemandedMask, RHSKnown, Depth + 1) ||
@@ -336,6 +347,7 @@ Value *InstCombiner::SimplifyDemandedUse
     Known.One = RHSKnown.One & LHSKnown.One;
     Known.Zero = RHSKnown.Zero & LHSKnown.Zero;
     break;
+  }
   case Instruction::ZExt:
   case Instruction::Trunc: {
     unsigned SrcBitWidth = I->getOperand(0)->getType()->getScalarSizeInBits();

Modified: llvm/trunk/test/Transforms/InstCombine/minmax-demandbits.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/minmax-demandbits.ll?rev=344237&r1=344236&r2=344237&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/minmax-demandbits.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/minmax-demandbits.ll Thu Oct 11 04:04:09 2018
@@ -4,9 +4,7 @@
 
 define i32 @and_umax_less(i32 %A) {
 ; CHECK-LABEL: @and_umax_less(
-; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i32 [[A:%.*]], 31
-; CHECK-NEXT:    [[L1:%.*]] = select i1 [[TMP1]], i32 [[A]], i32 31
-; CHECK-NEXT:    [[X:%.*]] = and i32 [[L1]], -32
+; CHECK-NEXT:    [[X:%.*]] = and i32 [[A:%.*]], -32
 ; CHECK-NEXT:    ret i32 [[X]]
 ;
   %l0 = icmp ugt i32 31, %A
@@ -17,9 +15,7 @@ define i32 @and_umax_less(i32 %A) {
 
 define i32 @and_umax_muchless(i32 %A) {
 ; CHECK-LABEL: @and_umax_muchless(
-; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i32 [[A:%.*]], 12
-; CHECK-NEXT:    [[L1:%.*]] = select i1 [[TMP1]], i32 [[A]], i32 12
-; CHECK-NEXT:    [[X:%.*]] = and i32 [[L1]], -32
+; CHECK-NEXT:    [[X:%.*]] = and i32 [[A:%.*]], -32
 ; CHECK-NEXT:    ret i32 [[X]]
 ;
   %l0 = icmp ugt i32 12, %A
@@ -43,9 +39,7 @@ define i32 @and_umax_more(i32 %A) {
 
 define i32 @shr_umax(i32 %A) {
 ; CHECK-LABEL: @shr_umax(
-; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i32 [[A:%.*]], 15
-; CHECK-NEXT:    [[L1:%.*]] = select i1 [[TMP1]], i32 [[A]], i32 15
-; CHECK-NEXT:    [[X:%.*]] = lshr i32 [[L1]], 4
+; CHECK-NEXT:    [[X:%.*]] = lshr i32 [[A:%.*]], 4
 ; CHECK-NEXT:    ret i32 [[X]]
 ;
   %l0 = icmp ugt i32 15, %A
@@ -80,9 +74,7 @@ define i8 @t_0_10(i8 %A) {
 
 define i8 @t_1_10(i8 %A) {
 ; CHECK-LABEL: @t_1_10(
-; CHECK-NEXT:    [[L2:%.*]] = icmp ugt i8 [[A:%.*]], 1
-; CHECK-NEXT:    [[L1:%.*]] = select i1 [[L2]], i8 [[A]], i8 1
-; CHECK-NEXT:    [[X:%.*]] = and i8 [[L1]], 10
+; CHECK-NEXT:    [[X:%.*]] = and i8 [[A:%.*]], 10
 ; CHECK-NEXT:    ret i8 [[X]]
 ;
   %l2 = icmp ugt i8 %A, 1
@@ -93,9 +85,7 @@ define i8 @t_1_10(i8 %A) {
 
 define i8 @t_2_4(i8 %A) {
 ; CHECK-LABEL: @t_2_4(
-; CHECK-NEXT:    [[L2:%.*]] = icmp ugt i8 [[A:%.*]], 2
-; CHECK-NEXT:    [[L1:%.*]] = select i1 [[L2]], i8 [[A]], i8 2
-; CHECK-NEXT:    [[X:%.*]] = and i8 [[L1]], 4
+; CHECK-NEXT:    [[X:%.*]] = and i8 [[A:%.*]], 4
 ; CHECK-NEXT:    ret i8 [[X]]
 ;
   %l2 = icmp ugt i8 %A, 2
@@ -106,9 +96,7 @@ define i8 @t_2_4(i8 %A) {
 
 define i8 @t_2_192(i8 %A) {
 ; CHECK-LABEL: @t_2_192(
-; CHECK-NEXT:    [[L2:%.*]] = icmp ugt i8 [[A:%.*]], 2
-; CHECK-NEXT:    [[L1:%.*]] = select i1 [[L2]], i8 [[A]], i8 2
-; CHECK-NEXT:    [[X:%.*]] = and i8 [[L1]], -64
+; CHECK-NEXT:    [[X:%.*]] = and i8 [[A:%.*]], -64
 ; CHECK-NEXT:    ret i8 [[X]]
 ;
   %l2 = icmp ugt i8 %A, 2
@@ -119,9 +107,7 @@ define i8 @t_2_192(i8 %A) {
 
 define i8 @t_2_63_or(i8 %A) {
 ; CHECK-LABEL: @t_2_63_or(
-; CHECK-NEXT:    [[L2:%.*]] = icmp ugt i8 [[A:%.*]], 2
-; CHECK-NEXT:    [[L1:%.*]] = select i1 [[L2]], i8 [[A]], i8 2
-; CHECK-NEXT:    [[X:%.*]] = or i8 [[L1]], 63
+; CHECK-NEXT:    [[X:%.*]] = or i8 [[A:%.*]], 63
 ; CHECK-NEXT:    ret i8 [[X]]
 ;
   %l2 = icmp ugt i8 %A, 2




More information about the llvm-commits mailing list