Consistently assume that arithmetic operations can overflow unless one can prove the opposite.
Previously, HDiv never had its CanOverflow flag cleared and HMod had inverted logic (compared to HAdd, HSub and HMul). Minor cleanups on the way. R=jkummerow@chromium.org Review URL: https://codereview.chromium.org/14617015 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@14644 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
ca5fa6b2ce
commit
c1bc396c2d
@ -1445,6 +1445,16 @@ HValue* HMul::Canonicalize() {
|
||||
}
|
||||
|
||||
|
||||
HValue* HMod::Canonicalize() {
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
HValue* HDiv::Canonicalize() {
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
HValue* HChange::Canonicalize() {
|
||||
return (from().Equals(to())) ? value() : this;
|
||||
}
|
||||
@ -1773,20 +1783,22 @@ Range* HMul::InferRange(Zone* zone) {
|
||||
|
||||
Range* HDiv::InferRange(Zone* zone) {
|
||||
if (representation().IsInteger32()) {
|
||||
Range* a = left()->range();
|
||||
Range* b = right()->range();
|
||||
Range* result = new(zone) Range();
|
||||
if (left()->range()->CanBeMinusZero()) {
|
||||
if (a->CanBeMinusZero()) {
|
||||
result->set_can_be_minus_zero(true);
|
||||
}
|
||||
|
||||
if (left()->range()->CanBeZero() && right()->range()->CanBeNegative()) {
|
||||
if (a->CanBeZero() && b->CanBeNegative()) {
|
||||
result->set_can_be_minus_zero(true);
|
||||
}
|
||||
|
||||
if (right()->range()->Includes(-1) && left()->range()->Includes(kMinInt)) {
|
||||
SetFlag(HValue::kCanOverflow);
|
||||
if (!a->Includes(kMinInt) || !b->Includes(-1)) {
|
||||
ClearFlag(HValue::kCanOverflow);
|
||||
}
|
||||
|
||||
if (!right()->range()->CanBeZero()) {
|
||||
if (!b->CanBeZero()) {
|
||||
ClearFlag(HValue::kCanBeDivByZero);
|
||||
}
|
||||
return result;
|
||||
@ -1799,16 +1811,17 @@ Range* HDiv::InferRange(Zone* zone) {
|
||||
Range* HMod::InferRange(Zone* zone) {
|
||||
if (representation().IsInteger32()) {
|
||||
Range* a = left()->range();
|
||||
Range* b = right()->range();
|
||||
Range* result = new(zone) Range();
|
||||
if (a->CanBeMinusZero() || a->CanBeNegative()) {
|
||||
result->set_can_be_minus_zero(true);
|
||||
}
|
||||
|
||||
if (right()->range()->Includes(-1) && left()->range()->Includes(kMinInt)) {
|
||||
SetFlag(HValue::kCanOverflow);
|
||||
if (!a->Includes(kMinInt) || !b->Includes(-1)) {
|
||||
ClearFlag(HValue::kCanOverflow);
|
||||
}
|
||||
|
||||
if (!right()->range()->CanBeZero()) {
|
||||
if (!b->CanBeZero()) {
|
||||
ClearFlag(HValue::kCanBeDivByZero);
|
||||
}
|
||||
return result;
|
||||
|
@ -4414,6 +4414,8 @@ class HMod: public HArithmeticBinaryOperation {
|
||||
|
||||
virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
|
||||
|
||||
virtual HValue* Canonicalize();
|
||||
|
||||
DECLARE_CONCRETE_INSTRUCTION(Mod)
|
||||
|
||||
protected:
|
||||
@ -4425,6 +4427,7 @@ class HMod: public HArithmeticBinaryOperation {
|
||||
HMod(HValue* context, HValue* left, HValue* right)
|
||||
: HArithmeticBinaryOperation(context, left, right) {
|
||||
SetFlag(kCanBeDivByZero);
|
||||
SetFlag(kCanOverflow);
|
||||
}
|
||||
};
|
||||
|
||||
@ -4448,6 +4451,8 @@ class HDiv: public HArithmeticBinaryOperation {
|
||||
|
||||
virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
|
||||
|
||||
virtual HValue* Canonicalize();
|
||||
|
||||
DECLARE_CONCRETE_INSTRUCTION(Div)
|
||||
|
||||
protected:
|
||||
|
Loading…
Reference in New Issue
Block a user