[llvm] Simplify `(a % b) lt/ge (b-1)` into `(a % b) eq/ne (b-1)` (PR #72504)

via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 16 03:14:37 PST 2024


elhewaty wrote:

and for the following change
```
diff --git a/llvm/test/Transforms/InstCombine/modulo.ll b/llvm/test/Transforms/InstCombine/modulo.ll
index 2988c524faed..76e16651f4e3 100644
--- a/llvm/test/Transforms/InstCombine/modulo.ll
+++ b/llvm/test/Transforms/InstCombine/modulo.ll
@@ -4,7 +4,10 @@
 ; PR21929
 define i32 @modulo2(i32 %x) {
 ; CHECK-LABEL: @modulo2(
-; CHECK-NEXT:    [[RET_I:%.*]] = and i32 [[X:%.*]], 1
+; CHECK-NEXT:    [[REM_I:%.*]] = srem i32 [[X:%.*]], 2
+; CHECK-NEXT:    [[CMP_I:%.*]] = icmp eq i32 [[REM_I]], -1
+; CHECK-NEXT:    [[ADD_I:%.*]] = select i1 [[CMP_I]], i32 2, i32 0
+; CHECK-NEXT:    [[RET_I:%.*]] = add nsw i32 [[ADD_I]], [[REM_I]]
 ; CHECK-NEXT:    ret i32 [[RET_I]]
 ;
   %rem.i = srem i32 %x, 2
@@ -16,7 +19,10 @@ define i32 @modulo2(i32 %x) {
 
 define <2 x i32> @modulo2_vec(<2 x i32> %x) {
 ; CHECK-LABEL: @modulo2_vec(
-; CHECK-NEXT:    [[RET_I:%.*]] = and <2 x i32> [[X:%.*]], <i32 1, i32 1>
+; CHECK-NEXT:    [[REM_I:%.*]] = srem <2 x i32> [[X:%.*]], <i32 2, i32 2>
+; CHECK-NEXT:    [[CMP_I:%.*]] = icmp eq <2 x i32> [[REM_I]], <i32 -1, i32 -1>
+; CHECK-NEXT:    [[ADD_I:%.*]] = select <2 x i1> [[CMP_I]], <2 x i32> <i32 2, i32 2>, <2 x i32> zeroinitializer
+; CHECK-NEXT:    [[RET_I:%.*]] = add nsw <2 x i32> [[ADD_I]], [[REM_I]]
 ; CHECK-NEXT:    ret <2 x i32> [[RET_I]]
 ;
   %rem.i = srem <2 x i32> %x, <i32 2, i32 2>
```
the old optimization is one instruction `and`, but the patch replaces this instruction
with 3 instructions.



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


More information about the llvm-commits mailing list