[PATCH] D150091: [InstCombine] Transform `icmp eq/ne ({su}div exact X,Y),C` -> `icmp eq/ne X, Y*C`
Noah Goldstein via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Thu Jul 13 17:37:27 PDT 2023
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rGddd18d02c71b: [InstCombine] Transform `icmp eq/ne ({su}div exact X,Y),C` -> `icmp eq/ne X… (authored by goldstein.w.n).
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D150091/new/
https://reviews.llvm.org/D150091
Files:
llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
llvm/test/Transforms/InstCombine/sdiv-icmp.ll
Index: llvm/test/Transforms/InstCombine/sdiv-icmp.ll
===================================================================
--- llvm/test/Transforms/InstCombine/sdiv-icmp.ll
+++ llvm/test/Transforms/InstCombine/sdiv-icmp.ll
@@ -4,8 +4,7 @@
declare void @use.i8(i8)
define i1 @sdiv_exact_eq_0(i8 %x, i8 %y) {
; CHECK-LABEL: @sdiv_exact_eq_0(
-; CHECK-NEXT: [[D:%.*]] = sdiv exact i8 [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[D]], 0
+; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[X:%.*]], 0
; CHECK-NEXT: ret i1 [[R]]
;
%d = sdiv exact i8 %x, %y
@@ -15,7 +14,7 @@
define i1 @udiv_exact_ne_0(i8 %x, i8 %y) {
; CHECK-LABEL: @udiv_exact_ne_0(
-; CHECK-NEXT: [[R:%.*]] = icmp ule i8 [[Y:%.*]], [[X:%.*]]
+; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[X:%.*]], 0
; CHECK-NEXT: ret i1 [[R]]
;
%d = udiv exact i8 %x, %y
@@ -25,8 +24,7 @@
define i1 @sdiv_exact_ne_1(i8 %x, i8 %y) {
; CHECK-LABEL: @sdiv_exact_ne_1(
-; CHECK-NEXT: [[D:%.*]] = sdiv exact i8 [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[D]], 0
+; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[X:%.*]], 0
; CHECK-NEXT: ret i1 [[R]]
;
%d = sdiv exact i8 %x, %y
@@ -36,8 +34,7 @@
define i1 @udiv_exact_eq_1(i8 %x, i8 %y) {
; CHECK-LABEL: @udiv_exact_eq_1(
-; CHECK-NEXT: [[D:%.*]] = udiv exact i8 [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[D]], 1
+; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: ret i1 [[R]]
;
%d = udiv exact i8 %x, %y
@@ -48,8 +45,8 @@
define i1 @sdiv_exact_eq_9_no_of(i8 %x, i8 %y) {
; CHECK-LABEL: @sdiv_exact_eq_9_no_of(
; CHECK-NEXT: [[YY:%.*]] = and i8 [[Y:%.*]], 7
-; CHECK-NEXT: [[D:%.*]] = sdiv exact i8 [[X:%.*]], [[YY]]
-; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[D]], 9
+; CHECK-NEXT: [[TMP1:%.*]] = mul nuw nsw i8 [[YY]], 9
+; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[TMP1]], [[X:%.*]]
; CHECK-NEXT: ret i1 [[R]]
;
%yy = and i8 %y, 7
@@ -100,8 +97,8 @@
define i1 @udiv_exact_ne_30_no_of(i8 %x, i8 %y) {
; CHECK-LABEL: @udiv_exact_ne_30_no_of(
; CHECK-NEXT: [[YY:%.*]] = and i8 [[Y:%.*]], 7
-; CHECK-NEXT: [[D:%.*]] = udiv exact i8 [[X:%.*]], [[YY]]
-; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[D]], 30
+; CHECK-NEXT: [[TMP1:%.*]] = mul nuw i8 [[YY]], 30
+; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[TMP1]], [[X:%.*]]
; CHECK-NEXT: ret i1 [[R]]
;
%yy = and i8 %y, 7
Index: llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -3323,7 +3323,29 @@
break;
}
case Instruction::UDiv:
- if (C.isZero()) {
+ case Instruction::SDiv:
+ if (BO->isExact()) {
+ // div exact X, Y eq/ne 0 -> X eq/ne 0
+ // div exact X, Y eq/ne 1 -> X eq/ne Y
+ // div exact X, Y eq/ne C ->
+ // if Y * C never-overflow && OneUse:
+ // -> Y * C eq/ne X
+ if (C.isZero())
+ return new ICmpInst(Pred, BOp0, Constant::getNullValue(BO->getType()));
+ else if (C.isOne())
+ return new ICmpInst(Pred, BOp0, BOp1);
+ else if (BO->hasOneUse()) {
+ OverflowResult OR = computeOverflow(
+ Instruction::Mul, BO->getOpcode() == Instruction::SDiv, BOp1,
+ Cmp.getOperand(1), BO);
+ if (OR == OverflowResult::NeverOverflows) {
+ Value *YC =
+ Builder.CreateMul(BOp1, ConstantInt::get(BO->getType(), C));
+ return new ICmpInst(Pred, YC, BOp0);
+ }
+ }
+ }
+ if (BO->getOpcode() == Instruction::UDiv && C.isZero()) {
// (icmp eq/ne (udiv A, B), 0) -> (icmp ugt/ule i32 B, A)
auto NewPred = isICMP_NE ? ICmpInst::ICMP_ULE : ICmpInst::ICMP_UGT;
return new ICmpInst(NewPred, BOp1, BOp0);
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D150091.540239.patch
Type: text/x-patch
Size: 3865 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230714/0dea293b/attachment.bin>
More information about the llvm-commits
mailing list