B3ReduceStrength should reduce EqualOrUnordered over const float input
authorsbarati@apple.com <sbarati@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 1 Jul 2017 03:35:47 +0000 (03:35 +0000)
committersbarati@apple.com <sbarati@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 1 Jul 2017 03:35:47 +0000 (03:35 +0000)
https://bugs.webkit.org/show_bug.cgi?id=174039

Reviewed by Michael Saboff.

We perform this folding for ConstDoubleValue. It is simply
an oversight that we didn't do it for ConstFloatValue.

* b3/B3ConstFloatValue.cpp:
(JSC::B3::ConstFloatValue::equalOrUnorderedConstant):
* b3/B3ConstFloatValue.h:
* b3/testb3.cpp:
(JSC::B3::testFloatEqualOrUnorderedFolding):
(JSC::B3::testFloatEqualOrUnorderedFoldingNaN):
(JSC::B3::testFloatEqualOrUnorderedDontFold):
(JSC::B3::run):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@219038 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/b3/B3ConstFloatValue.cpp
Source/JavaScriptCore/b3/B3ConstFloatValue.h
Source/JavaScriptCore/b3/testb3.cpp

index 19dc3c2..bfb8a62 100644 (file)
@@ -1,3 +1,22 @@
+2017-06-30  Saam Barati  <sbarati@apple.com>
+
+        B3ReduceStrength should reduce EqualOrUnordered over const float input
+        https://bugs.webkit.org/show_bug.cgi?id=174039
+
+        Reviewed by Michael Saboff.
+
+        We perform this folding for ConstDoubleValue. It is simply
+        an oversight that we didn't do it for ConstFloatValue.
+
+        * b3/B3ConstFloatValue.cpp:
+        (JSC::B3::ConstFloatValue::equalOrUnorderedConstant):
+        * b3/B3ConstFloatValue.h:
+        * b3/testb3.cpp:
+        (JSC::B3::testFloatEqualOrUnorderedFolding):
+        (JSC::B3::testFloatEqualOrUnorderedFoldingNaN):
+        (JSC::B3::testFloatEqualOrUnorderedDontFold):
+        (JSC::B3::run):
+
 2017-06-30  Matt Baker  <mattbaker@apple.com>
 
         Web Inspector: AsyncStackTrace nodes can be corrupted when truncating
index 76facae..d3cb033 100644 (file)
@@ -172,6 +172,17 @@ TriState ConstFloatValue::greaterEqualConstant(const Value* other) const
     return triState(m_value >= other->asFloat());
 }
 
+TriState ConstFloatValue::equalOrUnorderedConstant(const Value* other) const
+{
+    if (std::isnan(m_value))
+        return TrueTriState;
+
+    if (!other->hasFloat())
+        return MixedTriState;
+    float otherValue = other->asFloat();
+    return triState(std::isunordered(m_value, otherValue) || m_value == otherValue);
+}
+
 void ConstFloatValue::dumpMeta(CommaPrinter& comma, PrintStream& out) const
 {
     out.print(comma);
index 185583c..35dd2e0 100644 (file)
@@ -61,6 +61,7 @@ public:
     TriState greaterThanConstant(const Value* other) const override;
     TriState lessEqualConstant(const Value* other) const override;
     TriState greaterEqualConstant(const Value* other) const override;
+    TriState equalOrUnorderedConstant(const Value* other) const override;
 
 protected:
     void dumpMeta(CommaPrinter&, PrintStream&) const override;
index 1075643..73ddb64 100644 (file)
@@ -15473,6 +15473,78 @@ void testDoubleLiteralComparison(double a, double b)
     }
 }
 
+void testFloatEqualOrUnorderedFolding()
+{
+    for (auto& first : floatingPointOperands<float>()) {
+        for (auto& second : floatingPointOperands<float>()) {
+            float a = first.value;
+            float b = second.value;
+            bool expectedResult = (a == b) || std::isunordered(a, b);
+            Procedure proc;
+            BasicBlock* root = proc.addBlock();
+            Value* constA = root->appendNew<ConstFloatValue>(proc, Origin(), a);
+            Value* constB = root->appendNew<ConstFloatValue>(proc, Origin(), b);
+
+            root->appendNewControlValue(proc, Return, Origin(),
+                root->appendNew<Value>(
+                    proc, EqualOrUnordered, Origin(),
+                    constA,
+                    constB));
+            CHECK(!!compileAndRun<int32_t>(proc) == expectedResult);
+        }
+    }
+}
+
+void testFloatEqualOrUnorderedFoldingNaN()
+{
+    std::list<float> nans = {
+        bitwise_cast<float>(0xfffffffd),
+        bitwise_cast<float>(0xfffffffe),
+        bitwise_cast<float>(0xfffffff0),
+        static_cast<float>(PNaN),
+    };
+
+    unsigned i = 0;
+    for (float nan : nans) {
+        RELEASE_ASSERT(std::isnan(nan));
+        Procedure proc;
+        BasicBlock* root = proc.addBlock();
+        Value* a = root->appendNew<ConstFloatValue>(proc, Origin(), nan);
+        Value* b = root->appendNew<Value>(proc, DoubleToFloat, Origin(),
+            root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0));
+
+        if (i % 2)
+            std::swap(a, b);
+        ++i;
+        root->appendNewControlValue(proc, Return, Origin(),
+            root->appendNew<Value>(proc, EqualOrUnordered, Origin(), a, b));
+        CHECK(!!compileAndRun<int32_t>(proc, static_cast<double>(1.0)));
+    }
+}
+
+void testFloatEqualOrUnorderedDontFold()
+{
+    for (auto& first : floatingPointOperands<float>()) {
+        float a = first.value;
+        Procedure proc;
+        BasicBlock* root = proc.addBlock();
+        Value* constA = root->appendNew<ConstFloatValue>(proc, Origin(), a);
+        Value* b = root->appendNew<Value>(proc, DoubleToFloat, Origin(),
+            root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0));
+        root->appendNewControlValue(proc, Return, Origin(),
+            root->appendNew<Value>(
+                proc, EqualOrUnordered, Origin(), constA, b));
+
+        auto code = compileProc(proc);
+
+        for (auto& second : floatingPointOperands<float>()) {
+            float b = second.value;
+            bool expectedResult = (a == b) || std::isunordered(a, b);
+            CHECK(!!invoke<int32_t>(*code, static_cast<double>(b)) == expectedResult);
+        }
+    }
+}
+
 // Make sure the compiler does not try to optimize anything out.
 NEVER_INLINE double zero()
 {
@@ -17012,6 +17084,10 @@ void run(const char* filter)
     RUN(testDoubleLiteralComparison(125.3144446948241, 125.3144446948242));
     RUN(testDoubleLiteralComparison(125.3144446948242, 125.3144446948241));
 
+    RUN(testFloatEqualOrUnorderedFolding());
+    RUN(testFloatEqualOrUnorderedFoldingNaN());
+    RUN(testFloatEqualOrUnorderedDontFold());
+
     if (isX86()) {
         RUN(testBranchBitAndImmFusion(Identity, Int64, 1, Air::BranchTest32, Air::Arg::Tmp));
         RUN(testBranchBitAndImmFusion(Identity, Int64, 0xff, Air::BranchTest32, Air::Arg::Tmp));