mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-08-09 11:25:55 +00:00
For PR1205:
APIntify visitDiv, visitMul and visitRem. Patch by Zhou Sheng. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@35283 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -2961,11 +2961,10 @@ Instruction *InstCombiner::visitMul(BinaryOperator &I) {
|
|||||||
if (CI->isAllOnesValue()) // X * -1 == 0 - X
|
if (CI->isAllOnesValue()) // X * -1 == 0 - X
|
||||||
return BinaryOperator::createNeg(Op0, I.getName());
|
return BinaryOperator::createNeg(Op0, I.getName());
|
||||||
|
|
||||||
int64_t Val = (int64_t)cast<ConstantInt>(CI)->getZExtValue();
|
APInt Val(cast<ConstantInt>(CI)->getValue());
|
||||||
if (isPowerOf2_64(Val)) { // Replace X*(2^C) with X << C
|
if (Val.isPowerOf2()) { // Replace X*(2^C) with X << C
|
||||||
uint64_t C = Log2_64(Val);
|
|
||||||
return BinaryOperator::createShl(Op0,
|
return BinaryOperator::createShl(Op0,
|
||||||
ConstantInt::get(Op0->getType(), C));
|
ConstantInt::get(Op0->getType(), Val.logBase2()));
|
||||||
}
|
}
|
||||||
} else if (ConstantFP *Op1F = dyn_cast<ConstantFP>(Op1)) {
|
} else if (ConstantFP *Op1F = dyn_cast<ConstantFP>(Op1)) {
|
||||||
if (Op1F->isNullValue())
|
if (Op1F->isNullValue())
|
||||||
@@ -3128,7 +3127,7 @@ Instruction *InstCombiner::commonIDivTransforms(BinaryOperator &I) {
|
|||||||
ConstantExpr::getMul(RHS, LHSRHS));
|
ConstantExpr::getMul(RHS, LHSRHS));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!RHS->isNullValue()) { // avoid X udiv 0
|
if (!RHS->isZero()) { // avoid X udiv 0
|
||||||
if (SelectInst *SI = dyn_cast<SelectInst>(Op0))
|
if (SelectInst *SI = dyn_cast<SelectInst>(Op0))
|
||||||
if (Instruction *R = FoldOpIntoSelect(I, SI, this))
|
if (Instruction *R = FoldOpIntoSelect(I, SI, this))
|
||||||
return R;
|
return R;
|
||||||
@@ -3157,23 +3156,21 @@ Instruction *InstCombiner::visitUDiv(BinaryOperator &I) {
|
|||||||
// Check to see if this is an unsigned division with an exact power of 2,
|
// Check to see if this is an unsigned division with an exact power of 2,
|
||||||
// if so, convert to a right shift.
|
// if so, convert to a right shift.
|
||||||
if (ConstantInt *C = dyn_cast<ConstantInt>(Op1)) {
|
if (ConstantInt *C = dyn_cast<ConstantInt>(Op1)) {
|
||||||
if (uint64_t Val = C->getZExtValue()) // Don't break X / 0
|
APInt Val(C->getValue());
|
||||||
if (isPowerOf2_64(Val)) {
|
if (Val != 0 && Val.isPowerOf2()) // Don't break X / 0
|
||||||
uint64_t ShiftAmt = Log2_64(Val);
|
return BinaryOperator::createLShr(Op0,
|
||||||
return BinaryOperator::createLShr(Op0,
|
ConstantInt::get(Op0->getType(), Val.logBase2()));
|
||||||
ConstantInt::get(Op0->getType(), ShiftAmt));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// X udiv (C1 << N), where C1 is "1<<C2" --> X >> (N+C2)
|
// X udiv (C1 << N), where C1 is "1<<C2" --> X >> (N+C2)
|
||||||
if (BinaryOperator *RHSI = dyn_cast<BinaryOperator>(I.getOperand(1))) {
|
if (BinaryOperator *RHSI = dyn_cast<BinaryOperator>(I.getOperand(1))) {
|
||||||
if (RHSI->getOpcode() == Instruction::Shl &&
|
if (RHSI->getOpcode() == Instruction::Shl &&
|
||||||
isa<ConstantInt>(RHSI->getOperand(0))) {
|
isa<ConstantInt>(RHSI->getOperand(0))) {
|
||||||
uint64_t C1 = cast<ConstantInt>(RHSI->getOperand(0))->getZExtValue();
|
APInt C1(cast<ConstantInt>(RHSI->getOperand(0))->getValue());
|
||||||
if (isPowerOf2_64(C1)) {
|
if (C1.isPowerOf2()) {
|
||||||
Value *N = RHSI->getOperand(1);
|
Value *N = RHSI->getOperand(1);
|
||||||
const Type *NTy = N->getType();
|
const Type *NTy = N->getType();
|
||||||
if (uint64_t C2 = Log2_64(C1)) {
|
if (uint64_t C2 = C1.logBase2()) {
|
||||||
Constant *C2V = ConstantInt::get(NTy, C2);
|
Constant *C2V = ConstantInt::get(NTy, C2);
|
||||||
N = InsertNewInstBefore(BinaryOperator::createAdd(N, C2V, "tmp"), I);
|
N = InsertNewInstBefore(BinaryOperator::createAdd(N, C2V, "tmp"), I);
|
||||||
}
|
}
|
||||||
@@ -3187,10 +3184,10 @@ Instruction *InstCombiner::visitUDiv(BinaryOperator &I) {
|
|||||||
if (SelectInst *SI = dyn_cast<SelectInst>(Op1))
|
if (SelectInst *SI = dyn_cast<SelectInst>(Op1))
|
||||||
if (ConstantInt *STO = dyn_cast<ConstantInt>(SI->getOperand(1)))
|
if (ConstantInt *STO = dyn_cast<ConstantInt>(SI->getOperand(1)))
|
||||||
if (ConstantInt *SFO = dyn_cast<ConstantInt>(SI->getOperand(2))) {
|
if (ConstantInt *SFO = dyn_cast<ConstantInt>(SI->getOperand(2))) {
|
||||||
uint64_t TVA = STO->getZExtValue(), FVA = SFO->getZExtValue();
|
APInt TVA(STO->getValue()), FVA(SFO->getValue());
|
||||||
if (isPowerOf2_64(TVA) && isPowerOf2_64(FVA)) {
|
if (TVA.isPowerOf2() && FVA.isPowerOf2()) {
|
||||||
// Compute the shift amounts
|
// Compute the shift amounts
|
||||||
unsigned TSA = Log2_64(TVA), FSA = Log2_64(FVA);
|
uint32_t TSA = TVA.logBase2(), FSA = FVA.logBase2();
|
||||||
// Construct the "on true" case of the select
|
// Construct the "on true" case of the select
|
||||||
Constant *TC = ConstantInt::get(Op0->getType(), TSA);
|
Constant *TC = ConstantInt::get(Op0->getType(), TSA);
|
||||||
Instruction *TSI = BinaryOperator::createLShr(
|
Instruction *TSI = BinaryOperator::createLShr(
|
||||||
@@ -3230,7 +3227,7 @@ Instruction *InstCombiner::visitSDiv(BinaryOperator &I) {
|
|||||||
// If the sign bits of both operands are zero (i.e. we can prove they are
|
// If the sign bits of both operands are zero (i.e. we can prove they are
|
||||||
// unsigned inputs), turn this into a udiv.
|
// unsigned inputs), turn this into a udiv.
|
||||||
if (I.getType()->isInteger()) {
|
if (I.getType()->isInteger()) {
|
||||||
uint64_t Mask = 1ULL << (I.getType()->getPrimitiveSizeInBits()-1);
|
APInt Mask(APInt::getSignBit(I.getType()->getPrimitiveSizeInBits()));
|
||||||
if (MaskedValueIsZero(Op1, Mask) && MaskedValueIsZero(Op0, Mask)) {
|
if (MaskedValueIsZero(Op1, Mask) && MaskedValueIsZero(Op0, Mask)) {
|
||||||
return BinaryOperator::createUDiv(Op0, Op1, I.getName());
|
return BinaryOperator::createUDiv(Op0, Op1, I.getName());
|
||||||
}
|
}
|
||||||
@@ -3381,7 +3378,7 @@ Instruction *InstCombiner::visitURem(BinaryOperator &I) {
|
|||||||
// 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 (ConstantInt *C = dyn_cast<ConstantInt>(RHS))
|
if (ConstantInt *C = dyn_cast<ConstantInt>(RHS))
|
||||||
if (isPowerOf2_64(C->getZExtValue()))
|
if (C->getValue().isPowerOf2())
|
||||||
return BinaryOperator::createAnd(Op0, SubOne(C));
|
return BinaryOperator::createAnd(Op0, SubOne(C));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3389,8 +3386,8 @@ Instruction *InstCombiner::visitURem(BinaryOperator &I) {
|
|||||||
// Turn A % (C << N), where C is 2^k, into A & ((C << N)-1)
|
// Turn A % (C << N), where C is 2^k, into A & ((C << N)-1)
|
||||||
if (RHSI->getOpcode() == Instruction::Shl &&
|
if (RHSI->getOpcode() == Instruction::Shl &&
|
||||||
isa<ConstantInt>(RHSI->getOperand(0))) {
|
isa<ConstantInt>(RHSI->getOperand(0))) {
|
||||||
unsigned C1 = cast<ConstantInt>(RHSI->getOperand(0))->getZExtValue();
|
APInt C1(cast<ConstantInt>(RHSI->getOperand(0))->getValue());
|
||||||
if (isPowerOf2_64(C1)) {
|
if (C1.isPowerOf2()) {
|
||||||
Constant *N1 = ConstantInt::getAllOnesValue(I.getType());
|
Constant *N1 = ConstantInt::getAllOnesValue(I.getType());
|
||||||
Value *Add = InsertNewInstBefore(BinaryOperator::createAdd(RHSI, N1,
|
Value *Add = InsertNewInstBefore(BinaryOperator::createAdd(RHSI, N1,
|
||||||
"tmp"), I);
|
"tmp"), I);
|
||||||
@@ -3405,8 +3402,8 @@ Instruction *InstCombiner::visitURem(BinaryOperator &I) {
|
|||||||
if (ConstantInt *STO = dyn_cast<ConstantInt>(SI->getOperand(1)))
|
if (ConstantInt *STO = dyn_cast<ConstantInt>(SI->getOperand(1)))
|
||||||
if (ConstantInt *SFO = dyn_cast<ConstantInt>(SI->getOperand(2))) {
|
if (ConstantInt *SFO = dyn_cast<ConstantInt>(SI->getOperand(2))) {
|
||||||
// STO == 0 and SFO == 0 handled above.
|
// STO == 0 and SFO == 0 handled above.
|
||||||
if (isPowerOf2_64(STO->getZExtValue()) &&
|
if ((STO->getValue().isPowerOf2()) &&
|
||||||
isPowerOf2_64(SFO->getZExtValue())) {
|
(SFO->getValue().isPowerOf2())) {
|
||||||
Value *TrueAnd = InsertNewInstBefore(
|
Value *TrueAnd = InsertNewInstBefore(
|
||||||
BinaryOperator::createAnd(Op0, SubOne(STO), SI->getName()+".t"), I);
|
BinaryOperator::createAnd(Op0, SubOne(STO), SI->getName()+".t"), I);
|
||||||
Value *FalseAnd = InsertNewInstBefore(
|
Value *FalseAnd = InsertNewInstBefore(
|
||||||
@@ -3427,7 +3424,7 @@ Instruction *InstCombiner::visitSRem(BinaryOperator &I) {
|
|||||||
|
|
||||||
if (Value *RHSNeg = dyn_castNegVal(Op1))
|
if (Value *RHSNeg = dyn_castNegVal(Op1))
|
||||||
if (!isa<ConstantInt>(RHSNeg) ||
|
if (!isa<ConstantInt>(RHSNeg) ||
|
||||||
cast<ConstantInt>(RHSNeg)->getSExtValue() > 0) {
|
cast<ConstantInt>(RHSNeg)->getValue().isPositive()) {
|
||||||
// X % -Y -> X % Y
|
// X % -Y -> X % Y
|
||||||
AddUsesToWorkList(I);
|
AddUsesToWorkList(I);
|
||||||
I.setOperand(1, RHSNeg);
|
I.setOperand(1, RHSNeg);
|
||||||
@@ -3436,7 +3433,7 @@ Instruction *InstCombiner::visitSRem(BinaryOperator &I) {
|
|||||||
|
|
||||||
// If the top bits of both operands are zero (i.e. we can prove they are
|
// If the top bits of both operands are zero (i.e. we can prove they are
|
||||||
// unsigned inputs), turn this into a urem.
|
// unsigned inputs), turn this into a urem.
|
||||||
uint64_t Mask = 1ULL << (I.getType()->getPrimitiveSizeInBits()-1);
|
APInt Mask(APInt::getSignBit(I.getType()->getPrimitiveSizeInBits()));
|
||||||
if (MaskedValueIsZero(Op1, Mask) && MaskedValueIsZero(Op0, Mask)) {
|
if (MaskedValueIsZero(Op1, Mask) && MaskedValueIsZero(Op0, Mask)) {
|
||||||
// X srem Y -> X urem Y, iff X and Y don't have sign bit set
|
// X srem Y -> X urem Y, iff X and Y don't have sign bit set
|
||||||
return BinaryOperator::createURem(Op0, Op1, I.getName());
|
return BinaryOperator::createURem(Op0, Op1, I.getName());
|
||||||
|
Reference in New Issue
Block a user