mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-09-07 16:54:48 +00:00
Add value range analyzing of Add and Sub.
Understand that mul %x, 1 = %x. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@58069 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
06587497dc
commit
79cce5c51b
@ -1938,6 +1938,7 @@ namespace {
|
|||||||
assert(!Ty->isFPOrFPVector() && "Float in work queue!");
|
assert(!Ty->isFPOrFPVector() && "Float in work queue!");
|
||||||
|
|
||||||
Constant *Zero = Constant::getNullValue(Ty);
|
Constant *Zero = Constant::getNullValue(Ty);
|
||||||
|
Constant *One = ConstantInt::get(Ty, 1);
|
||||||
ConstantInt *AllOnes = ConstantInt::getAllOnesValue(Ty);
|
ConstantInt *AllOnes = ConstantInt::getAllOnesValue(Ty);
|
||||||
|
|
||||||
switch (Opcode) {
|
switch (Opcode) {
|
||||||
@ -1945,19 +1946,73 @@ namespace {
|
|||||||
case Instruction::LShr:
|
case Instruction::LShr:
|
||||||
case Instruction::AShr:
|
case Instruction::AShr:
|
||||||
case Instruction::Shl:
|
case Instruction::Shl:
|
||||||
|
if (Op1 == Zero) {
|
||||||
|
add(BO, Op0, ICmpInst::ICMP_EQ, NewContext);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case Instruction::Sub:
|
case Instruction::Sub:
|
||||||
if (Op1 == Zero) {
|
if (Op1 == Zero) {
|
||||||
add(BO, Op0, ICmpInst::ICMP_EQ, NewContext);
|
add(BO, Op0, ICmpInst::ICMP_EQ, NewContext);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (ConstantInt *CI0 = dyn_cast<ConstantInt>(Op0)) {
|
||||||
|
unsigned n_ci0 = VN.getOrInsertVN(Op1, Top);
|
||||||
|
ConstantRange CR = VR.range(n_ci0, Top);
|
||||||
|
if (!CR.isFullSet()) {
|
||||||
|
CR.subtract(CI0->getValue());
|
||||||
|
unsigned n_bo = VN.getOrInsertVN(BO, Top);
|
||||||
|
VR.applyRange(n_bo, CR, Top, this);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ConstantInt *CI1 = dyn_cast<ConstantInt>(Op1)) {
|
||||||
|
unsigned n_ci1 = VN.getOrInsertVN(Op0, Top);
|
||||||
|
ConstantRange CR = VR.range(n_ci1, Top);
|
||||||
|
if (!CR.isFullSet()) {
|
||||||
|
CR.subtract(CI1->getValue());
|
||||||
|
unsigned n_bo = VN.getOrInsertVN(BO, Top);
|
||||||
|
VR.applyRange(n_bo, CR, Top, this);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case Instruction::Or:
|
case Instruction::Or:
|
||||||
if (Op0 == AllOnes || Op1 == AllOnes) {
|
if (Op0 == AllOnes || Op1 == AllOnes) {
|
||||||
add(BO, AllOnes, ICmpInst::ICMP_EQ, NewContext);
|
add(BO, AllOnes, ICmpInst::ICMP_EQ, NewContext);
|
||||||
return;
|
return;
|
||||||
} // fall-through
|
}
|
||||||
case Instruction::Xor:
|
if (Op0 == Zero) {
|
||||||
|
add(BO, Op1, ICmpInst::ICMP_EQ, NewContext);
|
||||||
|
return;
|
||||||
|
} else if (Op1 == Zero) {
|
||||||
|
add(BO, Op0, ICmpInst::ICMP_EQ, NewContext);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case Instruction::Add:
|
case Instruction::Add:
|
||||||
|
if (ConstantInt *CI0 = dyn_cast<ConstantInt>(Op0)) {
|
||||||
|
unsigned n_ci0 = VN.getOrInsertVN(Op1, Top);
|
||||||
|
ConstantRange CR = VR.range(n_ci0, Top);
|
||||||
|
if (!CR.isFullSet()) {
|
||||||
|
CR.subtract(-CI0->getValue());
|
||||||
|
unsigned n_bo = VN.getOrInsertVN(BO, Top);
|
||||||
|
VR.applyRange(n_bo, CR, Top, this);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ConstantInt *CI1 = dyn_cast<ConstantInt>(Op1)) {
|
||||||
|
unsigned n_ci1 = VN.getOrInsertVN(Op0, Top);
|
||||||
|
ConstantRange CR = VR.range(n_ci1, Top);
|
||||||
|
if (!CR.isFullSet()) {
|
||||||
|
CR.subtract(-CI1->getValue());
|
||||||
|
unsigned n_bo = VN.getOrInsertVN(BO, Top);
|
||||||
|
VR.applyRange(n_bo, CR, Top, this);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// fall-through
|
||||||
|
case Instruction::Xor:
|
||||||
if (Op0 == Zero) {
|
if (Op0 == Zero) {
|
||||||
add(BO, Op1, ICmpInst::ICMP_EQ, NewContext);
|
add(BO, Op1, ICmpInst::ICMP_EQ, NewContext);
|
||||||
return;
|
return;
|
||||||
@ -1974,19 +2029,30 @@ namespace {
|
|||||||
add(BO, Op0, ICmpInst::ICMP_EQ, NewContext);
|
add(BO, Op0, ICmpInst::ICMP_EQ, NewContext);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// fall-through
|
if (Op0 == Zero || Op1 == Zero) {
|
||||||
|
add(BO, Zero, ICmpInst::ICMP_EQ, NewContext);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case Instruction::Mul:
|
case Instruction::Mul:
|
||||||
if (Op0 == Zero || Op1 == Zero) {
|
if (Op0 == Zero || Op1 == Zero) {
|
||||||
add(BO, Zero, ICmpInst::ICMP_EQ, NewContext);
|
add(BO, Zero, ICmpInst::ICMP_EQ, NewContext);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (Op0 == One) {
|
||||||
|
add(BO, Op1, ICmpInst::ICMP_EQ, NewContext);
|
||||||
|
return;
|
||||||
|
} else if (Op1 == One) {
|
||||||
|
add(BO, Op0, ICmpInst::ICMP_EQ, NewContext);
|
||||||
|
return;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// "%x = add i32 %y, %z" and %x EQ %y then %z EQ 0
|
// "%x = add i32 %y, %z" and %x EQ %y then %z EQ 0
|
||||||
// "%x = add i32 %y, %z" and %x EQ %z then %y EQ 0
|
// "%x = add i32 %y, %z" and %x EQ %z then %y EQ 0
|
||||||
// "%x = shl i32 %y, %z" and %x EQ %y and %y NE 0 then %z EQ 0
|
// "%x = shl i32 %y, %z" and %x EQ %y and %y NE 0 then %z EQ 0
|
||||||
// "%x = udiv i32 %y, %z" and %x EQ %y then %z EQ 1
|
// "%x = udiv i32 %y, %z" and %x EQ %y and %y NE 0 then %z EQ 1
|
||||||
|
|
||||||
Value *Known = Op0, *Unknown = Op1,
|
Value *Known = Op0, *Unknown = Op1,
|
||||||
*TheBO = VN.canonicalize(BO, Top);
|
*TheBO = VN.canonicalize(BO, Top);
|
||||||
@ -2009,10 +2075,8 @@ namespace {
|
|||||||
case Instruction::UDiv:
|
case Instruction::UDiv:
|
||||||
case Instruction::SDiv:
|
case Instruction::SDiv:
|
||||||
if (Unknown == Op1) break;
|
if (Unknown == Op1) break;
|
||||||
if (isRelatedBy(Known, Zero, ICmpInst::ICMP_NE)) {
|
if (isRelatedBy(Known, Zero, ICmpInst::ICMP_NE))
|
||||||
Constant *One = ConstantInt::get(Ty, 1);
|
|
||||||
add(Unknown, One, ICmpInst::ICMP_EQ, NewContext);
|
add(Unknown, One, ICmpInst::ICMP_EQ, NewContext);
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2488,7 +2552,7 @@ namespace {
|
|||||||
|
|
||||||
void PredicateSimplifier::Forwards::visitLoadInst(LoadInst &LI) {
|
void PredicateSimplifier::Forwards::visitLoadInst(LoadInst &LI) {
|
||||||
Value *Ptr = LI.getPointerOperand();
|
Value *Ptr = LI.getPointerOperand();
|
||||||
// avoid "load uint* null" -> null NE null.
|
// avoid "load i8* null" -> null NE null.
|
||||||
if (isa<Constant>(Ptr)) return;
|
if (isa<Constant>(Ptr)) return;
|
||||||
|
|
||||||
VRPSolver VRP(VN, IG, UB, VR, PS->DTDFS, PS->modified, &LI);
|
VRPSolver VRP(VN, IG, UB, VR, PS->DTDFS, PS->modified, &LI);
|
||||||
@ -2624,8 +2688,8 @@ namespace {
|
|||||||
if (!Op1->getValue().isAllOnesValue())
|
if (!Op1->getValue().isAllOnesValue())
|
||||||
NextVal = ConstantInt::get(Op1->getValue()+1);
|
NextVal = ConstantInt::get(Op1->getValue()+1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NextVal) {
|
if (NextVal) {
|
||||||
VRPSolver VRP(VN, IG, UB, VR, PS->DTDFS, PS->modified, &IC);
|
VRPSolver VRP(VN, IG, UB, VR, PS->DTDFS, PS->modified, &IC);
|
||||||
if (VRP.isRelatedBy(IC.getOperand(0), NextVal,
|
if (VRP.isRelatedBy(IC.getOperand(0), NextVal,
|
||||||
|
Loading…
Reference in New Issue
Block a user