mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 20:51:52 +01:00
Make use of the exact bit when optimizing '(X >>exact 3) << 1' to eliminate the
'and' that would zero out the trailing bits, and to produce an exact shift ourselves. llvm-svn: 147391
This commit is contained in:
parent
06b6c587e8
commit
c7e12f7dbf
@ -536,12 +536,11 @@ Instruction *InstCombiner::FoldShiftByConstant(Value *Op0, ConstantInt *Op1,
|
|||||||
if (ShiftAmt1 == 0) return 0; // Will be simplified in the future.
|
if (ShiftAmt1 == 0) return 0; // Will be simplified in the future.
|
||||||
Value *X = ShiftOp->getOperand(0);
|
Value *X = ShiftOp->getOperand(0);
|
||||||
|
|
||||||
uint32_t AmtSum = ShiftAmt1+ShiftAmt2; // Fold into one big shift.
|
|
||||||
|
|
||||||
IntegerType *Ty = cast<IntegerType>(I.getType());
|
IntegerType *Ty = cast<IntegerType>(I.getType());
|
||||||
|
|
||||||
// Check for (X << c1) << c2 and (X >> c1) >> c2
|
// Check for (X << c1) << c2 and (X >> c1) >> c2
|
||||||
if (I.getOpcode() == ShiftOp->getOpcode()) {
|
if (I.getOpcode() == ShiftOp->getOpcode()) {
|
||||||
|
uint32_t AmtSum = ShiftAmt1+ShiftAmt2; // Fold into one big shift.
|
||||||
// If this is oversized composite shift, then unsigned shifts get 0, ashr
|
// If this is oversized composite shift, then unsigned shifts get 0, ashr
|
||||||
// saturates.
|
// saturates.
|
||||||
if (AmtSum >= TypeBits) {
|
if (AmtSum >= TypeBits) {
|
||||||
@ -603,9 +602,16 @@ Instruction *InstCombiner::FoldShiftByConstant(Value *Op0, ConstantInt *Op1,
|
|||||||
// (X >>? C1) << C2 --> X >>? (C1-C2) & (-1 << C2)
|
// (X >>? C1) << C2 --> X >>? (C1-C2) & (-1 << C2)
|
||||||
if (I.getOpcode() == Instruction::Shl &&
|
if (I.getOpcode() == Instruction::Shl &&
|
||||||
ShiftOp->getOpcode() != Instruction::Shl) {
|
ShiftOp->getOpcode() != Instruction::Shl) {
|
||||||
Value *Shift = Builder->CreateBinOp(ShiftOp->getOpcode(), X,
|
ConstantInt *ShiftDiffCst = ConstantInt::get(Ty, ShiftDiff);
|
||||||
ConstantInt::get(Ty, ShiftDiff));
|
if (ShiftOp->isExact()) {
|
||||||
|
// (X >>?exact C1) << C2 --> X >>?exact (C1-C2)
|
||||||
|
BinaryOperator *NewShr = BinaryOperator::Create(ShiftOp->getOpcode(),
|
||||||
|
X, ShiftDiffCst);
|
||||||
|
NewShr->setIsExact(true);
|
||||||
|
return NewShr;
|
||||||
|
}
|
||||||
|
Value *Shift = Builder->CreateBinOp(ShiftOp->getOpcode(),
|
||||||
|
X, ShiftDiffCst);
|
||||||
APInt Mask(APInt::getHighBitsSet(TypeBits, TypeBits - ShiftAmt2));
|
APInt Mask(APInt::getHighBitsSet(TypeBits, TypeBits - ShiftAmt2));
|
||||||
return BinaryOperator::CreateAnd(Shift,
|
return BinaryOperator::CreateAnd(Shift,
|
||||||
ConstantInt::get(I.getContext(),Mask));
|
ConstantInt::get(I.getContext(),Mask));
|
||||||
|
@ -542,3 +542,21 @@ define i32 @test45(i32 %a) nounwind {
|
|||||||
; CHECK-NEXT: %y = lshr i32 %a, 5
|
; CHECK-NEXT: %y = lshr i32 %a, 5
|
||||||
; CHECK-NEXT: ret i32 %y
|
; CHECK-NEXT: ret i32 %y
|
||||||
}
|
}
|
||||||
|
|
||||||
|
define i32 @test46(i32 %a) {
|
||||||
|
%y = ashr exact i32 %a, 3
|
||||||
|
%z = shl i32 %y, 1
|
||||||
|
ret i32 %z
|
||||||
|
; CHECK: @test46
|
||||||
|
; CHECK-NEXT: %z = ashr exact i32 %a, 2
|
||||||
|
; CHECK-NEXT: ret i32 %z
|
||||||
|
}
|
||||||
|
|
||||||
|
define i32 @test47(i32 %a) {
|
||||||
|
%y = lshr exact i32 %a, 3
|
||||||
|
%z = shl i32 %y, 1
|
||||||
|
ret i32 %z
|
||||||
|
; CHECK: @test47
|
||||||
|
; CHECK-NEXT: %z = lshr exact i32 %a, 2
|
||||||
|
; CHECK-NEXT: ret i32 %z
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user