mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-02-01 05:01:59 +01:00
[InstCombine] allow shl+shr demanded bits folds with splat constants
llvm-svn: 300911
This commit is contained in:
parent
5a205db771
commit
aaccb178b4
@ -551,9 +551,10 @@ private:
|
||||
unsigned Depth, Instruction *CxtI);
|
||||
/// Helper routine of SimplifyDemandedUseBits. It tries to simplify demanded
|
||||
/// bit for "r1 = shr x, c1; r2 = shl r1, c2" instruction sequence.
|
||||
Value *SimplifyShrShlDemandedBits(Instruction *Lsr, Instruction *Sftl,
|
||||
const APInt &DemandedMask, APInt &KnownZero,
|
||||
APInt &KnownOne);
|
||||
Value *SimplifyShrShlDemandedBits(
|
||||
Instruction *Shr, const APInt &ShrOp1, Instruction *Shl,
|
||||
const APInt &ShlOp1, const APInt &DemandedMask, APInt &KnownZero,
|
||||
APInt &KnownOne);
|
||||
|
||||
/// \brief Tries to simplify operands to an integer instruction based on its
|
||||
/// demanded bits.
|
||||
|
@ -472,15 +472,12 @@ Value *InstCombiner::SimplifyDemandedUseBits(Value *V, APInt DemandedMask,
|
||||
case Instruction::Shl: {
|
||||
const APInt *SA;
|
||||
if (match(I->getOperand(1), m_APInt(SA))) {
|
||||
{
|
||||
Value *VarX; ConstantInt *C1;
|
||||
if (match(I->getOperand(0), m_Shr(m_Value(VarX), m_ConstantInt(C1)))) {
|
||||
Instruction *Shr = cast<Instruction>(I->getOperand(0));
|
||||
Value *R = SimplifyShrShlDemandedBits(Shr, I, DemandedMask,
|
||||
KnownZero, KnownOne);
|
||||
if (R)
|
||||
return R;
|
||||
}
|
||||
const APInt *ShrAmt;
|
||||
if (match(I->getOperand(0), m_Shr(m_Value(), m_APInt(ShrAmt)))) {
|
||||
Instruction *Shr = cast<Instruction>(I->getOperand(0));
|
||||
if (Value *R = SimplifyShrShlDemandedBits(
|
||||
Shr, *ShrAmt, I, *SA, DemandedMask, KnownZero, KnownOne))
|
||||
return R;
|
||||
}
|
||||
|
||||
uint64_t ShiftAmt = SA->getLimitedValue(BitWidth-1);
|
||||
@ -876,20 +873,17 @@ Value *InstCombiner::SimplifyMultipleUseDemandedBits(Instruction *I,
|
||||
///
|
||||
/// As with SimplifyDemandedUseBits, it returns NULL if the simplification was
|
||||
/// not successful.
|
||||
Value *InstCombiner::SimplifyShrShlDemandedBits(Instruction *Shr,
|
||||
Instruction *Shl,
|
||||
const APInt &DemandedMask,
|
||||
APInt &KnownZero,
|
||||
APInt &KnownOne) {
|
||||
|
||||
const APInt &ShlOp1 = cast<ConstantInt>(Shl->getOperand(1))->getValue();
|
||||
const APInt &ShrOp1 = cast<ConstantInt>(Shr->getOperand(1))->getValue();
|
||||
Value *
|
||||
InstCombiner::SimplifyShrShlDemandedBits(Instruction *Shr, const APInt &ShrOp1,
|
||||
Instruction *Shl, const APInt &ShlOp1,
|
||||
const APInt &DemandedMask,
|
||||
APInt &KnownZero, APInt &KnownOne) {
|
||||
if (!ShlOp1 || !ShrOp1)
|
||||
return nullptr; // Noop.
|
||||
return nullptr; // No-op.
|
||||
|
||||
Value *VarX = Shr->getOperand(0);
|
||||
Type *Ty = VarX->getType();
|
||||
unsigned BitWidth = Ty->getIntegerBitWidth();
|
||||
unsigned BitWidth = Ty->getScalarSizeInBits();
|
||||
if (ShlOp1.uge(BitWidth) || ShrOp1.uge(BitWidth))
|
||||
return nullptr; // Undef.
|
||||
|
||||
|
@ -1075,9 +1075,8 @@ define i32 @test54(i32 %x) {
|
||||
|
||||
define <2 x i32> @test54_splat_vec(<2 x i32> %x) {
|
||||
; CHECK-LABEL: @test54_splat_vec(
|
||||
; CHECK-NEXT: [[SHR2:%.*]] = lshr <2 x i32> %x, <i32 1, i32 1>
|
||||
; CHECK-NEXT: [[SHL:%.*]] = shl <2 x i32> [[SHR2]], <i32 4, i32 4>
|
||||
; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> [[SHL]], <i32 16, i32 16>
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = shl <2 x i32> %x, <i32 3, i32 3>
|
||||
; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> [[TMP1]], <i32 16, i32 16>
|
||||
; CHECK-NEXT: ret <2 x i32> [[AND]]
|
||||
;
|
||||
%shr2 = lshr <2 x i32> %x, <i32 1, i32 1>
|
||||
@ -1138,9 +1137,8 @@ define i32 @test58(i32 %x) {
|
||||
|
||||
define <2 x i32> @test58_splat_vec(<2 x i32> %x) {
|
||||
; CHECK-LABEL: @test58_splat_vec(
|
||||
; CHECK-NEXT: [[SHR:%.*]] = ashr <2 x i32> %x, <i32 4, i32 4>
|
||||
; CHECK-NEXT: [[SHL:%.*]] = shl nsw <2 x i32> [[SHR]], <i32 1, i32 1>
|
||||
; CHECK-NEXT: [[OR:%.*]] = or <2 x i32> [[SHL]], <i32 1, i32 1>
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = ashr <2 x i32> %x, <i32 3, i32 3>
|
||||
; CHECK-NEXT: [[OR:%.*]] = or <2 x i32> [[TMP1]], <i32 1, i32 1>
|
||||
; CHECK-NEXT: ret <2 x i32> [[OR]]
|
||||
;
|
||||
%shr = ashr <2 x i32> %x, <i32 4, i32 4>
|
||||
|
Loading…
x
Reference in New Issue
Block a user