зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1630779 - Fix DefinitelyDifferentValue. r=iain
I think using MConstant::equals was /probably/ fine, but I find it hard to reason about. This also potentially allows comparing double 1.0 to int32 1 or similar. Differential Revision: https://phabricator.services.mozilla.com/D71240
This commit is contained in:
Родитель
e245496607
Коммит
3d95c82e6e
|
@ -4967,31 +4967,55 @@ static bool AddIsANonZeroAdditionOf(MAdd* add, MDefinition* ins) {
|
|||
return true;
|
||||
}
|
||||
|
||||
// Skip over instructions that usually appear between the actual index
|
||||
// value being used and the MLoadElement.
|
||||
// They don't modify the index value in a meaningful way.
|
||||
static MDefinition* SkipUninterestingInstructions(MDefinition* ins) {
|
||||
// Drop the MToNumberInt32 added by the TypePolicy for double and float
|
||||
// values.
|
||||
if (ins->isToNumberInt32()) {
|
||||
return SkipUninterestingInstructions(ins->toToNumberInt32()->input());
|
||||
}
|
||||
|
||||
// Ignore the bounds check, which don't modify the index.
|
||||
if (ins->isBoundsCheck()) {
|
||||
return SkipUninterestingInstructions(ins->toBoundsCheck()->index());
|
||||
}
|
||||
|
||||
// Masking the index for Spectre-mitigation is not observable.
|
||||
if (ins->isSpectreMaskIndex()) {
|
||||
return SkipUninterestingInstructions(ins->toSpectreMaskIndex()->index());
|
||||
}
|
||||
|
||||
return ins;
|
||||
}
|
||||
|
||||
static bool DefinitelyDifferentValue(MDefinition* ins1, MDefinition* ins2) {
|
||||
ins1 = SkipUninterestingInstructions(ins1);
|
||||
ins2 = SkipUninterestingInstructions(ins2);
|
||||
|
||||
if (ins1 == ins2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Drop the MToNumberInt32 added by the TypePolicy for double and float
|
||||
// values.
|
||||
if (ins1->isToNumberInt32()) {
|
||||
return DefinitelyDifferentValue(ins1->toToNumberInt32()->input(), ins2);
|
||||
}
|
||||
if (ins2->isToNumberInt32()) {
|
||||
return DefinitelyDifferentValue(ins2->toToNumberInt32()->input(), ins1);
|
||||
}
|
||||
|
||||
// Ignore the bounds check, which in most cases will contain the same info.
|
||||
if (ins1->isBoundsCheck()) {
|
||||
return DefinitelyDifferentValue(ins1->toBoundsCheck()->index(), ins2);
|
||||
}
|
||||
if (ins2->isBoundsCheck()) {
|
||||
return DefinitelyDifferentValue(ins2->toBoundsCheck()->index(), ins1);
|
||||
}
|
||||
|
||||
// For constants check they are not equal.
|
||||
if (ins1->isConstant() && ins2->isConstant()) {
|
||||
return !ins1->toConstant()->equals(ins2->toConstant());
|
||||
MConstant* cst1 = ins1->toConstant();
|
||||
MConstant* cst2 = ins2->toConstant();
|
||||
|
||||
if (!cst1->isTypeRepresentableAsDouble() ||
|
||||
!cst2->isTypeRepresentableAsDouble()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Be conservative and only allow values that fit into int32.
|
||||
int32_t n1, n2;
|
||||
if (!mozilla::NumberIsInt32(cst1->numberToDouble(), &n1) ||
|
||||
!mozilla::NumberIsInt32(cst2->numberToDouble(), &n2)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return n1 != n2;
|
||||
}
|
||||
|
||||
// Check if "ins1 = ins2 + cte", which would make both instructions
|
||||
|
|
Загрузка…
Ссылка в новой задаче