forked from OSchip/llvm-project
[InstCombine] Teach canEvaluateTruncated to handle arithmetic shift (including those with vector splat shift amount)
Differential Revision: https://reviews.llvm.org/D36784 llvm-svn: 311050
This commit is contained in:
parent
cbcffb173c
commit
86111c6696
|
@ -373,6 +373,23 @@ static bool canEvaluateTruncated(Value *V, Type *Ty, InstCombiner &IC,
|
|||
}
|
||||
break;
|
||||
}
|
||||
case Instruction::AShr: {
|
||||
// If this is a truncate of an arithmetic shr, we can truncate it to a
|
||||
// smaller ashr iff we know that all the bits from the sign bit of the
|
||||
// original type and the sign bit of the truncate type are similar.
|
||||
// TODO: It is enough to check that the bits we would be shifting in are
|
||||
// similar to sign bit of the truncate type.
|
||||
const APInt *Amt;
|
||||
if (match(I->getOperand(1), m_APInt(Amt))) {
|
||||
uint32_t OrigBitWidth = OrigTy->getScalarSizeInBits();
|
||||
uint32_t BitWidth = Ty->getScalarSizeInBits();
|
||||
if (Amt->getLimitedValue(BitWidth) < BitWidth &&
|
||||
OrigBitWidth - BitWidth <
|
||||
IC.ComputeNumSignBits(I->getOperand(0), 0, CxtI))
|
||||
return canEvaluateTruncated(I->getOperand(0), Ty, IC, CxtI);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Instruction::Trunc:
|
||||
// trunc(trunc(x)) -> trunc(x)
|
||||
return true;
|
||||
|
|
|
@ -89,6 +89,32 @@ define i32 @test6(i64 %A) {
|
|||
ret i32 %D
|
||||
}
|
||||
|
||||
define i32 @trunc_ashr(i32 %X) {
|
||||
; CHECK-LABEL: @trunc_ashr(
|
||||
; CHECK-NEXT: [[B:%.*]] = or i32 [[X:%.*]], -2147483648
|
||||
; CHECK-NEXT: [[C:%.*]] = ashr i32 [[B]], 8
|
||||
; CHECK-NEXT: ret i32 [[C]]
|
||||
;
|
||||
%A = zext i32 %X to i36
|
||||
%B = or i36 %A, -2147483648 ; 0xF80000000
|
||||
%C = ashr i36 %B, 8
|
||||
%T = trunc i36 %C to i32
|
||||
ret i32 %T
|
||||
}
|
||||
|
||||
define <2 x i32> @trunc_ashr_vec(<2 x i32> %X) {
|
||||
; CHECK-LABEL: @trunc_ashr_vec(
|
||||
; CHECK-NEXT: [[B:%.*]] = or <2 x i32> [[X:%.*]], <i32 -2147483648, i32 -2147483648>
|
||||
; CHECK-NEXT: [[C:%.*]] = ashr <2 x i32> [[B]], <i32 8, i32 8>
|
||||
; CHECK-NEXT: ret <2 x i32> [[C]]
|
||||
;
|
||||
%A = zext <2 x i32> %X to <2 x i36>
|
||||
%B = or <2 x i36> %A, <i36 -2147483648, i36 -2147483648> ; 0xF80000000
|
||||
%C = ashr <2 x i36> %B, <i36 8, i36 8>
|
||||
%T = trunc <2 x i36> %C to <2 x i32>
|
||||
ret <2 x i32> %T
|
||||
}
|
||||
|
||||
define i92 @test7(i64 %A) {
|
||||
; CHECK-LABEL: @test7(
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = lshr i64 %A, 32
|
||||
|
|
Loading…
Reference in New Issue