[llvm] a488c78 - [InstCombine] reduce signbit test of logic ops to cmp with zero
Sanjay Patel via llvm-commits
llvm-commits at lists.llvm.org
Mon Jul 12 06:03:24 PDT 2021
Author: Sanjay Patel
Date: 2021-07-12T09:01:26-04:00
New Revision: a488c7879e688f40647f0deacd7e09ec3082e4a4
URL: https://github.com/llvm/llvm-project/commit/a488c7879e688f40647f0deacd7e09ec3082e4a4
DIFF: https://github.com/llvm/llvm-project/commit/a488c7879e688f40647f0deacd7e09ec3082e4a4.diff
LOG: [InstCombine] reduce signbit test of logic ops to cmp with zero
This is the pattern from the description of:
https://llvm.org/PR50816
There might be a way to generalize this to a smaller or more
generic pattern, but I have not found it yet.
https://alive2.llvm.org/ce/z/ShzJoF
define i1 @src(i8 %x) {
%add = add i8 %x, -1
%xor = xor i8 %x, -1
%and = and i8 %add, %xor
%r = icmp slt i8 %and, 0
ret i1 %r
}
define i1 @tgt(i8 %x) {
%r = icmp eq i8 %x, 0
ret i1 %r
}
Added:
Modified:
llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
llvm/test/Transforms/InstCombine/icmp.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index 6e66c61f5e46d..031b95e9c0875 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -1855,6 +1855,19 @@ Instruction *InstCombinerImpl::foldICmpAndConstant(ICmpInst &Cmp,
if (Instruction *I = foldICmpAndConstConst(Cmp, And, C))
return I;
+ const ICmpInst::Predicate Pred = Cmp.getPredicate();
+ bool TrueIfNeg;
+ if (isSignBitCheck(Pred, C, TrueIfNeg)) {
+ // ((X - 1) & ~X) < 0 --> X == 0
+ // ((X - 1) & ~X) >= 0 --> X != 0
+ Value *X;
+ if (match(And->getOperand(0), m_Add(m_Value(X), m_AllOnes())) &&
+ match(And->getOperand(1), m_Not(m_Specific(X)))) {
+ auto NewPred = TrueIfNeg ? CmpInst::ICMP_EQ : CmpInst::ICMP_NE;
+ return new ICmpInst(NewPred, X, ConstantInt::getNullValue(X->getType()));
+ }
+ }
+
// TODO: These all require that Y is constant too, so refactor with the above.
// Try to optimize things like "A[i] & 42 == 0" to index computations.
@@ -1877,8 +1890,8 @@ Instruction *InstCombinerImpl::foldICmpAndConstant(ICmpInst &Cmp,
// X & -C != -C -> X <= u ~C
// iff C is a power of 2
if (Cmp.getOperand(1) == Y && (-C).isPowerOf2()) {
- auto NewPred = Cmp.getPredicate() == CmpInst::ICMP_EQ ? CmpInst::ICMP_UGT
- : CmpInst::ICMP_ULE;
+ auto NewPred =
+ Pred == CmpInst::ICMP_EQ ? CmpInst::ICMP_UGT : CmpInst::ICMP_ULE;
return new ICmpInst(NewPred, X, SubOne(cast<Constant>(Cmp.getOperand(1))));
}
@@ -1893,8 +1906,8 @@ Instruction *InstCombinerImpl::foldICmpAndConstant(ICmpInst &Cmp,
if (auto *AndVTy = dyn_cast<VectorType>(And->getType()))
NTy = VectorType::get(NTy, AndVTy->getElementCount());
Value *Trunc = Builder.CreateTrunc(X, NTy);
- auto NewPred = Cmp.getPredicate() == CmpInst::ICMP_EQ ? CmpInst::ICMP_SGE
- : CmpInst::ICMP_SLT;
+ auto NewPred =
+ Pred == CmpInst::ICMP_EQ ? CmpInst::ICMP_SGE : CmpInst::ICMP_SLT;
return new ICmpInst(NewPred, Trunc, Constant::getNullValue(NTy));
}
}
diff --git a/llvm/test/Transforms/InstCombine/icmp.ll b/llvm/test/Transforms/InstCombine/icmp.ll
index 30b6c88052b6e..3d254ef1da16d 100644
--- a/llvm/test/Transforms/InstCombine/icmp.ll
+++ b/llvm/test/Transforms/InstCombine/icmp.ll
@@ -3953,10 +3953,7 @@ define i1 @thread_cmp_over_select_with_poison_falseval(i1 %b) {
define i1 @signbit_true_logic(i8 %x) {
; CHECK-LABEL: @signbit_true_logic(
-; CHECK-NEXT: [[DEC:%.*]] = add i8 [[X:%.*]], -1
-; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[X]], -1
-; CHECK-NEXT: [[AND:%.*]] = and i8 [[DEC]], [[NOT]]
-; CHECK-NEXT: [[R:%.*]] = icmp slt i8 [[AND]], 0
+; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[X:%.*]], 0
; CHECK-NEXT: ret i1 [[R]]
;
%dec = add i8 %x, -1
@@ -3968,10 +3965,7 @@ define i1 @signbit_true_logic(i8 %x) {
define <2 x i1> @signbit_false_logic(<2 x i5> %x) {
; CHECK-LABEL: @signbit_false_logic(
-; CHECK-NEXT: [[DEC:%.*]] = add <2 x i5> [[X:%.*]], <i5 -1, i5 undef>
-; CHECK-NEXT: [[NOT:%.*]] = xor <2 x i5> [[X]], <i5 -1, i5 -1>
-; CHECK-NEXT: [[AND:%.*]] = and <2 x i5> [[DEC]], [[NOT]]
-; CHECK-NEXT: [[R:%.*]] = icmp sgt <2 x i5> [[AND]], <i5 -1, i5 -1>
+; CHECK-NEXT: [[R:%.*]] = icmp ne <2 x i5> [[X:%.*]], zeroinitializer
; CHECK-NEXT: ret <2 x i1> [[R]]
;
%dec = add <2 x i5> %x, <i5 -1, i5 undef>
@@ -3991,7 +3985,7 @@ define i1 @signbit_true_logic_uses_commute(i64 %x) {
; CHECK-NEXT: call void @use_i64(i64 [[NOT]])
; CHECK-NEXT: [[AND:%.*]] = and i64 [[DEC]], [[NOT]]
; CHECK-NEXT: call void @use_i64(i64 [[AND]])
-; CHECK-NEXT: [[R:%.*]] = icmp slt i64 [[AND]], 0
+; CHECK-NEXT: [[R:%.*]] = icmp eq i64 [[X]], 0
; CHECK-NEXT: ret i1 [[R]]
;
%dec = add i64 %x, -1
More information about the llvm-commits
mailing list