in vm/jitrino/src/optimizer/hashvaluenumberer.cpp [1530:1680]
bool allowsAnyZeroElimination(ComparisonModifier mod, Type::Tag comparisonType,
Opnd *src0, Opnd *src1, bool isTrueEdge,
Opnd **opnd)
{
bool positive = false;
switch (mod) {
case Cmp_EQ:
positive = true;
case Cmp_NE_Un:
{
bool canelim = false;
ConstInst::ConstValue cv;
Opnd *constOpnd = 0;
Opnd *otherOpnd = 0;
if (ConstantFolder::isConstant(src0->getInst(), cv)) {
constOpnd = src0;
otherOpnd = src1;
} else if (ConstantFolder::isConstant(src1->getInst(), cv)) {
constOpnd = src1;
otherOpnd = src0;
} else {
return false;
}
bool notEqual = isTrueEdge ^ positive; // we know (nonconst != const)
switch (constOpnd->getInst()->getType()) {
case Type::Int8: case Type::Int16: case Type::Int32:
case Type::UInt8: case Type::UInt16: case Type::UInt32:
canelim = (notEqual ? (cv.i4 == 0) : (cv.i4 != 0)); break;
case Type::Int64:
case Type::UInt64:
canelim = (notEqual ? (cv.i8 == 0) : (cv.i8 != 0)); break;
case Type::IntPtr:
case Type::UIntPtr:
case Type::ManagedPtr: case Type::UnmanagedPtr:
case Type::SystemObject: case Type::SystemClass: case Type::SystemString:
case Type::Array: case Type::Object:
case Type::BoxedValue:
case Type::MethodPtr: case Type::VTablePtr:
case Type::CompressedSystemObject:
case Type::CompressedSystemClass:
case Type::CompressedSystemString:
case Type::CompressedArray: case Type::CompressedObject:
canelim = (notEqual ? (cv.i == 0) : (cv.i != 0)); break;
case Type::NullObject:
case Type::CompressedNullObject:
canelim = notEqual; break;
default:
break;
}
if (canelim) {
*opnd = otherOpnd;
return true;
}
}
break;
case Cmp_GT:
case Cmp_GT_Un:
positive = true;
case Cmp_GTE:
case Cmp_GTE_Un:
if (isTrueEdge) {
Inst *src1inst = src1->getInst();
ConstInst::ConstValue cv;
if (ConstantFolder::isConstant(src1inst, cv)) {
bool canelim = false;
switch (src1inst->getType()) {
case Type::Int8: case Type::Int16: case Type::Int32:
canelim = (positive ? (cv.i4 >= 0) : (cv.i4 > 0)); break;
case Type::Int64:
canelim = (positive ? (cv.i8 >= 0) : (cv.i8 > 0)); break;
case Type::IntPtr:
canelim = (positive ? true : (cv.i != 0)); break;
case Type::UInt8: case Type::UInt16: case Type::UInt32:
canelim = (positive ? true : (cv.i4 != 0)); break;
case Type::UInt64:
canelim = (positive ? true : (cv.i8 != 0)); break;
case Type::UIntPtr:
canelim = (positive ? true : (cv.i != 0)); break;
default:
break;
}
if (canelim) {
*opnd = src0;
return true;
}
}
} else {
Inst *src0inst = src0->getInst();
ConstInst::ConstValue cv;
if (ConstantFolder::isConstant(src0inst, cv)) {
bool canelim = false;
switch (src0inst->getType()) {
case Type::Int8: case Type::Int16: case Type::Int32:
canelim = (positive ? (cv.i4 <= 0) : (cv.i4 < 0)); break;
case Type::Int64:
canelim = (positive ? (cv.i8 <= 0) : (cv.i8 < 0)); break;
case Type::IntPtr:
canelim = (positive ? true : (cv.i != 0)); break;
case Type::UInt8: case Type::UInt16: case Type::UInt32:
canelim = (positive ? true : (cv.i4 != 0)); break;
case Type::UInt64:
canelim = (positive ? true : (cv.i8 != 0)); break;
case Type::UIntPtr:
canelim = (positive ? true : (cv.i != 0)); break;
default:
break;
}
if (canelim) {
*opnd = src1;
return true;
}
}
}
break;
case Cmp_Zero:
positive = true;
case Cmp_NonZero:
{
bool canelim = false;
switch (src0->getInst()->getType()) {
case Type::Int8: case Type::Int16: case Type::Int32:
case Type::UInt8: case Type::UInt16: case Type::UInt32:
case Type::Int64:
case Type::UInt64:
case Type::IntPtr:
case Type::UIntPtr:
case Type::ManagedPtr: case Type::UnmanagedPtr:
case Type::SystemObject: case Type::SystemClass: case Type::SystemString:
case Type::Array: case Type::Object: case Type::BoxedValue:
case Type::MethodPtr: case Type::VTablePtr:
case Type::CompressedSystemObject:
case Type::CompressedSystemClass:
case Type::CompressedSystemString:
case Type::CompressedArray: case Type::CompressedObject:
canelim = positive ^ isTrueEdge; break;
case Type::NullObject: case Type::CompressedNullObject:
default:
break;
}
if (canelim) {
*opnd = src0;
return true;
}
}
break;
default:
assert(0);
break;
}
return false;
}