[llvm] 5515263 - [InstCombine] Fold and of two ranges differing by mask

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Fri Apr 29 03:01:45 PDT 2022


Author: Nikita Popov
Date: 2022-04-29T12:01:38+02:00
New Revision: 5515263e4462b4bf39184f6a0e24964b4519eae4

URL: https://github.com/llvm/llvm-project/commit/5515263e4462b4bf39184f6a0e24964b4519eae4
DIFF: https://github.com/llvm/llvm-project/commit/5515263e4462b4bf39184f6a0e24964b4519eae4.diff

LOG: [InstCombine] Fold and of two ranges differing by mask

This is the de Morgan conjugated variant of the existing fold for
ors. Implement this by switching the range code to always work
on ors and perform invert operands at the start and end. This makes
reasoning easier and makes the extension more obviosuly correct.

Added: 
    

Modified: 
    llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
    llvm/test/Transforms/InstCombine/and-or-icmps.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index 4f53813d34bb..9963c692a5c7 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -1187,23 +1187,20 @@ static Value *foldAndOrOfICmpsUsingRanges(
   if (V1 != V2)
     return nullptr;
 
-  ConstantRange CR1 = ConstantRange::makeExactICmpRegion(Pred1, C1);
+  ConstantRange CR1 = ConstantRange::makeExactICmpRegion(
+      IsAnd ? ICmpInst::getInversePredicate(Pred1) : Pred1, C1);
   if (Offset1)
     CR1 = CR1.subtract(*Offset1);
 
-  ConstantRange CR2 = ConstantRange::makeExactICmpRegion(Pred2, C2);
+  ConstantRange CR2 = ConstantRange::makeExactICmpRegion(
+      IsAnd ? ICmpInst::getInversePredicate(Pred2) : Pred2, C2);
   if (Offset2)
     CR2 = CR2.subtract(*Offset2);
 
   Type *Ty = V1->getType();
   Value *NewV = V1;
-  Optional<ConstantRange> CR =
-      IsAnd ? CR1.exactIntersectWith(CR2) : CR1.exactUnionWith(CR2);
+  Optional<ConstantRange> CR = CR1.exactUnionWith(CR2);
   if (!CR) {
-    // TODO: Support and.
-    if (IsAnd)
-      return nullptr;
-
     if (!BothHaveOneUse || CR1.isWrappedSet() || CR2.isWrappedSet())
       return nullptr;
 
@@ -1220,6 +1217,9 @@ static Value *foldAndOrOfICmpsUsingRanges(
     NewV = Builder.CreateAnd(NewV, ConstantInt::get(Ty, ~LowerDiff));
   }
 
+  if (IsAnd)
+    CR = CR->inverse();
+
   CmpInst::Predicate NewPred;
   APInt NewC, Offset;
   CR->getEquivalentICmp(NewPred, NewC, Offset);

diff  --git a/llvm/test/Transforms/InstCombine/and-or-icmps.ll b/llvm/test/Transforms/InstCombine/and-or-icmps.ll
index 28651230a5c8..c85446c5e5f3 100644
--- a/llvm/test/Transforms/InstCombine/and-or-icmps.ll
+++ b/llvm/test/Transforms/InstCombine/and-or-icmps.ll
@@ -1183,12 +1183,10 @@ define i1 @and_ranges_signed_pred(i64 %x) {
 
 define i1 @and_two_ranges_to_mask_and_range(i8 %c)  {
 ; CHECK-LABEL: @and_two_ranges_to_mask_and_range(
-; CHECK-NEXT:    [[TMP1:%.*]] = add i8 [[C:%.*]], -123
-; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i8 [[TMP1]], -26
-; CHECK-NEXT:    [[TMP2:%.*]] = add i8 [[C]], -91
-; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i8 [[TMP2]], -26
-; CHECK-NEXT:    [[AND:%.*]] = and i1 [[CMP1]], [[CMP2]]
-; CHECK-NEXT:    ret i1 [[AND]]
+; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[C:%.*]], -33
+; CHECK-NEXT:    [[TMP2:%.*]] = add i8 [[TMP1]], -91
+; CHECK-NEXT:    [[TMP3:%.*]] = icmp ult i8 [[TMP2]], -26
+; CHECK-NEXT:    ret i1 [[TMP3]]
 ;
   %c.off = add i8 %c, -97
   %cmp1 = icmp ugt i8 %c.off, 25
@@ -1234,11 +1232,9 @@ define i1 @and_two_ranges_to_mask_and_range_
diff erent_sizes(i8 %c)  {
 
 define i1 @and_two_ranges_to_mask_and_range_no_add_on_one_range(i16 %x) {
 ; CHECK-LABEL: @and_two_ranges_to_mask_and_range_no_add_on_one_range(
-; CHECK-NEXT:    [[CMP1:%.*]] = icmp ugt i16 [[X:%.*]], 11
-; CHECK-NEXT:    [[TMP1:%.*]] = add i16 [[X]], -28
-; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i16 [[TMP1]], -12
-; CHECK-NEXT:    [[AND:%.*]] = and i1 [[CMP1]], [[TMP2]]
-; CHECK-NEXT:    ret i1 [[AND]]
+; CHECK-NEXT:    [[TMP1:%.*]] = and i16 [[X:%.*]], -20
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp ugt i16 [[TMP1]], 11
+; CHECK-NEXT:    ret i1 [[TMP2]]
 ;
   %cmp1 = icmp uge i16 %x, 12
   %cmp2 = icmp ult i16 %x, 16


        


More information about the llvm-commits mailing list