Expand Trunc in B3 to support Double to Float
authorkeith_miller@apple.com <keith_miller@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 21 Oct 2016 22:20:05 +0000 (22:20 +0000)
committerkeith_miller@apple.com <keith_miller@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 21 Oct 2016 22:20:05 +0000 (22:20 +0000)
https://bugs.webkit.org/show_bug.cgi?id=163809

Source/JavaScriptCore:

Reviewed by Geoffrey Garen.

This feature is useful for passing floating point arguments via registers.
Currently, ArgumentRegValue returns a the full 64-bit register. Thus, we
need a way to indicate to B3 that we only want the low 32-bits.

* b3/B3Common.h:
(JSC::B3::isIdentical):
* b3/B3LowerToAir.cpp:
(JSC::B3::Air::LowerToAir::lower):
* b3/B3Opcode.h:
* b3/B3ReduceStrength.cpp:
* b3/B3Validate.cpp:
* b3/B3Value.cpp:
(JSC::B3::Value::typeFor):
* b3/testb3.cpp:
(JSC::B3::testAddFPRArgsFloat):
(JSC::B3::testCeilArgWithEffectfulDoubleConversion):
(JSC::B3::testFloorArgWithEffectfulDoubleConversion):
(JSC::B3::testDoubleProducerPhiToFloatConversionWithDoubleConsumer):
(JSC::B3::run):

Websites/webkit.org:

Update the docs to explain that Trunc now works with fleating point numbers.

Reviewed by Geoffrey Garen.

* docs/b3/intermediate-representation.html:

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

Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/b3/B3Common.h
Source/JavaScriptCore/b3/B3LowerToAir.cpp
Source/JavaScriptCore/b3/B3Opcode.h
Source/JavaScriptCore/b3/B3ReduceStrength.cpp
Source/JavaScriptCore/b3/B3Validate.cpp
Source/JavaScriptCore/b3/B3Value.cpp
Source/JavaScriptCore/b3/testb3.cpp
Websites/webkit.org/ChangeLog
Websites/webkit.org/docs/b3/intermediate-representation.html

index 59a07f5..f310343 100644 (file)
@@ -1,5 +1,32 @@
 2016-10-21  Keith Miller  <keith_miller@apple.com>
 
+        Expand Trunc in B3 to support Double to Float
+        https://bugs.webkit.org/show_bug.cgi?id=163809
+
+        Reviewed by Geoffrey Garen.
+
+        This feature is useful for passing floating point arguments via registers.
+        Currently, ArgumentRegValue returns a the full 64-bit register. Thus, we
+        need a way to indicate to B3 that we only want the low 32-bits.
+
+        * b3/B3Common.h:
+        (JSC::B3::isIdentical):
+        * b3/B3LowerToAir.cpp:
+        (JSC::B3::Air::LowerToAir::lower):
+        * b3/B3Opcode.h:
+        * b3/B3ReduceStrength.cpp:
+        * b3/B3Validate.cpp:
+        * b3/B3Value.cpp:
+        (JSC::B3::Value::typeFor):
+        * b3/testb3.cpp:
+        (JSC::B3::testAddFPRArgsFloat):
+        (JSC::B3::testCeilArgWithEffectfulDoubleConversion):
+        (JSC::B3::testFloorArgWithEffectfulDoubleConversion):
+        (JSC::B3::testDoubleProducerPhiToFloatConversionWithDoubleConsumer):
+        (JSC::B3::run):
+
+2016-10-21  Keith Miller  <keith_miller@apple.com>
+
         Rename WASM to Wasm
         https://bugs.webkit.org/show_bug.cgi?id=163796
 
index 2402caf..235110c 100644 (file)
@@ -69,6 +69,11 @@ inline bool isIdentical(double left, double right)
     return isIdentical<int64_t>(left, right);
 }
 
+inline bool isIdentical(float left, float right)
+{
+    return isIdentical<int32_t>(left, right);
+}
+
 template<typename ResultType, typename InputType, typename BitsType>
 inline bool isRepresentableAsImpl(InputType originalValue)
 {
index a13493d..1ce7664 100644 (file)
@@ -2378,7 +2378,7 @@ private:
             // We expect that the moveConstants() phase has run, and any doubles referenced from
             // stackmaps get fused.
             RELEASE_ASSERT(m_value->opcode() == ConstFloat || isIdentical(m_value->asDouble(), 0.0));
-            RELEASE_ASSERT(m_value->opcode() == ConstDouble || isIdentical(m_value->asFloat(), 0.0));
+            RELEASE_ASSERT(m_value->opcode() == ConstDouble || isIdentical(m_value->asFloat(), 0.0f));
             append(MoveZeroToDouble, tmp(m_value));
             return;
         }
index 6fcaa31..fb51e94 100644 (file)
@@ -109,7 +109,7 @@ enum Opcode : int16_t {
     // Takes Int32 and returns Int64:
     SExt32,
     ZExt32,
-    // Takes Int64 and returns Int32:
+    // Does a bitwise truncation of Int64->Int32 and Double->Float:
     Trunc,
     // Takes ints and returns floating point value. Note that we don't currently provide the opposite operation,
     // because double-to-int conversions have weirdly different semantics on different platforms. Use
index 539cd56..8ab1ef6 100644 (file)
@@ -1326,7 +1326,7 @@ private:
         case Trunc:
             // Turn this: Trunc(constant)
             // Into this: static_cast<int32_t>(constant)
-            if (m_value->child(0)->hasInt64()) {
+            if (m_value->child(0)->hasInt64() || m_value->child(0)->hasDouble()) {
                 replaceWithNewValue(
                     m_proc.addIntConstant(m_value, static_cast<int32_t>(m_value->child(0)->asInt64())));
                 break;
index 3c002ed..428d0f4 100644 (file)
@@ -267,8 +267,10 @@ public:
             case Trunc:
                 VALIDATE(!value->kind().hasExtraBits(), ("At ", *value));
                 VALIDATE(value->numChildren() == 1, ("At ", *value));
-                VALIDATE(value->child(0)->type() == Int64, ("At ", *value));
-                VALIDATE(value->type() == Int32, ("At ", *value));
+                VALIDATE(
+                    (value->type() == Int32 && value->child(0)->type() == Int64)
+                    || (value->type() == Float && value->child(0)->type() == Double),
+                    ("At ", *value));
                 break;
             case Abs:
             case Ceil:
index 71b9eda..3ec4487 100644 (file)
@@ -774,7 +774,6 @@ Type Value::typeFor(Kind kind, Value* firstChild, Value* secondChild)
         return pointerType();
     case SExt8:
     case SExt16:
-    case Trunc:
     case Equal:
     case NotEqual:
     case LessThan:
@@ -787,6 +786,8 @@ Type Value::typeFor(Kind kind, Value* firstChild, Value* secondChild)
     case BelowEqual:
     case EqualOrUnordered:
         return Int32;
+    case Trunc:
+        return firstChild->type() == Int64 ? Int32 : Float;
     case SExt32:
     case ZExt32:
         return Int64;
index c6381b1..b94a3e4 100644 (file)
@@ -714,6 +714,20 @@ void testAddArgsFloat(float a, float b)
     CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(a + b)));
 }
 
+void testAddFPRArgsFloat(float a, float b)
+{
+    Procedure proc;
+    BasicBlock* root = proc.addBlock();
+    Value* argument1 = root->appendNew<Value>(proc, Trunc, Origin(),
+        root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0));
+    Value* argument2 = root->appendNew<Value>(proc, Trunc, Origin(),
+        root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR1));
+    Value* result = root->appendNew<Value>(proc, Add, Origin(), argument1, argument2);
+    root->appendNewControlValue(proc, Return, Origin(), result);
+
+    CHECK(isIdentical(compileAndRun<float>(proc, a, b), a + b));
+}
+
 void testAddArgImmFloat(float a, float b)
 {
     Procedure proc;
@@ -4010,7 +4024,7 @@ void testCeilArgWithEffectfulDoubleConversion(float a)
     double effect = 0;
     int32_t resultValue = compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), &effect);
     CHECK(isIdentical(resultValue, bitwise_cast<int32_t>(ceilf(a))));
-    CHECK(isIdentical(effect, ceilf(a)));
+    CHECK(isIdentical(effect, static_cast<double>(ceilf(a))));
 }
 
 void testFloorArg(double a)
@@ -4205,7 +4219,7 @@ void testFloorArgWithEffectfulDoubleConversion(float a)
     double effect = 0;
     int32_t resultValue = compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), &effect);
     CHECK(isIdentical(resultValue, bitwise_cast<int32_t>(floorf(a))));
-    CHECK(isIdentical(effect, floorf(a)));
+    CHECK(isIdentical(effect, static_cast<double>(floorf(a))));
 }
 
 void testSqrtArg(double a)
@@ -4538,7 +4552,7 @@ void testDoubleProducerPhiToFloatConversionWithDoubleConsumer(float value)
 
     auto code = compile(proc);
     CHECK(isIdentical(invoke<double>(*code, 1, bitwise_cast<int32_t>(value)), (value + value) + static_cast<double>(value)));
-    CHECK(isIdentical(invoke<double>(*code, 0, bitwise_cast<int32_t>(value)), (42.5f + value) + 42.5f));
+    CHECK(isIdentical(invoke<double>(*code, 0, bitwise_cast<int32_t>(value)), static_cast<double>((42.5f + value) + 42.5f)));
 }
 
 void testDoubleProducerPhiWithNonFloatConst(float value, double constValue)
@@ -13935,6 +13949,7 @@ void run(const char* filter)
     RUN(testAddImmsDouble(negativeZero(), negativeZero()));
     RUN_UNARY(testAddArgFloat, floatingPointOperands<float>());
     RUN_BINARY(testAddArgsFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
+    RUN_BINARY(testAddFPRArgsFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
     RUN_BINARY(testAddArgImmFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
     RUN_BINARY(testAddImmArgFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
     RUN_BINARY(testAddImmsFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
index 3d33523..b39af96 100644 (file)
@@ -1,3 +1,14 @@
+2016-10-21  Keith Miller  <keith_miller@apple.com>
+
+        Expand Trunc in B3 to support Double to Float
+        https://bugs.webkit.org/show_bug.cgi?id=163809
+
+        Update the docs to explain that Trunc now works with fleating point numbers.
+
+        Reviewed by Geoffrey Garen.
+
+        * docs/b3/intermediate-representation.html:
+
 2016-10-14  Keith Miller  <keith_miller@apple.com>
 
         B3 needs a special WasmAddress Opcode
index 73bff57..5c8509a 100644 (file)
       <dd>Returns a 64-bit integer such that the low 32 bits are the given Int32 value and the
         high 32 bits are zero.</dd>
 
-      <dt>Int32 Trunc(Int64)</dt>
-      <dd>Returns the low 32 bits of the 64-bit value.</dd>
+      <dt>U Trunc(T)</dt>
+      <dd>Returns the low 32 bits of the 64-bit value. If T is Int64 then U is Int32.
+        If T is Double then U is Float.</dd>
 
       <dt>Double IToD(T)</dt>
       <dd>Converts the given integer into a double.  Value for Int32 or Int64 inputs.</dd>