mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-18 12:29:21 +00:00
Rearrange some code, fold "rem X, 0", implementing rem.ll:test6
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@26411 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
22873462c9
commit
19ccd5c757
@ -1814,6 +1814,17 @@ Instruction *InstCombiner::visitDiv(BinaryOperator &I) {
|
|||||||
|
|
||||||
Instruction *InstCombiner::visitRem(BinaryOperator &I) {
|
Instruction *InstCombiner::visitRem(BinaryOperator &I) {
|
||||||
Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
|
Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
|
||||||
|
|
||||||
|
// 0 % X == 0, we don't need to preserve faults!
|
||||||
|
if (Constant *LHS = dyn_cast<Constant>(Op0))
|
||||||
|
if (LHS->isNullValue())
|
||||||
|
return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType()));
|
||||||
|
|
||||||
|
if (isa<UndefValue>(Op0)) // undef % X -> 0
|
||||||
|
return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType()));
|
||||||
|
if (isa<UndefValue>(Op1))
|
||||||
|
return ReplaceInstUsesWith(I, Op1); // X % undef -> undef
|
||||||
|
|
||||||
if (I.getType()->isSigned()) {
|
if (I.getType()->isSigned()) {
|
||||||
if (Value *RHSNeg = dyn_castNegVal(Op1))
|
if (Value *RHSNeg = dyn_castNegVal(Op1))
|
||||||
if (!isa<ConstantSInt>(RHSNeg) ||
|
if (!isa<ConstantSInt>(RHSNeg) ||
|
||||||
@ -1842,22 +1853,19 @@ Instruction *InstCombiner::visitRem(BinaryOperator &I) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isa<UndefValue>(Op0)) // undef % X -> 0
|
|
||||||
return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType()));
|
|
||||||
if (isa<UndefValue>(Op1))
|
|
||||||
return ReplaceInstUsesWith(I, Op1); // X % undef -> undef
|
|
||||||
|
|
||||||
if (ConstantInt *RHS = dyn_cast<ConstantInt>(Op1)) {
|
if (ConstantInt *RHS = dyn_cast<ConstantInt>(Op1)) {
|
||||||
|
// X % 0 == undef, we don't need to preserve faults!
|
||||||
|
if (RHS->equalsInt(0))
|
||||||
|
return ReplaceInstUsesWith(I, UndefValue::get(I.getType()));
|
||||||
|
|
||||||
if (RHS->equalsInt(1)) // X % 1 == 0
|
if (RHS->equalsInt(1)) // X % 1 == 0
|
||||||
return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType()));
|
return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType()));
|
||||||
|
|
||||||
// Check to see if this is an unsigned remainder with an exact power of 2,
|
// Check to see if this is an unsigned remainder with an exact power of 2,
|
||||||
// if so, convert to a bitwise and.
|
// if so, convert to a bitwise and.
|
||||||
if (ConstantUInt *C = dyn_cast<ConstantUInt>(RHS))
|
if (ConstantUInt *C = dyn_cast<ConstantUInt>(RHS))
|
||||||
if (uint64_t Val = C->getValue()) // Don't break X % 0 (divide by zero)
|
if (isPowerOf2_64(C->getValue()))
|
||||||
if (!(Val & (Val-1))) // Power of 2
|
return BinaryOperator::createAnd(Op0, SubOne(C));
|
||||||
return BinaryOperator::createAnd(Op0,
|
|
||||||
ConstantUInt::get(I.getType(), Val-1));
|
|
||||||
|
|
||||||
if (!RHS->isNullValue()) {
|
if (!RHS->isNullValue()) {
|
||||||
if (SelectInst *SI = dyn_cast<SelectInst>(Op0))
|
if (SelectInst *SI = dyn_cast<SelectInst>(Op0))
|
||||||
@ -1869,6 +1877,20 @@ Instruction *InstCombiner::visitRem(BinaryOperator &I) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Instruction *RHSI = dyn_cast<Instruction>(I.getOperand(1))) {
|
||||||
|
// Turn A % (C << N), where C is 2^k, into A & ((C << N)-1) [urem only].
|
||||||
|
if (I.getType()->isUnsigned() &&
|
||||||
|
RHSI->getOpcode() == Instruction::Shl &&
|
||||||
|
isa<ConstantUInt>(RHSI->getOperand(0))) {
|
||||||
|
unsigned C1 = cast<ConstantUInt>(RHSI->getOperand(0))->getRawValue();
|
||||||
|
if (isPowerOf2_64(C1)) {
|
||||||
|
Constant *N1 = ConstantInt::getAllOnesValue(I.getType());
|
||||||
|
Value *Add = InsertNewInstBefore(BinaryOperator::createAdd(RHSI, N1,
|
||||||
|
"tmp"), I);
|
||||||
|
return BinaryOperator::createAnd(Op0, Add);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// If this is 'urem X, (Cond ? C1, C2)' where C1&C2 are powers of two,
|
// If this is 'urem X, (Cond ? C1, C2)' where C1&C2 are powers of two,
|
||||||
// transform this into: '(Cond ? (urem X, C1) : (urem X, C2))'.
|
// transform this into: '(Cond ? (urem X, C1) : (urem X, C2))'.
|
||||||
if (SelectInst *SI = dyn_cast<SelectInst>(Op1))
|
if (SelectInst *SI = dyn_cast<SelectInst>(Op1))
|
||||||
@ -1882,8 +1904,7 @@ Instruction *InstCombiner::visitRem(BinaryOperator &I) {
|
|||||||
return &I;
|
return &I;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(STO->getValue() & (STO->getValue()-1)) &&
|
if (isPowerOf2_64(STO->getValue()) && isPowerOf2_64(SFO->getValue())){
|
||||||
!(SFO->getValue() & (SFO->getValue()-1))) {
|
|
||||||
Value *TrueAnd = InsertNewInstBefore(BinaryOperator::createAnd(Op0,
|
Value *TrueAnd = InsertNewInstBefore(BinaryOperator::createAnd(Op0,
|
||||||
SubOne(STO), SI->getName()+".t"), I);
|
SubOne(STO), SI->getName()+".t"), I);
|
||||||
Value *FalseAnd = InsertNewInstBefore(BinaryOperator::createAnd(Op0,
|
Value *FalseAnd = InsertNewInstBefore(BinaryOperator::createAnd(Op0,
|
||||||
@ -1891,26 +1912,6 @@ Instruction *InstCombiner::visitRem(BinaryOperator &I) {
|
|||||||
return new SelectInst(SI->getOperand(0), TrueAnd, FalseAnd);
|
return new SelectInst(SI->getOperand(0), TrueAnd, FalseAnd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 0 % X == 0, we don't need to preserve faults!
|
|
||||||
if (ConstantInt *LHS = dyn_cast<ConstantInt>(Op0))
|
|
||||||
if (LHS->equalsInt(0))
|
|
||||||
return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType()));
|
|
||||||
|
|
||||||
|
|
||||||
if (Instruction *RHSI = dyn_cast<Instruction>(I.getOperand(1))) {
|
|
||||||
// Turn A % (C << N), where C is 2^k, into A & ((C << N)-1) [urem only].
|
|
||||||
if (I.getType()->isUnsigned() &&
|
|
||||||
RHSI->getOpcode() == Instruction::Shl &&
|
|
||||||
isa<ConstantUInt>(RHSI->getOperand(0))) {
|
|
||||||
unsigned C1 = cast<ConstantUInt>(RHSI->getOperand(0))->getRawValue();
|
|
||||||
if (isPowerOf2_64(C1)) {
|
|
||||||
Constant *N1 = ConstantInt::getAllOnesValue(I.getType());
|
|
||||||
Value *Add = InsertNewInstBefore(BinaryOperator::createAdd(RHSI, N1,
|
|
||||||
"tmp"), I);
|
|
||||||
return BinaryOperator::createAnd(Op0, Add);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user