return (use & (kTypeUint32 | kTypeNumber | kTypeAny)) != 0;
}
+ bool CanObserveNaN(MachineTypeUnion use) {
+ return (use & (kTypeNumber | kTypeAny)) != 0;
+ }
+
bool CanObserveNonUint32(MachineTypeUnion use) {
return (use & (kTypeInt32 | kTypeNumber | kTypeAny)) != 0;
}
if (lower()) DeferReplacement(node, lowering->Int32Mod(node));
break;
}
- if (CanLowerToUint32Binop(node, use)) {
+ if (BothInputsAre(node, Type::Unsigned32()) && !CanObserveNaN(use)) {
// => unsigned Uint32Mod
VisitUint32Binop(node);
if (lower()) DeferReplacement(node, lowering->Uint32Mod(node));
TestingGraph t(test_types[i], test_types[i]);
t.CheckLoweringBinop(IrOpcode::kFloat64Div, t.simplified()->NumberDivide());
- t.CheckLoweringBinop(IrOpcode::kFloat64Mod,
- t.simplified()->NumberModulus());
+ if (!test_types[i]->Is(Type::Unsigned32())) {
+ t.CheckLoweringBinop(IrOpcode::kFloat64Mod,
+ t.simplified()->NumberModulus());
+ }
}
}
CHECK_EQ(IrOpcode::kFloat64Mod, mod->opcode()); // Pesky -0 behavior.
}
}
+
+
+TEST(NumberModulus_Uint32) {
+ const double kConstants[] = {2, 100, 1000, 1024, 2048};
+ const MachineType kTypes[] = {kMachInt32, kMachUint32};
+
+ for (auto const type : kTypes) {
+ for (auto const c : kConstants) {
+ TestingGraph t(Type::Unsigned32());
+ Node* k = t.jsgraph.Constant(c);
+ Node* mod = t.graph()->NewNode(t.simplified()->NumberModulus(), t.p0, k);
+ Node* use = t.Use(mod, type);
+ t.Return(use);
+ t.Lower();
+
+ CHECK_EQ(IrOpcode::kUint32Mod, use->InputAt(0)->opcode());
+ }
+ }
+}