forked from OSchip/llvm-project
[InstCombine] Move casts around shift operations
It is possible to perform a left shift before zero extending if the shift would only shift out zeros. llvm-svn: 290928
This commit is contained in:
parent
022d2a563b
commit
cb892e9066
|
@ -731,6 +731,25 @@ Instruction *InstCombiner::visitShl(BinaryOperator &I) {
|
|||
if (ConstantInt *Op1C = dyn_cast<ConstantInt>(I.getOperand(1))) {
|
||||
unsigned ShAmt = Op1C->getZExtValue();
|
||||
|
||||
// Turn:
|
||||
// %zext = zext i32 %V to i64
|
||||
// %res = shl i64 %V, 8
|
||||
//
|
||||
// Into:
|
||||
// %shl = shl i32 %V, 8
|
||||
// %res = zext i32 %shl to i64
|
||||
//
|
||||
// This is only valid if %V would have zeros shifted out.
|
||||
if (auto *ZI = dyn_cast<ZExtInst>(I.getOperand(0))) {
|
||||
unsigned SrcBitWidth = ZI->getSrcTy()->getScalarSizeInBits();
|
||||
if (ShAmt < SrcBitWidth &&
|
||||
MaskedValueIsZero(ZI->getOperand(0),
|
||||
APInt::getHighBitsSet(SrcBitWidth, ShAmt), 0, &I)) {
|
||||
auto *Shl = Builder->CreateShl(ZI->getOperand(0), ShAmt);
|
||||
return new ZExtInst(Shl, I.getType());
|
||||
}
|
||||
}
|
||||
|
||||
// If the shifted-out value is known-zero, then this is a NUW shift.
|
||||
if (!I.hasNoUnsignedWrap() &&
|
||||
MaskedValueIsZero(I.getOperand(0),
|
||||
|
|
|
@ -204,11 +204,11 @@ define i32 @test17(i32 %X) {
|
|||
|
||||
define i32 @test18(i16 %x, i32 %y) {
|
||||
; CHECK: @test18
|
||||
; CHECK-NEXT: [[AND:%.*]] = and i16 %x, 4
|
||||
; CHECK-NEXT: [[EXT:%.*]] = zext i16 [[AND]] to i32
|
||||
; CHECK-NEXT: [[SHL:%.*]] = shl nuw nsw i32 [[EXT]], 3
|
||||
; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[SHL]], 63
|
||||
; CHECK-NEXT: [[REM:%.*]] = and i32 [[XOR]], %y
|
||||
; CHECK-NEXT: [[SHL:%.*]] = shl i16 %x, 3
|
||||
; CHECK-NEXT: [[AND:%.*]] = and i16 [[SHL]], 32
|
||||
; CHECK-NEXT: [[XOR:%.*]] = xor i16 [[AND]], 63
|
||||
; CHECK-NEXT: [[EXT:%.*]] = zext i16 [[XOR]] to i32
|
||||
; CHECK-NEXT: [[REM:%.*]] = and i32 [[EXT]], %y
|
||||
; CHECK-NEXT: ret i32 [[REM]]
|
||||
%1 = and i16 %x, 4
|
||||
%2 = icmp ne i16 %1, 0
|
||||
|
|
|
@ -1049,3 +1049,15 @@ define <2 x i65> @test_63(<2 x i64> %t) {
|
|||
%b = ashr <2 x i65> %sext, <i65 33, i65 33>
|
||||
ret <2 x i65> %b
|
||||
}
|
||||
|
||||
define i64 @test_64(i32 %t) {
|
||||
; CHECK-LABEL: @test_64(
|
||||
; CHECK-NEXT: [[SHL:%.*]] = shl i32 %t, 8
|
||||
; CHECK-NEXT: [[EXT:%.*]] = zext i32 [[SHL]] to i64
|
||||
; CHECK-NEXT: ret i64 [[EXT]]
|
||||
|
||||
%and = and i32 %t, 16777215
|
||||
%ext = zext i32 %and to i64
|
||||
%shl = shl i64 %ext, 8
|
||||
ret i64 %shl
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue