[llvm] 902acde - [InstCombine] Optimize away certain additions using modular arithmetic
David Majnemer via llvm-commits
llvm-commits at lists.llvm.org
Mon Oct 28 15:52:34 PDT 2024
Author: David Majnemer
Date: 2024-10-28T22:51:35Z
New Revision: 902acde34198bb11cc758dcf3aee00eb1cb09ceb
URL: https://github.com/llvm/llvm-project/commit/902acde34198bb11cc758dcf3aee00eb1cb09ceb
DIFF: https://github.com/llvm/llvm-project/commit/902acde34198bb11cc758dcf3aee00eb1cb09ceb.diff
LOG: [InstCombine] Optimize away certain additions using modular arithmetic
We can turn:
```
%add = add i8 %arg, C1
%and = and i8 %add, C2
%cmp = icmp eq i1 %and, C3
```
into:
```
%and = and i8 %arg, C2
%cmp = icmp eq i1 %and, (C3 - C1) & C2
```
This is only worth doing if the sequence is the sole user of the addition
operation.
Added:
Modified:
llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
llvm/test/Transforms/InstCombine/and-compare.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index 338e9772c7cc08..6bb39cabb0988b 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -1976,6 +1976,22 @@ Instruction *InstCombinerImpl::foldICmpAndConstant(ICmpInst &Cmp,
return new ICmpInst(Pred, LShr, Constant::getNullValue(LShr->getType()));
}
+ // (icmp eq/ne (and (add A, Addend), Msk), C)
+ // -> (icmp eq/ne (and A, Msk), (and (sub C, Addend), Msk))
+ {
+ Value *A;
+ const APInt *Addend, *Msk;
+ if (match(And, m_And(m_OneUse(m_Add(m_Value(A), m_APInt(Addend))),
+ m_APInt(Msk))) &&
+ Msk->isMask() && C.ule(*Msk)) {
+ APInt NewComperand = (C - *Addend) & *Msk;
+ Value* MaskA = Builder.CreateAnd(A, ConstantInt::get(A->getType(), *Msk));
+ return new ICmpInst(
+ Pred, MaskA,
+ Constant::getIntegerValue(MaskA->getType(), NewComperand));
+ }
+ }
+
return nullptr;
}
diff --git a/llvm/test/Transforms/InstCombine/and-compare.ll b/llvm/test/Transforms/InstCombine/and-compare.ll
index 5a9767a64a2ced..9f8d3e317accc7 100644
--- a/llvm/test/Transforms/InstCombine/and-compare.ll
+++ b/llvm/test/Transforms/InstCombine/and-compare.ll
@@ -172,3 +172,87 @@ define i1 @test_ne_cp2_other_okay2(i8 %x, i8 %yy) {
%r = icmp ne i8 %and_x_y, %and_x_neg_y
ret i1 %r
}
+
+define i1 @test_eq_0_and_15_add_1(i8 %a) {
+; CHECK-LABEL: @test_eq_0_and_15_add_1(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[TMP0:%.*]] = and i8 [[A:%.*]], 15
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[TMP0]], 15
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+entry:
+ %add = add i8 %a, 1
+ %and = and i8 %add, 15
+ %cmp = icmp eq i8 %and, 0
+ ret i1 %cmp
+}
+
+define i1 @test_ne_0_and_15_add_1(i8 %a) {
+; CHECK-LABEL: @test_ne_0_and_15_add_1(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[TMP0:%.*]] = and i8 [[A:%.*]], 15
+; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[TMP0]], 15
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+entry:
+ %add = add i8 %a, 1
+ %and = and i8 %add, 15
+ %cmp = icmp ne i8 %and, 0
+ ret i1 %cmp
+}
+
+define i1 @test_eq_0_and_15_add_3(i8 %a) {
+; CHECK-LABEL: @test_eq_0_and_15_add_3(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[TMP0:%.*]] = and i8 [[A:%.*]], 15
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[TMP0]], 13
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+entry:
+ %add = add i8 %a, 3
+ %and = and i8 %add, 15
+ %cmp = icmp eq i8 %and, 0
+ ret i1 %cmp
+}
+
+define i1 @test_ne_0_and_15_add_3(i8 %a) {
+; CHECK-LABEL: @test_ne_0_and_15_add_3(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[TMP0:%.*]] = and i8 [[A:%.*]], 15
+; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[TMP0]], 13
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+entry:
+ %add = add i8 %a, 3
+ %and = and i8 %add, 15
+ %cmp = icmp ne i8 %and, 0
+ ret i1 %cmp
+}
+
+define i1 @test_eq_11_and_15_add_10(i8 %a) {
+; CHECK-LABEL: @test_eq_11_and_15_add_10(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[TMP0:%.*]] = and i8 [[A:%.*]], 15
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[TMP0]], 1
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+entry:
+ %add = add i8 %a, 10
+ %and = and i8 %add, 15
+ %cmp = icmp eq i8 %and, 11
+ ret i1 %cmp
+}
+
+define i1 @test_ne_11_and_15_add_10(i8 %a) {
+; CHECK-LABEL: @test_ne_11_and_15_add_10(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[TMP0:%.*]] = and i8 [[A:%.*]], 15
+; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[TMP0]], 1
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+entry:
+ %add = add i8 %a, 10
+ %and = and i8 %add, 15
+ %cmp = icmp ne i8 %and, 11
+ ret i1 %cmp
+}
More information about the llvm-commits
mailing list