[llvm] 5354a21 - [InstCombine] fold shift+trunc signbit check
Sanjay Patel via llvm-commits
llvm-commits at lists.llvm.org
Mon Apr 12 13:26:00 PDT 2021
Author: Sanjay Patel
Date: 2021-04-12T16:19:43-04:00
New Revision: 5354a213a0e309f1bfd8d80c5041a559608d7968
URL: https://github.com/llvm/llvm-project/commit/5354a213a0e309f1bfd8d80c5041a559608d7968
DIFF: https://github.com/llvm/llvm-project/commit/5354a213a0e309f1bfd8d80c5041a559608d7968.diff
LOG: [InstCombine] fold shift+trunc signbit check
https://alive2.llvm.org/ce/z/6vQvrP
This solves:
https://llvm.org/PR49866
Added:
Modified:
llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
llvm/test/Transforms/InstCombine/compare-signs.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index 30048d1232cbf..1474830843957 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -1523,11 +1523,11 @@ Instruction *InstCombinerImpl::foldICmpTruncConstant(ICmpInst &Cmp,
ConstantInt::get(V->getType(), 1));
}
+ unsigned DstBits = Trunc->getType()->getScalarSizeInBits(),
+ SrcBits = X->getType()->getScalarSizeInBits();
if (Cmp.isEquality() && Trunc->hasOneUse()) {
// Simplify icmp eq (trunc x to i8), 42 -> icmp eq x, 42|highbits if all
// of the high bits truncated out of x are known.
- unsigned DstBits = Trunc->getType()->getScalarSizeInBits(),
- SrcBits = X->getType()->getScalarSizeInBits();
KnownBits Known = computeKnownBits(X, 0, &Cmp);
// If all the high bits are known, we can do this xform.
@@ -1539,6 +1539,22 @@ Instruction *InstCombinerImpl::foldICmpTruncConstant(ICmpInst &Cmp,
}
}
+ // Look through truncated right-shift of the sign-bit for a sign-bit check:
+ // trunc iN (ShOp >> ShAmtC) to i[N - ShAmtC] < 0 --> ShOp < 0
+ // trunc iN (ShOp >> ShAmtC) to i[N - ShAmtC] > -1 --> ShOp > -1
+ Value *ShOp;
+ const APInt *ShAmtC;
+ bool TrueIfSigned;
+ if (isSignBitCheck(Pred, C, TrueIfSigned) &&
+ match(X, m_Shr(m_Value(ShOp), m_APInt(ShAmtC))) &&
+ DstBits == SrcBits - ShAmtC->getZExtValue()) {
+ return TrueIfSigned
+ ? new ICmpInst(ICmpInst::ICMP_SLT, ShOp,
+ ConstantInt::getNullValue(X->getType()))
+ : new ICmpInst(ICmpInst::ICMP_SGT, ShOp,
+ ConstantInt::getAllOnesValue(X->getType()));
+ }
+
return nullptr;
}
diff --git a/llvm/test/Transforms/InstCombine/compare-signs.ll b/llvm/test/Transforms/InstCombine/compare-signs.ll
index 8be5ee08bf406..cac253c587be8 100644
--- a/llvm/test/Transforms/InstCombine/compare-signs.ll
+++ b/llvm/test/Transforms/InstCombine/compare-signs.ll
@@ -152,9 +152,7 @@ define <2 x i1> @test4c_vec(<2 x i64> %a) {
define i1 @shift_trunc_signbit_test(i32 %x) {
; CHECK-LABEL: @shift_trunc_signbit_test(
-; CHECK-NEXT: [[SH:%.*]] = lshr i32 [[X:%.*]], 24
-; CHECK-NEXT: [[TR:%.*]] = trunc i32 [[SH]] to i8
-; CHECK-NEXT: [[R:%.*]] = icmp slt i8 [[TR]], 0
+; CHECK-NEXT: [[R:%.*]] = icmp slt i32 [[X:%.*]], 0
; CHECK-NEXT: ret i1 [[R]]
;
%sh = lshr i32 %x, 24
@@ -169,7 +167,7 @@ define <2 x i1> @shift_trunc_signbit_test_vec_uses(<2 x i17> %x, <2 x i17>* %p1,
; CHECK-NEXT: store <2 x i17> [[SH]], <2 x i17>* [[P1:%.*]], align 8
; CHECK-NEXT: [[TR:%.*]] = trunc <2 x i17> [[SH]] to <2 x i13>
; CHECK-NEXT: store <2 x i13> [[TR]], <2 x i13>* [[P2:%.*]], align 4
-; CHECK-NEXT: [[R:%.*]] = icmp sgt <2 x i13> [[TR]], <i13 -1, i13 -1>
+; CHECK-NEXT: [[R:%.*]] = icmp sgt <2 x i17> [[X]], <i17 -1, i17 -1>
; CHECK-NEXT: ret <2 x i1> [[R]]
;
%sh = lshr <2 x i17> %x, <i17 4, i17 4>
@@ -180,6 +178,8 @@ define <2 x i1> @shift_trunc_signbit_test_vec_uses(<2 x i17> %x, <2 x i17>* %p1,
ret <2 x i1> %r
}
+; negative test
+
define i1 @shift_trunc_wrong_shift(i32 %x) {
; CHECK-LABEL: @shift_trunc_wrong_shift(
; CHECK-NEXT: [[SH:%.*]] = lshr i32 [[X:%.*]], 23
@@ -193,6 +193,8 @@ define i1 @shift_trunc_wrong_shift(i32 %x) {
ret i1 %r
}
+; negative test
+
define i1 @shift_trunc_wrong_cmp(i32 %x) {
; CHECK-LABEL: @shift_trunc_wrong_cmp(
; CHECK-NEXT: [[SH:%.*]] = lshr i32 [[X:%.*]], 24
More information about the llvm-commits
mailing list