[llvm] Fold (a % b) lt/ge (b-1) where b is a power of 2 (PR #72504)

Yingwei Zheng via llvm-commits llvm-commits at lists.llvm.org
Sun Nov 19 00:12:15 PST 2023


================
@@ -6837,6 +6837,22 @@ Instruction *InstCombinerImpl::visitICmpInst(ICmpInst &I) {
     Changed = true;
   }
 
+  {
+    Value *X, *Y;
+    ICmpInst::Predicate Pred = I.getPredicate();
+    if ((Pred == ICmpInst::ICMP_SGE || Pred == ICmpInst::ICMP_SLT) &&
+        match(Op0, m_OneUse(m_SRem(m_Value(X), m_Value(Y)))) &&
+        match(Op1, m_OneUse(m_c_Add(m_Deferred(Y), m_AllOnes()))) &&
+        isKnownNonNegative(Y, DL, 0, Q.AC, Q.CxtI, Q.DT)) {
----------------
dtcxzyw wrote:

It cannot handle constant integers/splat vectors. 
```suggestion
        (match(Op1, m_OneUse(m_c_Add(m_Deferred(Y), m_AllOnes()))) &&
        isKnownNonNegative(Y, DL, 0, Q.AC, Q.CxtI, Q.DT)) ||
        (match(Y, m_APInt(*C)) && C->isNonNegative() && match(Op1, m_SpecificInt(*C - 1)))) {
```
Please add some tests with constant integers/splat vectors:
```
define i1 @test_srem_slt_constant(i32 %a) {
  %y = srem i32 %a, 512
  %cmp = icmp slt i32 %y, 511
  ret i1 %cmp
}
define i1 @test_srem_sge_constant(i32 %a) {
  %y = srem i32 %a, 512
  %cmp = icmp sge i32 %y, 511
  ret i1 %cmp
}
define <2 x i1> @test_srem_slt_constant_splat(<2 x i32> %a) {
  %y = srem <2 x i32> %a, <i32 512, i32 512>
  %cmp = icmp slt <2 x i32> %y, <i32 511, i32 511>
  ret <2 x i1> %cmp
}
define <2 x i1> @test_srem_sge_constant_splat(<2 x i32> %a) {
  %y = srem <2 x i32> %a, <i32 512, i32 512>
  %cmp = icmp sge <2 x i32> %y, <i32 511, i32 511>
  ret <2 x i1> %cmp
}
```


https://github.com/llvm/llvm-project/pull/72504


More information about the llvm-commits mailing list