[llvm-branch-commits] [llvm] 526102b - [InstCombine] Canonicalize icmp eq pow2 more thoroughly
Tobias Hieta via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Thu Mar 23 07:34:59 PDT 2023
Author: Nikita Popov
Date: 2023-03-23T15:32:45+01:00
New Revision: 526102b37e597379962525ba4563f24735ad05a8
URL: https://github.com/llvm/llvm-project/commit/526102b37e597379962525ba4563f24735ad05a8
DIFF: https://github.com/llvm/llvm-project/commit/526102b37e597379962525ba4563f24735ad05a8.diff
LOG: [InstCombine] Canonicalize icmp eq pow2 more thoroughly
We currently already canonicalize icmp eq (%x & Pow2), Pow2 to
icmp ne (%x & Pow2), 0. This patch generalizes the fold based on
known bits.
In particular, this allows us to handle comparisons against
!range !{i64 0, i64 2} loads, which addresses an optimization
regression in Rust caused by 8df376db7282b955e7990cb8887ee9dcd3565040.
Differential Revision: https://reviews.llvm.org/D146149
(cherry picked from commit 61d2f3a71e61929bf9b07c90e21d268090417bdb)
Added:
Modified:
llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
llvm/test/Transforms/InstCombine/div.ll
llvm/test/Transforms/InstCombine/icmp-range.ll
llvm/test/Transforms/InstCombine/icmp-shl-nsw.ll
llvm/test/Transforms/InstCombine/icmp-shr-lt-gt.ll
llvm/test/Transforms/InstCombine/zext.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index 1480a0ff9e2f8..de30958520480 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -3184,16 +3184,6 @@ Instruction *InstCombinerImpl::foldICmpBinOpEqualityWithConstant(
}
break;
}
- case Instruction::And: {
- const APInt *BOC;
- if (match(BOp1, m_APInt(BOC))) {
- // If we have ((X & C) == C), turn it into ((X & C) != 0).
- if (C == *BOC && C.isPowerOf2())
- return new ICmpInst(isICMP_NE ? ICmpInst::ICMP_EQ : ICmpInst::ICMP_NE,
- BO, Constant::getNullValue(RHS->getType()));
- }
- break;
- }
case Instruction::UDiv:
if (C.isZero()) {
// (icmp eq/ne (udiv A, B), 0) -> (icmp ugt/ule i32 B, A)
@@ -5653,6 +5643,12 @@ Instruction *InstCombinerImpl::foldICmpUsingKnownBits(ICmpInst &I) {
}
}
}
+
+ // Op0 eq C_Pow2 -> Op0 ne 0 if Op0 is known to be C_Pow2 or zero.
+ if (Op1Known.isConstant() && Op1Known.getConstant().isPowerOf2() &&
+ (Op0Known & Op1Known) == Op0Known)
+ return new ICmpInst(CmpInst::getInversePredicate(Pred), Op0,
+ ConstantInt::getNullValue(Op1->getType()));
break;
}
case ICmpInst::ICMP_ULT: {
diff --git a/llvm/test/Transforms/InstCombine/div.ll b/llvm/test/Transforms/InstCombine/div.ll
index 3d34e3c57bf58..425c688b04e1c 100644
--- a/llvm/test/Transforms/InstCombine/div.ll
+++ b/llvm/test/Transforms/InstCombine/div.ll
@@ -400,7 +400,7 @@ define i32 @test28(i32 %a) {
define i32 @test29(i32 %a) {
; CHECK-LABEL: @test29(
-; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[A:%.*]], -1
+; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i32 [[A:%.*]], 0
; CHECK-NEXT: [[DIV:%.*]] = zext i1 [[TMP1]] to i32
; CHECK-NEXT: ret i32 [[DIV]]
;
diff --git a/llvm/test/Transforms/InstCombine/icmp-range.ll b/llvm/test/Transforms/InstCombine/icmp-range.ll
index b4a7110df9bbc..097de4a85f993 100644
--- a/llvm/test/Transforms/InstCombine/icmp-range.ll
+++ b/llvm/test/Transforms/InstCombine/icmp-range.ll
@@ -643,7 +643,7 @@ define i1 @icmp_eq_bool_0(ptr %ptr) {
define i1 @icmp_eq_bool_1(ptr %ptr) {
; CHECK-LABEL: @icmp_eq_bool_1(
; CHECK-NEXT: [[VAL:%.*]] = load i64, ptr [[PTR:%.*]], align 8, !range [[RNG6]]
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[VAL]], 1
+; CHECK-NEXT: [[CMP:%.*]] = icmp ne i64 [[VAL]], 0
; CHECK-NEXT: ret i1 [[CMP]]
;
%val = load i64, ptr %ptr, align 8, !range !{i64 0, i64 2}
@@ -665,7 +665,7 @@ define i1 @icmp_ne_bool_0(ptr %ptr) {
define i1 @icmp_ne_bool_1(ptr %ptr) {
; CHECK-LABEL: @icmp_ne_bool_1(
; CHECK-NEXT: [[VAL:%.*]] = load i64, ptr [[PTR:%.*]], align 8, !range [[RNG6]]
-; CHECK-NEXT: [[CMP:%.*]] = icmp ne i64 [[VAL]], 1
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[VAL]], 0
; CHECK-NEXT: ret i1 [[CMP]]
;
%val = load i64, ptr %ptr, align 8, !range !{i64 0, i64 2}
diff --git a/llvm/test/Transforms/InstCombine/icmp-shl-nsw.ll b/llvm/test/Transforms/InstCombine/icmp-shl-nsw.ll
index 012ed586194d4..cbec5929304d8 100644
--- a/llvm/test/Transforms/InstCombine/icmp-shl-nsw.ll
+++ b/llvm/test/Transforms/InstCombine/icmp-shl-nsw.ll
@@ -162,7 +162,7 @@ define i1 @icmp_sgt8(i8 %x) {
define i1 @icmp_sgt9(i8 %x) {
; CHECK-LABEL: @icmp_sgt9(
-; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 %x, -1
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[X:%.*]], 0
; CHECK-NEXT: ret i1 [[CMP]]
;
%shl = shl nsw i8 %x, 7
@@ -303,7 +303,7 @@ define i1 @icmp_sle8(i8 %x) {
define i1 @icmp_sle9(i8 %x) {
; CHECK-LABEL: @icmp_sle9(
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 %x, -1
+; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[X:%.*]], 0
; CHECK-NEXT: ret i1 [[CMP]]
;
%shl = shl nsw i8 %x, 7
diff --git a/llvm/test/Transforms/InstCombine/icmp-shr-lt-gt.ll b/llvm/test/Transforms/InstCombine/icmp-shr-lt-gt.ll
index 6ef1c6ca211d5..33c9b59551667 100644
--- a/llvm/test/Transforms/InstCombine/icmp-shr-lt-gt.ll
+++ b/llvm/test/Transforms/InstCombine/icmp-shr-lt-gt.ll
@@ -2767,7 +2767,7 @@ define i1 @lshrult_03_00_exact(i4 %x) {
define i1 @lshrult_03_01_exact(i4 %x) {
; CHECK-LABEL: @lshrult_03_01_exact(
-; CHECK-NEXT: [[C:%.*]] = icmp ne i4 [[X:%.*]], -8
+; CHECK-NEXT: [[C:%.*]] = icmp eq i4 [[X:%.*]], 0
; CHECK-NEXT: ret i1 [[C]]
;
%s = lshr exact i4 %x, 3
diff --git a/llvm/test/Transforms/InstCombine/zext.ll b/llvm/test/Transforms/InstCombine/zext.ll
index dd781c78d3fb1..8aa2a10e6abb2 100644
--- a/llvm/test/Transforms/InstCombine/zext.ll
+++ b/llvm/test/Transforms/InstCombine/zext.ll
@@ -718,9 +718,7 @@ define i64 @zext_icmp_eq_bool_0(ptr %ptr) {
define i64 @zext_icmp_eq_bool_1(ptr %ptr) {
; CHECK-LABEL: @zext_icmp_eq_bool_1(
; CHECK-NEXT: [[VAL:%.*]] = load i64, ptr [[PTR:%.*]], align 8, !range [[RNG0]]
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[VAL]], 1
-; CHECK-NEXT: [[LEN:%.*]] = zext i1 [[CMP]] to i64
-; CHECK-NEXT: ret i64 [[LEN]]
+; CHECK-NEXT: ret i64 [[VAL]]
;
%val = load i64, ptr %ptr, align 8, !range !{i64 0, i64 2}
%cmp = icmp eq i64 %val, 1
@@ -742,8 +740,7 @@ define i64 @zext_icmp_ne_bool_0(ptr %ptr) {
define i64 @zext_icmp_ne_bool_1(ptr %ptr) {
; CHECK-LABEL: @zext_icmp_ne_bool_1(
; CHECK-NEXT: [[VAL:%.*]] = load i64, ptr [[PTR:%.*]], align 8, !range [[RNG0]]
-; CHECK-NEXT: [[CMP:%.*]] = icmp ne i64 [[VAL]], 1
-; CHECK-NEXT: [[LEN:%.*]] = zext i1 [[CMP]] to i64
+; CHECK-NEXT: [[LEN:%.*]] = xor i64 [[VAL]], 1
; CHECK-NEXT: ret i64 [[LEN]]
;
%val = load i64, ptr %ptr, align 8, !range !{i64 0, i64 2}
More information about the llvm-branch-commits
mailing list