Skip to content

Commit 9d167e0

Browse files
bjopeyuxuanchen1997
authored andcommitted
[InstCombine] Turn AShr into LShr more often in SimplifyDemandedUseBits (#99155)
Summary: The functional change here is to undo "llvm-svn: 311773", aka D36936, aka commit 22178dd. That patch avoided to convert AShr into LShr in SimplifyDemandedUseBits based on known sign bits analysis. Even if it would be legal to turn the shift into a logical shift (given by the fact that the shifted in bits wasn't demanded), that patch prevented converting the shift into LShr when any of the original sign bits were demanded. One side effect of the reverted functionalty was that the better we were at computing number of sign bits, the less likely it was that we would replace AShr by LShr during SimplifyDemandedUseBits. This was seen in #97693 when an improvement of ComputeNumSignBits resulted in regressions due to no longer rewriting AShr to LShr. The test case from D36936 still passes after this commit. So it seems like at least the compiler has been taught how to optimize that scenario even if we do the AShr->LShr transform more aggressively. Test Plan: Reviewers: Subscribers: Tasks: Tags: Differential Revision: https://phabricator.intern.facebook.com/D60250972
1 parent 34ba864 commit 9d167e0

File tree

2 files changed

+14
-21
lines changed

2 files changed

+14
-21
lines changed

llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -806,34 +806,30 @@ Value *InstCombinerImpl::SimplifyDemandedUseBits(Instruction *I,
806806

807807
// Signed shift right.
808808
APInt DemandedMaskIn(DemandedMask.shl(ShiftAmt));
809-
// If any of the high bits are demanded, we should set the sign bit as
810-
// demanded.
811-
if (DemandedMask.countl_zero() <= ShiftAmt)
809+
// If any of the bits being shifted in are demanded, then we should set
810+
// the sign bit as demanded.
811+
bool ShiftedInBitsDemanded = DemandedMask.countl_zero() < ShiftAmt;
812+
if (ShiftedInBitsDemanded)
812813
DemandedMaskIn.setSignBit();
813-
814814
if (SimplifyDemandedBits(I, 0, DemandedMaskIn, Known, Depth + 1, Q)) {
815815
// exact flag may not longer hold.
816816
I->dropPoisonGeneratingFlags();
817817
return I;
818818
}
819819

820-
Known = KnownBits::ashr(
821-
Known, KnownBits::makeConstant(APInt(BitWidth, ShiftAmt)),
822-
ShiftAmt != 0, I->isExact());
823-
824-
// If the input sign bit is known to be zero, or if none of the top bits
825-
// are demanded, turn this into an unsigned shift right.
826-
assert(BitWidth > ShiftAmt && "Shift amount not saturated?");
827-
APInt HighBits(APInt::getHighBitsSet(
828-
BitWidth, std::min(SignBits + ShiftAmt - 1, BitWidth)));
829-
if (Known.Zero[BitWidth-ShiftAmt-1] ||
830-
!DemandedMask.intersects(HighBits)) {
820+
// If the input sign bit is known to be zero, or if none of the shifted in
821+
// bits are demanded, turn this into an unsigned shift right.
822+
if (Known.Zero[BitWidth - 1] || !ShiftedInBitsDemanded) {
831823
BinaryOperator *LShr = BinaryOperator::CreateLShr(I->getOperand(0),
832824
I->getOperand(1));
833825
LShr->setIsExact(cast<BinaryOperator>(I)->isExact());
834826
LShr->takeName(I);
835827
return InsertNewInstWith(LShr, I->getIterator());
836828
}
829+
830+
Known = KnownBits::ashr(
831+
Known, KnownBits::makeConstant(APInt(BitWidth, ShiftAmt)),
832+
ShiftAmt != 0, I->isExact());
837833
} else {
838834
llvm::computeKnownBits(I, Known, Depth, Q);
839835
}

llvm/test/Transforms/InstCombine/ashr-demand.ll

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -74,12 +74,9 @@ define i16 @ashr_can_be_lshr(i32 %a) {
7474
; optimizations.
7575
define i32 @ashr_can_be_lshr_2(i32 %a) {
7676
; CHECK-LABEL: @ashr_can_be_lshr_2(
77-
; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[A:%.*]], 1056964608
78-
; CHECK-NEXT: [[OR:%.*]] = zext i32 [[TMP1]] to i64
79-
; CHECK-NEXT: [[SHL:%.*]] = shl i64 [[OR]], 34
80-
; CHECK-NEXT: [[ASHR:%.*]] = ashr exact i64 [[SHL]], 32
81-
; CHECK-NEXT: [[TRUNC:%.*]] = trunc nsw i64 [[ASHR]] to i32
82-
; CHECK-NEXT: ret i32 [[TRUNC]]
77+
; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[A:%.*]], 2
78+
; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], -67108864
79+
; CHECK-NEXT: ret i32 [[TMP2]]
8380
;
8481
%ext = zext i32 %a to i64
8582
%or = or i64 %ext, 4278190080

0 commit comments

Comments
 (0)