From: Sanjay Patel Date: Mon, 12 Apr 2021 20:16:19 +0000 (-0400) Subject: [InstCombine] fold shift+trunc signbit check X-Git-Tag: llvmorg-14-init~9826 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=5354a213a0e309f1bfd8d80c5041a559608d7968;p=platform%2Fupstream%2Fllvm.git [InstCombine] fold shift+trunc signbit check https://alive2.llvm.org/ce/z/6vQvrP This solves: https://llvm.org/PR49866 --- diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp index 30048d1..1474830 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 8be5ee0..cac253c 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]], +; CHECK-NEXT: [[R:%.*]] = icmp sgt <2 x i17> [[X]], ; CHECK-NEXT: ret <2 x i1> [[R]] ; %sh = lshr <2 x i17> %x, @@ -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