[llvm] 0aabdad - [InstCombine] Combine code for and/or of icmps (NFC)

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 9 12:18:40 PST 2021


Author: Nikita Popov
Date: 2021-11-09T21:18:31+01:00
New Revision: 0aabdad1ef96d489d63933e47bf19bcc832239e8

URL: https://github.com/llvm/llvm-project/commit/0aabdad1ef96d489d63933e47bf19bcc832239e8
DIFF: https://github.com/llvm/llvm-project/commit/0aabdad1ef96d489d63933e47bf19bcc832239e8.diff

LOG: [InstCombine] Combine code for and/or of icmps (NFC)

The implementation for and/or is the same, apart from the choice
of exactIntersectWith() vs exactUnionWith(). Extract a common
function to make future extension easier.

Added: 
    

Modified: 
    llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index fbda801e73e7..9b9b0c0c9af3 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -1199,6 +1199,34 @@ static Value *foldAndOrOfICmpsWithConstEq(ICmpInst *Cmp0, ICmpInst *Cmp1,
   return Builder.CreateBinOp(Logic.getOpcode(), Cmp0, SubstituteCmp);
 }
 
+/// Fold (icmp Pred1 V1, C1) & (icmp Pred2 V2, C2)
+/// or   (icmp Pred1 V1, C1) | (icmp Pred2 V2, C2)
+/// into a single comparison using range-based reasoning.
+static Value *foldAndOrOfICmpsUsingRanges(
+    ICmpInst::Predicate Pred1, Value *V1, const APInt &C1,
+    ICmpInst::Predicate Pred2, Value *V2, const APInt &C2,
+    IRBuilderBase &Builder, bool IsAnd) {
+  if (V1 != V2)
+    return nullptr;
+
+  ConstantRange CR1 = ConstantRange::makeExactICmpRegion(Pred1, C1);
+  ConstantRange CR2 = ConstantRange::makeExactICmpRegion(Pred2, C2);
+  Optional<ConstantRange> CR =
+      IsAnd ? CR1.exactIntersectWith(CR2) : CR1.exactUnionWith(CR2);
+  if (!CR)
+    return nullptr;
+
+  CmpInst::Predicate NewPred;
+  APInt NewC, Offset;
+  CR->getEquivalentICmp(NewPred, NewC, Offset);
+
+  Type *Ty = V1->getType();
+  Value *NewV = V1;
+  if (Offset != 0)
+    NewV = Builder.CreateAdd(NewV, ConstantInt::get(Ty, Offset));
+  return Builder.CreateICmp(NewPred, NewV, ConstantInt::get(Ty, NewC));
+}
+
 /// Fold (icmp)&(icmp) if possible.
 Value *InstCombinerImpl::foldAndOfICmps(ICmpInst *LHS, ICmpInst *RHS,
                                         BinaryOperator &And) {
@@ -1317,28 +1345,9 @@ Value *InstCombinerImpl::foldAndOfICmps(ICmpInst *LHS, ICmpInst *RHS,
     }
   }
 
-  // From here on, we only handle:
-  //    (icmp1 A, C1) & (icmp2 A, C2) --> something simpler.
-  if (LHS0 != RHS0)
-    return nullptr;
-
-  ConstantRange CR1 =
-      ConstantRange::makeExactICmpRegion(PredL, LHSC->getValue());
-  ConstantRange CR2 =
-      ConstantRange::makeExactICmpRegion(PredR, RHSC->getValue());
-  Optional<ConstantRange> CR = CR1.exactIntersectWith(CR2);
-  if (!CR)
-    return nullptr;
-
-  CmpInst::Predicate Pred;
-  APInt NewRHS, Offset;
-  CR->getEquivalentICmp(Pred, NewRHS, Offset);
-
-  Type *Ty = LHS0->getType();
-  Value *NewLHS = LHS0;
-  if (Offset != 0)
-    NewLHS = Builder.CreateAdd(NewLHS, ConstantInt::get(Ty, Offset));
-  return Builder.CreateICmp(Pred, NewLHS, ConstantInt::get(Ty, NewRHS));
+  return foldAndOrOfICmpsUsingRanges(PredL, LHS0, LHSC->getValue(),
+                                     PredR, RHS0, RHSC->getValue(),
+                                     Builder, /* IsAnd */ true);
 }
 
 Value *InstCombinerImpl::foldLogicOfFCmps(FCmpInst *LHS, FCmpInst *RHS,
@@ -2462,28 +2471,9 @@ Value *InstCombinerImpl::foldOrOfICmps(ICmpInst *LHS, ICmpInst *RHS,
         return Builder.CreateICmpULE(LHS0, LHSC);
   }
 
-  // From here on, we only handle:
-  //    (icmp1 A, C1) | (icmp2 A, C2) --> something simpler.
-  if (LHS0 != RHS0)
-    return nullptr;
-
-  ConstantRange CR1 =
-      ConstantRange::makeExactICmpRegion(PredL, LHSC->getValue());
-  ConstantRange CR2 =
-      ConstantRange::makeExactICmpRegion(PredR, RHSC->getValue());
-  Optional<ConstantRange> CR = CR1.exactUnionWith(CR2);
-  if (!CR)
-    return nullptr;
-
-  CmpInst::Predicate Pred;
-  APInt NewRHS, Offset;
-  CR->getEquivalentICmp(Pred, NewRHS, Offset);
-
-  Type *Ty = LHS0->getType();
-  Value *NewLHS = LHS0;
-  if (Offset != 0)
-    NewLHS = Builder.CreateAdd(NewLHS, ConstantInt::get(Ty, Offset));
-  return Builder.CreateICmp(Pred, NewLHS, ConstantInt::get(Ty, NewRHS));
+  return foldAndOrOfICmpsUsingRanges(PredL, LHS0, LHSC->getValue(),
+                                     PredR, RHS0, RHSC->getValue(),
+                                     Builder, /* IsAnd */ false);
 }
 
 // FIXME: We use commutative matchers (m_c_*) for some, but not all, matches


        


More information about the llvm-commits mailing list