Skip to content

Commit 22178dd

Browse files
author
Amjad Aboud
committed
[InstCombine] Consider more cases where SimplifyDemandedUseBits does not convert AShr to LShr.
There are cases where AShr have better chance to be optimized than LShr, especially when the demanded bits are not known to be Zero, and also known to be similar to the sign bit. Differential Revision: https://reviews.llvm.org/D36936 llvm-svn: 311773
1 parent 6cc8317 commit 22178dd

File tree

2 files changed

+22
-2
lines changed

2 files changed

+22
-2
lines changed

llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -521,9 +521,12 @@ Value *InstCombiner::SimplifyDemandedUseBits(Value *V, APInt DemandedMask,
521521
if (SimplifyDemandedBits(I, 0, DemandedMaskIn, Known, Depth + 1))
522522
return I;
523523

524+
unsigned SignBits = ComputeNumSignBits(I->getOperand(0), Depth + 1, CxtI);
525+
524526
assert(!Known.hasConflict() && "Bits known to be one AND zero?");
525-
// Compute the new bits that are at the top now.
526-
APInt HighBits(APInt::getHighBitsSet(BitWidth, ShiftAmt));
527+
// Compute the new bits that are at the top now plus sign bits.
528+
APInt HighBits(APInt::getHighBitsSet(
529+
BitWidth, std::min(SignBits + ShiftAmt - 1, BitWidth)));
527530
Known.Zero.lshrInPlace(ShiftAmt);
528531
Known.One.lshrInPlace(ShiftAmt);
529532

llvm/test/Transforms/InstCombine/trunc.ll

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,23 @@ define i32 @test6(i64 %A) {
8989
ret i32 %D
9090
}
9191

92+
; Test case where 'ashr' demanded bits does not contain any of the high bits,
93+
; but does contain sign bits, where the sign bit is not known to be zero.
94+
define i16 @ashr_mul_sign_bits(i8 %X, i8 %Y) {
95+
; CHECK-LABEL: @ashr_mul_sign_bits(
96+
; CHECK-NEXT: [[A:%.*]] = sext i8 %X to i16
97+
; CHECK-NEXT: [[B:%.*]] = sext i8 %Y to i16
98+
; CHECK-NEXT: [[C:%.*]] = mul nsw i16 [[A]], [[B]]
99+
; CHECK-NEXT: [[D:%.*]] = ashr i16 [[C]], 3
100+
; CHECK-NEXT: ret i16 [[D]]
101+
%A = sext i8 %X to i32
102+
%B = sext i8 %Y to i32
103+
%C = mul i32 %A, %B
104+
%D = ashr i32 %C, 3
105+
%E = trunc i32 %D to i16
106+
ret i16 %E
107+
}
108+
92109
define i16 @ashr_mul(i8 %X, i8 %Y) {
93110
; CHECK-LABEL: @ashr_mul(
94111
; CHECK-NEXT: [[A:%.*]] = sext i8 %X to i16

0 commit comments

Comments
 (0)