Title: [282212] trunk
Revision
282212
Author
[email protected]
Date
2021-09-09 08:30:01 -0700 (Thu, 09 Sep 2021)

Log Message

Differential testing: incorrect constant propagation around Uint8ClampedArray
https://bugs.webkit.org/show_bug.cgi?id=229869

JSTests:

Reviewed by Saam Barati.

* stress/Uint8ClampedArrayClampsInt52Positive.js: Added.
(let.x.123.test):
(noInline.test.int32pos1):
(255.int32pos2):
(1.int32neg1):
(0.int32neg2):
(0.int52pos1):
(255.int52pos2):
(255.int52neg1):
(0.int52neg2):
(0.int52neg3):
(0.int52pos3):
(255.int8):

Source/_javascript_Core:

We casted int52 values to int32 before clamping, which caused any value with the 32nd bit
set to be interpreted as negative. The fix is to check the full-size value when deciding to clamp.

Reviewed by Saam Barati.

* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileCompareStrictEq):

Modified Paths

Added Paths

Diff

Modified: trunk/JSTests/ChangeLog (282211 => 282212)


--- trunk/JSTests/ChangeLog	2021-09-09 13:59:41 UTC (rev 282211)
+++ trunk/JSTests/ChangeLog	2021-09-09 15:30:01 UTC (rev 282212)
@@ -1,3 +1,24 @@
+2021-09-09  Justin Michaud  <[email protected]>
+
+        Differential testing: incorrect constant propagation around Uint8ClampedArray
+        https://bugs.webkit.org/show_bug.cgi?id=229869
+
+        Reviewed by Saam Barati.
+
+        * stress/Uint8ClampedArrayClampsInt52Positive.js: Added.
+        (let.x.123.test):
+        (noInline.test.int32pos1):
+        (255.int32pos2):
+        (1.int32neg1):
+        (0.int32neg2):
+        (0.int52pos1):
+        (255.int52pos2):
+        (255.int52neg1):
+        (0.int52neg2):
+        (0.int52neg3):
+        (0.int52pos3):
+        (255.int8):
+
 2021-09-09  Robin Morisset  <[email protected]>
 
         Optimize compareStrictEq when neither side is a double and at least one is not a BigInt

Added: trunk/JSTests/stress/Uint8ClampedArrayClampsInt52Positive.js (0 => 282212)


--- trunk/JSTests/stress/Uint8ClampedArrayClampsInt52Positive.js	                        (rev 0)
+++ trunk/JSTests/stress/Uint8ClampedArrayClampsInt52Positive.js	2021-09-09 15:30:01 UTC (rev 282212)
@@ -0,0 +1,79 @@
+let x = 123
+
+function test(fn, expected) {
+    for (let i = 0; i < 10000; i++) {
+        const arr = new Uint8ClampedArray(1)
+        fn(arr)
+        x = arr[0]
+    } 
+    
+    if (x != expected)
+        throw new Error(`Clamping was done incorrectly ${x}, expected ${expected} in ${fn}`)
+}
+noInline(test)
+
+function int32pos1(arr) {
+    arr[0] = 0x70000001|0
+}
+noInline(int32pos1)
+test(int32pos1, 255)
+
+function int32pos2(arr) {
+    arr[0] = 0x800000001|0
+}
+noInline(int32pos2)
+test(int32pos2, 1)
+
+function int32neg1(arr) {
+    arr[0] = 0x80000001|0
+}
+noInline(int32neg1)
+test(int32neg1, 0)
+
+function int32neg2(arr) {
+    arr[0] = 0x80000000|0
+}
+noInline(int32neg2)
+test(int32neg2, 0)
+
+function int52pos1(arr) {
+    arr[0] = 0x80000001
+}
+noInline(int52pos1)
+test(int52pos1, 255)
+
+function int52pos2(arr) {
+    arr[0] = 0x80000000
+}
+noInline(int52pos2)
+test(int52pos2, 255)
+
+function int52neg1(arr) {
+    arr[0] = -0x80000001
+}
+noInline(int52neg1)
+test(int52neg1, 0)
+
+function int52neg2(arr) {
+    arr[0] = -0x80000000
+}
+noInline(int52neg2)
+test(int52neg2, 0)
+
+function int52neg3(arr) {
+    arr[0] = -0x0008_0000_0000_0000
+}
+noInline(int52neg3)
+test(int52neg3, 0)
+
+function int52pos3(arr) {
+    arr[0] = 0x0007_FFFF_FFFF_FFFF
+}
+noInline(int52pos3)
+test(int52pos3, 255)
+
+function int8(arr) {
+    arr[0] = 0x8000000fe - 0x800000000
+}
+noInline(int8)
+test(int8, 254)
\ No newline at end of file

Modified: trunk/Source/_javascript_Core/ChangeLog (282211 => 282212)


--- trunk/Source/_javascript_Core/ChangeLog	2021-09-09 13:59:41 UTC (rev 282211)
+++ trunk/Source/_javascript_Core/ChangeLog	2021-09-09 15:30:01 UTC (rev 282212)
@@ -1,3 +1,16 @@
+2021-09-09  Justin Michaud  <[email protected]>
+
+        Differential testing: incorrect constant propagation around Uint8ClampedArray
+        https://bugs.webkit.org/show_bug.cgi?id=229869
+
+        We casted int52 values to int32 before clamping, which caused any value with the 32nd bit
+        set to be interpreted as negative. The fix is to check the full-size value when deciding to clamp.
+
+        Reviewed by Saam Barati.
+
+        * ftl/FTLLowerDFGToB3.cpp:
+        (JSC::FTL::DFG::LowerDFGToB3::compileCompareStrictEq):
+
 2021-09-09  Robin Morisset  <[email protected]>
 
         Optimize compareStrictEq when neither side is a double and at least one is not a BigInt

Modified: trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp (282211 => 282212)


--- trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp	2021-09-09 13:59:41 UTC (rev 282211)
+++ trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp	2021-09-09 15:30:01 UTC (rev 282212)
@@ -17797,15 +17797,26 @@
     
     LValue getIntTypedArrayStoreOperand(Edge edge, bool isClamped = false)
     {
-        LValue intValue;
+        LValue valueAsInt32;
+        LValue value;
+        LValue zero;
+        LValue byteMax;
+        
         switch (edge.useKind()) {
         case Int52RepUse:
         case Int32Use: {
-            if (edge.useKind() == Int32Use)
-                intValue = lowInt32(edge);
-            else
-                intValue = m_out.castToInt32(lowStrictInt52(edge));
-
+            if (edge.useKind() == Int32Use) {
+                value = lowInt32(edge);
+                valueAsInt32 = value;
+                zero = m_out.int32Zero;
+                byteMax = m_out.constInt32(255);
+            } else {
+                value = lowStrictInt52(edge);
+                valueAsInt32 = m_out.castToInt32(value);
+                zero = m_out.int64Zero;
+                byteMax = m_out.constInt64(255);
+            }
+            
             if (isClamped) {
                 LBasicBlock atLeastZero = m_out.newBlock();
                 LBasicBlock continuation = m_out.newBlock();
@@ -17813,19 +17824,19 @@
                 Vector<ValueFromBlock, 2> intValues;
                 intValues.append(m_out.anchor(m_out.int32Zero));
                 m_out.branch(
-                    m_out.lessThan(intValue, m_out.int32Zero),
+                    m_out.lessThan(value, zero),
                     unsure(continuation), unsure(atLeastZero));
                             
                 LBasicBlock lastNext = m_out.appendTo(atLeastZero, continuation);
                             
                 intValues.append(m_out.anchor(m_out.select(
-                    m_out.greaterThan(intValue, m_out.constInt32(255)),
+                    m_out.greaterThan(value, byteMax),
                     m_out.constInt32(255),
-                    intValue)));
+                    valueAsInt32)));
                 m_out.jump(continuation);
                             
                 m_out.appendTo(continuation, lastNext);
-                intValue = m_out.phi(Int32, intValues);
+                valueAsInt32 = m_out.phi(Int32, intValues);
             }
             break;
         }
@@ -17855,9 +17866,9 @@
                 m_out.jump(continuation);
                             
                 m_out.appendTo(continuation, lastNext);
-                intValue = m_out.phi(Int32, intValues);
+                valueAsInt32 = m_out.phi(Int32, intValues);
             } else
-                intValue = doubleToInt32(doubleValue);
+                valueAsInt32 = doubleToInt32(doubleValue);
             break;
         }
                         
@@ -17865,7 +17876,7 @@
             DFG_CRASH(m_graph, m_node, "Bad use kind");
         }
         
-        return intValue;
+        return valueAsInt32;
     }
     
     LValue doubleToInt32(LValue doubleValue, double low, double high, bool isSigned = true)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to