Skip to content
Snippets Groups Projects
Commit 5e902248 authored by Simon Pilgrim's avatar Simon Pilgrim
Browse files

[InstCombine] SimplifyDemandedUseBits - remove lshr node if we only demand known sign bit

This is a lshr equivalent to D122340 - if we don't demand any of the additional sign bits introduced by the ashr, the lshr can be treated as an ashr and we can remove the shift entirely if we only demand already known sign bits.

Another step towards PR21929

https://alive2.llvm.org/ce/z/6f3kjq

Differential Revision: https://reviews.llvm.org/D123118
parent 1c1d477c
No related branches found
No related tags found
No related merge requests found
......@@ -616,6 +616,19 @@ Value *InstCombinerImpl::SimplifyDemandedUseBits(Value *V, APInt DemandedMask,
if (match(I->getOperand(1), m_APInt(SA))) {
uint64_t ShiftAmt = SA->getLimitedValue(BitWidth-1);
// If we are just demanding the shifted sign bit and below, then this can
// be treated as an ASHR in disguise.
if (DemandedMask.countLeadingZeros() >= ShiftAmt) {
// If we only want bits that already match the signbit then we don't
// need to shift.
unsigned NumHiDemandedBits =
BitWidth - DemandedMask.countTrailingZeros();
unsigned SignBits =
ComputeNumSignBits(I->getOperand(0), Depth + 1, CxtI);
if (SignBits >= NumHiDemandedBits)
return I->getOperand(0);
}
// Unsigned shift right.
APInt DemandedMaskIn(DemandedMask.shl(ShiftAmt));
......
......@@ -4,9 +4,8 @@
define i32 @PR21929(i32 %x) {
; CHECK-LABEL: @PR21929(
; CHECK-NEXT: [[REM_I:%.*]] = srem i32 [[X:%.*]], 2
; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[REM_I]], 30
; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], 2
; CHECK-NEXT: [[RET_I:%.*]] = add nsw i32 [[TMP2]], [[REM_I]]
; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[REM_I]], 2
; CHECK-NEXT: [[RET_I:%.*]] = add nsw i32 [[TMP1]], [[REM_I]]
; CHECK-NEXT: ret i32 [[RET_I]]
;
%rem.i = srem i32 %x, 2
......@@ -19,9 +18,8 @@ define i32 @PR21929(i32 %x) {
define <2 x i32> @PR21929_vec(<2 x i32> %x) {
; CHECK-LABEL: @PR21929_vec(
; CHECK-NEXT: [[REM_I:%.*]] = srem <2 x i32> [[X:%.*]], <i32 2, i32 2>
; CHECK-NEXT: [[TMP1:%.*]] = lshr <2 x i32> [[REM_I]], <i32 30, i32 30>
; CHECK-NEXT: [[TMP2:%.*]] = and <2 x i32> [[TMP1]], <i32 2, i32 2>
; CHECK-NEXT: [[RET_I:%.*]] = add nsw <2 x i32> [[TMP2]], [[REM_I]]
; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[REM_I]], <i32 2, i32 2>
; CHECK-NEXT: [[RET_I:%.*]] = add nsw <2 x i32> [[TMP1]], [[REM_I]]
; CHECK-NEXT: ret <2 x i32> [[RET_I]]
;
%rem.i = srem <2 x i32> %x, <i32 2, i32 2>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment