[llvm] [InstCombine] Fold icmp eq/ne (X and C), 0 when partial bits are known (PR #85863)
Yingwei Zheng via llvm-commits
llvm-commits at lists.llvm.org
Tue Mar 19 13:22:50 PDT 2024
https://github.com/dtcxzyw created https://github.com/llvm/llvm-project/pull/85863
Fixes https://github.com/llvm/llvm-project/issues/85823.
Alive2: https://alive2.llvm.org/ce/z/QUvHVj
>From 28da526b33a1916edbeb37d801c56bd8c8df900e Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Wed, 20 Mar 2024 04:12:02 +0800
Subject: [PATCH 1/2] [InstCombine] Add pre-commit for PR85823. NFC.
---
llvm/test/Transforms/InstCombine/icmp-dom.ll | 89 ++++++++++++++++++++
1 file changed, 89 insertions(+)
diff --git a/llvm/test/Transforms/InstCombine/icmp-dom.ll b/llvm/test/Transforms/InstCombine/icmp-dom.ll
index f4b9022d14349b..94243afd508120 100644
--- a/llvm/test/Transforms/InstCombine/icmp-dom.ll
+++ b/llvm/test/Transforms/InstCombine/icmp-dom.ll
@@ -403,3 +403,92 @@ truelabel:
falselabel:
ret i8 0
}
+
+define i1 @and_mask1_eq(i32 %conv) {
+; CHECK-LABEL: @and_mask1_eq(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[AND:%.*]] = and i32 [[CONV:%.*]], 1
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0
+; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
+; CHECK: then:
+; CHECK-NEXT: ret i1 false
+; CHECK: else:
+; CHECK-NEXT: call void @dummy()
+; CHECK-NEXT: [[AND1:%.*]] = and i32 [[CONV]], 3
+; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[AND1]], 0
+; CHECK-NEXT: ret i1 [[CMP1]]
+;
+entry:
+ %and = and i32 %conv, 1
+ %cmp = icmp eq i32 %and, 0
+ br i1 %cmp, label %then, label %else
+
+then:
+ ret i1 0
+
+else:
+ call void @dummy()
+ %and1 = and i32 %conv, 3
+ %cmp1 = icmp eq i32 %and1, 0
+ ret i1 %cmp1
+}
+
+define i1 @and_mask1_ne(i32 %conv) {
+; CHECK-LABEL: @and_mask1_ne(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[AND:%.*]] = and i32 [[CONV:%.*]], 1
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0
+; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
+; CHECK: then:
+; CHECK-NEXT: ret i1 false
+; CHECK: else:
+; CHECK-NEXT: call void @dummy()
+; CHECK-NEXT: [[AND1:%.*]] = and i32 [[CONV]], 3
+; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i32 [[AND1]], 0
+; CHECK-NEXT: ret i1 [[CMP1]]
+;
+entry:
+ %and = and i32 %conv, 1
+ %cmp = icmp eq i32 %and, 0
+ br i1 %cmp, label %then, label %else
+
+then:
+ ret i1 0
+
+else:
+ call void @dummy()
+ %and1 = and i32 %conv, 3
+ %cmp1 = icmp ne i32 %and1, 0
+ ret i1 %cmp1
+}
+
+define i1 @and_mask2(i32 %conv) {
+; CHECK-LABEL: @and_mask2(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[AND:%.*]] = and i32 [[CONV:%.*]], 4
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0
+; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
+; CHECK: then:
+; CHECK-NEXT: ret i1 false
+; CHECK: else:
+; CHECK-NEXT: call void @dummy()
+; CHECK-NEXT: [[AND1:%.*]] = and i32 [[CONV]], 3
+; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[AND1]], 0
+; CHECK-NEXT: ret i1 [[CMP1]]
+;
+entry:
+ %and = and i32 %conv, 4
+ %cmp = icmp eq i32 %and, 0
+ br i1 %cmp, label %then, label %else
+
+then:
+ ret i1 0
+
+else:
+ call void @dummy()
+ %and1 = and i32 %conv, 3
+ %cmp1 = icmp eq i32 %and1, 0
+ ret i1 %cmp1
+}
+
+declare void @dummy()
>From fd6783edc42218cf3d197cefe8b89cea41589f4d Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Wed, 20 Mar 2024 04:13:15 +0800
Subject: [PATCH 2/2] [InstCombine] Fold `icmp eq/ne (X and C), 0` when partial
bits are known
---
llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp | 9 ++++++---
llvm/test/Transforms/InstCombine/icmp-dom.ll | 8 ++------
2 files changed, 8 insertions(+), 9 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index 0dce0077bf1588..7cb5e98dea2581 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -1771,11 +1771,14 @@ Instruction *InstCombinerImpl::foldICmpAndConstConst(ICmpInst &Cmp,
return new ICmpInst(NewPred, X, Zero);
}
- APInt NewC2 = *C2;
KnownBits Know = computeKnownBits(And->getOperand(0), 0, And);
+ if (Know.One.intersects(*C2))
+ return replaceInstUsesWith(
+ Cmp, ConstantInt::getBool(Cmp.getType(), isICMP_NE));
+
// Set high zeros of C2 to allow matching negated power-of-2.
- NewC2 = *C2 | APInt::getHighBitsSet(C2->getBitWidth(),
- Know.countMinLeadingZeros());
+ APInt NewC2 = *C2 | APInt::getHighBitsSet(C2->getBitWidth(),
+ Know.countMinLeadingZeros());
// Restrict this fold only for single-use 'and' (PR10267).
// ((%x & C) == 0) --> %x u< (-C) iff (-C) is power of two.
diff --git a/llvm/test/Transforms/InstCombine/icmp-dom.ll b/llvm/test/Transforms/InstCombine/icmp-dom.ll
index 94243afd508120..d97a2e707ae235 100644
--- a/llvm/test/Transforms/InstCombine/icmp-dom.ll
+++ b/llvm/test/Transforms/InstCombine/icmp-dom.ll
@@ -414,9 +414,7 @@ define i1 @and_mask1_eq(i32 %conv) {
; CHECK-NEXT: ret i1 false
; CHECK: else:
; CHECK-NEXT: call void @dummy()
-; CHECK-NEXT: [[AND1:%.*]] = and i32 [[CONV]], 3
-; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[AND1]], 0
-; CHECK-NEXT: ret i1 [[CMP1]]
+; CHECK-NEXT: ret i1 false
;
entry:
%and = and i32 %conv, 1
@@ -443,9 +441,7 @@ define i1 @and_mask1_ne(i32 %conv) {
; CHECK-NEXT: ret i1 false
; CHECK: else:
; CHECK-NEXT: call void @dummy()
-; CHECK-NEXT: [[AND1:%.*]] = and i32 [[CONV]], 3
-; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i32 [[AND1]], 0
-; CHECK-NEXT: ret i1 [[CMP1]]
+; CHECK-NEXT: ret i1 true
;
entry:
%and = and i32 %conv, 1
More information about the llvm-commits
mailing list