Bug 1093356 - IonMonkey: Insert beta nodes for strict eq and ne operators too r=nbp,h4writer

This commit is contained in:
Dan Gohman 2014-11-14 09:31:45 -08:00
Родитель f38db5dd49
Коммит 9c750d7123
3 изменённых файлов: 81 добавлений и 0 удалений

Просмотреть файл

@ -3707,6 +3707,11 @@ class MCompare
bool isFloat32Comparison() const {
return compareType() == Compare_Float32;
}
bool isNumericComparison() const {
return isInt32Comparison() ||
isDoubleComparison() ||
isFloat32Comparison();
}
void setCompareType(CompareType type) {
compareType_ = type;
}

Просмотреть файл

@ -247,9 +247,19 @@ RangeAnalysis::addBetaNodes()
if (bound == 0)
comp.refineToExcludeNegativeZero();
break;
case JSOP_STRICTEQ:
// A strict comparison can test for things other than numeric value.
if (!compare->isNumericComparison())
continue;
// Otherwise fall through to handle JSOP_STRICTEQ the same as JSOP_EQ.
case JSOP_EQ:
comp.setDouble(bound, bound);
break;
case JSOP_STRICTNE:
// A strict comparison can test for things other than numeric value.
if (!compare->isNumericComparison())
continue;
// Otherwise fall through to handle JSOP_STRICTNE the same as JSOP_NE.
case JSOP_NE:
// Negative zero is not not-equal to zero.
if (bound == 0) {

Просмотреть файл

@ -5,6 +5,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/ArrayUtils.h"
#include "jit/IonAnalysis.h"
#include "jit/MIRGenerator.h"
#include "jit/MIRGraph.h"
@ -209,3 +211,67 @@ BEGIN_TEST(testJitRangeAnalysis_MathSignBeta)
return true;
}
END_TEST(testJitRangeAnalysis_MathSignBeta)
BEGIN_TEST(testJitRangeAnalysis_StrictCompareBeta)
{
MinimalFunc func;
MBasicBlock *entry = func.createEntryBlock();
MBasicBlock *thenBlock = func.createBlock(entry);
MBasicBlock *elseBlock = func.createBlock(entry);
// if (p === 0)
MParameter *p = func.createParameter();
entry->add(p);
MConstant *c0 = MConstant::New(func.alloc, DoubleValue(0.0));
entry->add(c0);
MCompare *cmp = MCompare::New(func.alloc, p, c0, JSOP_STRICTEQ);
entry->add(cmp);
entry->end(MTest::New(func.alloc, cmp, thenBlock, elseBlock));
// {
// return p + -0;
// }
MConstant *cm0 = MConstant::New(func.alloc, DoubleValue(-0.0));
thenBlock->add(cm0);
MAdd *thenAdd = MAdd::NewAsmJS(func.alloc, p, cm0, MIRType_Double);
thenBlock->add(thenAdd);
MReturn *thenRet = MReturn::New(func.alloc, thenAdd);
thenBlock->end(thenRet);
// else
// {
// return 0;
// }
MReturn *elseRet = MReturn::New(func.alloc, c0);
elseBlock->end(elseRet);
// If range analysis inserts a beta node for p, it will be able to compute
// a meaningful range for p + -0.
// We can't do beta node insertion with STRICTEQ and a non-numeric
// comparison though.
MCompare::CompareType nonNumerics[] = {
MCompare::Compare_Unknown,
MCompare::Compare_Object,
MCompare::Compare_Value,
MCompare::Compare_String
};
for (size_t i = 0; i < mozilla::ArrayLength(nonNumerics); ++i) {
cmp->setCompareType(nonNumerics[i]);
if (!func.runRangeAnalysis())
return false;
CHECK(!thenAdd->range() || thenAdd->range()->isUnknown());
ClearDominatorTree(func.graph);
}
// We can do it with a numeric comparison.
cmp->setCompareType(MCompare::Compare_Double);
if (!func.runRangeAnalysis())
return false;
CHECK(EquivalentRanges(thenAdd->range(),
Range::NewDoubleRange(func.alloc, 0.0, 0.0)));
return true;
}
END_TEST(testJitRangeAnalysis_StrictCompareBeta)