From ca2bc9ebb659d17806cf6a8e278772b980fc723c Mon Sep 17 00:00:00 2001 From: Benjamin Bouvier Date: Thu, 12 Sep 2013 14:54:01 -0700 Subject: [PATCH] Bug 915301: Check Float32 coherency; r=sstangl --- js/src/jit-test/tests/ion/bug915301.js | 23 +++++++++++++++ js/src/jit/IonAnalysis.cpp | 39 ++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 js/src/jit-test/tests/ion/bug915301.js diff --git a/js/src/jit-test/tests/ion/bug915301.js b/js/src/jit-test/tests/ion/bug915301.js new file mode 100644 index 00000000000..941ef8c1773 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug915301.js @@ -0,0 +1,23 @@ +setJitCompilerOption("ion.usecount.trigger", 50); +var f32 = new Float32Array(32); +f32[0] = 0; + +function g(x) { + eval(""); // don't inline + return x + 4; +} + +function f(n) { + var x; + if (n > 10000) { + x = 4.5; + } else { + x = f32[0]; + } + f32[0] = g(x); +} + +for (var n = 0; n < 100; n++) + f(n); + +assertEq(f32[0], 400); diff --git a/js/src/jit/IonAnalysis.cpp b/js/src/jit/IonAnalysis.cpp index f20d19c4045..ea980fc7999 100644 --- a/js/src/jit/IonAnalysis.cpp +++ b/js/src/jit/IonAnalysis.cpp @@ -400,6 +400,7 @@ class TypeAnalyzer bool adjustInputs(MDefinition *def); bool insertConversions(); + bool checkFloatCoherency(); bool graphContainsFloat32(); bool markPhiConsumers(); bool markPhiProducers(); @@ -900,6 +901,42 @@ TypeAnalyzer::tryEmitFloatOperations() return true; } +bool +TypeAnalyzer::checkFloatCoherency() +{ +#ifdef DEBUG + // Asserts that all Float32 instructions are flowing into Float32 consumers or specialized + // operations + for (ReversePostorderIterator block(graph.rpoBegin()); block != graph.rpoEnd(); ++block) { + if (mir->shouldCancel("Check Float32 coherency")) + return false; + + for (MDefinitionIterator def(*block); def; def++) { + if (def->type() != MIRType_Float32) + continue; + if (def->isPassArg()) // no check for PassArg as it is broken, see bug 915479 + continue; + + for (MUseDefIterator use(*def); use; use++) { + MDefinition *consumer = use.def(); + // The only valid uses of a Float32 are: + // - an operation that can consume Float32 + // - an operation that has been specialized to Float32 (for instance, an add) + // - a conversion to Double + if (consumer->canConsumeFloat32()) + continue; + if (consumer->type() == MIRType_Float32) + continue; + if (consumer->isToDouble()) + continue; + MOZ_ASSUME_UNREACHABLE("Float32 flowing into a non float specialized operation"); + } + } + } +#endif + return true; +} + bool TypeAnalyzer::analyze() { @@ -909,6 +946,8 @@ TypeAnalyzer::analyze() return false; if (!insertConversions()) return false; + if (!checkFloatCoherency()) + return false; return true; }