Diff
Modified: trunk/LayoutTests/ChangeLog (153186 => 153187)
--- trunk/LayoutTests/ChangeLog 2013-07-25 04:01:11 UTC (rev 153186)
+++ trunk/LayoutTests/ChangeLog 2013-07-25 04:01:14 UTC (rev 153187)
@@ -1,3 +1,24 @@
+2013-05-27 Filip Pizlo <fpi...@apple.com>
+
+ fourthTier: DFG ArithMod should have the !nodeUsedAsNumber optimizations that ArithDiv has
+ https://bugs.webkit.org/show_bug.cgi?id=116841
+
+ Reviewed by Mark Hahnenberg.
+
+ * fast/js/dfg-mod-by-neg1-and-then-or-zero-interesting-reg-alloc-expected.txt: Added.
+ * fast/js/dfg-mod-by-neg1-and-then-or-zero-interesting-reg-alloc.html: Added.
+ * fast/js/dfg-mod-by-zero-and-then-or-zero-interesting-reg-alloc-expected.txt: Added.
+ * fast/js/dfg-mod-by-zero-and-then-or-zero-interesting-reg-alloc.html: Added.
+ * fast/js/dfg-mod-neg2tothe31-by-one-and-then-or-zero-with-interesting-reg-alloc-expected.txt: Added.
+ * fast/js/dfg-mod-neg2tothe31-by-one-and-then-or-zero-with-interesting-reg-alloc.html: Added.
+ * fast/js/jsc-test-list:
+ * fast/js/script-tests/dfg-mod-by-neg1-and-then-or-zero-interesting-reg-alloc.js: Added.
+ (foo):
+ * fast/js/script-tests/dfg-mod-by-zero-and-then-or-zero-interesting-reg-alloc.js: Added.
+ (foo):
+ * fast/js/script-tests/dfg-mod-neg2tothe31-by-one-and-then-or-zero-with-interesting-reg-alloc.js: Added.
+ (foo):
+
2013-05-26 Filip Pizlo <fpi...@apple.com>
fourthTier: clean up ArithDiv/ArithMod in the DFG
Added: trunk/LayoutTests/fast/js/dfg-mod-by-neg1-and-then-or-zero-interesting-reg-alloc-expected.txt (0 => 153187)
--- trunk/LayoutTests/fast/js/dfg-mod-by-neg1-and-then-or-zero-interesting-reg-alloc-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/js/dfg-mod-by-neg1-and-then-or-zero-interesting-reg-alloc-expected.txt 2013-07-25 04:01:14 UTC (rev 153187)
@@ -0,0 +1,109 @@
+Tests that the (x%-1)|0 case in the DFG is handled correctly even when there is some interesting register allocation going on.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS foo(0, 0, 0, -1) is 0
+PASS foo(0, 0, 1, -1) is 0
+PASS foo(0, 0, 2, -1) is 0
+PASS foo(0, 0, 3, -1) is 0
+PASS foo(0, 0, 4, -1) is 0
+PASS foo(0, 0, 5, -1) is 0
+PASS foo(0, 0, 6, -1) is 0
+PASS foo(0, 0, 7, -1) is 0
+PASS foo(0, 0, 8, -1) is 0
+PASS foo(0, 0, 9, -1) is 0
+PASS foo(0, 0, 10, -1) is 0
+PASS foo(0, 0, 11, -1) is 0
+PASS foo(0, 0, 12, -1) is 0
+PASS foo(0, 0, 13, -1) is 0
+PASS foo(0, 0, 14, -1) is 0
+PASS foo(0, 0, 15, -1) is 0
+PASS foo(0, 0, 16, -1) is 0
+PASS foo(0, 0, 17, -1) is 0
+PASS foo(0, 0, 18, -1) is 0
+PASS foo(0, 0, 19, -1) is 0
+PASS foo(0, 0, 20, -1) is 0
+PASS foo(0, 0, 21, -1) is 0
+PASS foo(0, 0, 22, -1) is 0
+PASS foo(0, 0, 23, -1) is 0
+PASS foo(0, 0, 24, -1) is 0
+PASS foo(0, 0, 25, -1) is 0
+PASS foo(0, 0, 26, -1) is 0
+PASS foo(0, 0, 27, -1) is 0
+PASS foo(0, 0, 28, -1) is 0
+PASS foo(0, 0, 29, -1) is 0
+PASS foo(0, 0, 30, -1) is 0
+PASS foo(0, 0, 31, -1) is 0
+PASS foo(0, 0, 32, -1) is 0
+PASS foo(0, 0, 33, -1) is 0
+PASS foo(0, 0, 34, -1) is 0
+PASS foo(0, 0, 35, -1) is 0
+PASS foo(0, 0, 36, -1) is 0
+PASS foo(0, 0, 37, -1) is 0
+PASS foo(0, 0, 38, -1) is 0
+PASS foo(0, 0, 39, -1) is 0
+PASS foo(0, 0, 40, -1) is 0
+PASS foo(0, 0, 41, -1) is 0
+PASS foo(0, 0, 42, -1) is 0
+PASS foo(0, 0, 43, -1) is 0
+PASS foo(0, 0, 44, -1) is 0
+PASS foo(0, 0, 45, -1) is 0
+PASS foo(0, 0, 46, -1) is 0
+PASS foo(0, 0, 47, -1) is 0
+PASS foo(0, 0, 48, -1) is 0
+PASS foo(0, 0, 49, -1) is 0
+PASS foo(0, 0, 50, -1) is 0
+PASS foo(0, 0, 51, -1) is 0
+PASS foo(0, 0, 52, -1) is 0
+PASS foo(0, 0, 53, -1) is 0
+PASS foo(0, 0, 54, -1) is 0
+PASS foo(0, 0, 55, -1) is 0
+PASS foo(0, 0, 56, -1) is 0
+PASS foo(0, 0, 57, -1) is 0
+PASS foo(0, 0, 58, -1) is 0
+PASS foo(0, 0, 59, -1) is 0
+PASS foo(0, 0, 60, -1) is 0
+PASS foo(0, 0, 61, -1) is 0
+PASS foo(0, 0, 62, -1) is 0
+PASS foo(0, 0, 63, -1) is 0
+PASS foo(0, 0, 64, -1) is 0
+PASS foo(0, 0, 65, -1) is 0
+PASS foo(0, 0, 66, -1) is 0
+PASS foo(0, 0, 67, -1) is 0
+PASS foo(0, 0, 68, -1) is 0
+PASS foo(0, 0, 69, -1) is 0
+PASS foo(0, 0, 70, -1) is 0
+PASS foo(0, 0, 71, -1) is 0
+PASS foo(0, 0, 72, -1) is 0
+PASS foo(0, 0, 73, -1) is 0
+PASS foo(0, 0, 74, -1) is 0
+PASS foo(0, 0, 75, -1) is 0
+PASS foo(0, 0, 76, -1) is 0
+PASS foo(0, 0, 77, -1) is 0
+PASS foo(0, 0, 78, -1) is 0
+PASS foo(0, 0, 79, -1) is 0
+PASS foo(0, 0, 80, -1) is 0
+PASS foo(0, 0, 81, -1) is 0
+PASS foo(0, 0, 82, -1) is 0
+PASS foo(0, 0, 83, -1) is 0
+PASS foo(0, 0, 84, -1) is 0
+PASS foo(0, 0, 85, -1) is 0
+PASS foo(0, 0, 86, -1) is 0
+PASS foo(0, 0, 87, -1) is 0
+PASS foo(0, 0, 88, -1) is 0
+PASS foo(0, 0, 89, -1) is 0
+PASS foo(0, 0, 90, -1) is 0
+PASS foo(0, 0, 91, -1) is 0
+PASS foo(0, 0, 92, -1) is 0
+PASS foo(0, 0, 93, -1) is 0
+PASS foo(0, 0, 94, -1) is 0
+PASS foo(0, 0, 95, -1) is 0
+PASS foo(0, 0, 96, -1) is 0
+PASS foo(0, 0, 97, -1) is 0
+PASS foo(0, 0, 98, -1) is 0
+PASS foo(0, 0, 99, -1) is 0
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/fast/js/dfg-mod-by-neg1-and-then-or-zero-interesting-reg-alloc.html (0 => 153187)
--- trunk/LayoutTests/fast/js/dfg-mod-by-neg1-and-then-or-zero-interesting-reg-alloc.html (rev 0)
+++ trunk/LayoutTests/fast/js/dfg-mod-by-neg1-and-then-or-zero-interesting-reg-alloc.html 2013-07-25 04:01:14 UTC (rev 153187)
@@ -0,0 +1,10 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script src=""
+<script src=""
+</body>
+</html>
Added: trunk/LayoutTests/fast/js/dfg-mod-by-zero-and-then-or-zero-interesting-reg-alloc-expected.txt (0 => 153187)
--- trunk/LayoutTests/fast/js/dfg-mod-by-zero-and-then-or-zero-interesting-reg-alloc-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/js/dfg-mod-by-zero-and-then-or-zero-interesting-reg-alloc-expected.txt 2013-07-25 04:01:14 UTC (rev 153187)
@@ -0,0 +1,109 @@
+Tests that the (x/0)|0 case in the DFG is handled correctly even when there is some interesting register allocation going on.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS foo(0, 0, 0, 0) is 0
+PASS foo(0, 0, 1, 0) is 0
+PASS foo(0, 0, 2, 0) is 0
+PASS foo(0, 0, 3, 0) is 0
+PASS foo(0, 0, 4, 0) is 0
+PASS foo(0, 0, 5, 0) is 0
+PASS foo(0, 0, 6, 0) is 0
+PASS foo(0, 0, 7, 0) is 0
+PASS foo(0, 0, 8, 0) is 0
+PASS foo(0, 0, 9, 0) is 0
+PASS foo(0, 0, 10, 0) is 0
+PASS foo(0, 0, 11, 0) is 0
+PASS foo(0, 0, 12, 0) is 0
+PASS foo(0, 0, 13, 0) is 0
+PASS foo(0, 0, 14, 0) is 0
+PASS foo(0, 0, 15, 0) is 0
+PASS foo(0, 0, 16, 0) is 0
+PASS foo(0, 0, 17, 0) is 0
+PASS foo(0, 0, 18, 0) is 0
+PASS foo(0, 0, 19, 0) is 0
+PASS foo(0, 0, 20, 0) is 0
+PASS foo(0, 0, 21, 0) is 0
+PASS foo(0, 0, 22, 0) is 0
+PASS foo(0, 0, 23, 0) is 0
+PASS foo(0, 0, 24, 0) is 0
+PASS foo(0, 0, 25, 0) is 0
+PASS foo(0, 0, 26, 0) is 0
+PASS foo(0, 0, 27, 0) is 0
+PASS foo(0, 0, 28, 0) is 0
+PASS foo(0, 0, 29, 0) is 0
+PASS foo(0, 0, 30, 0) is 0
+PASS foo(0, 0, 31, 0) is 0
+PASS foo(0, 0, 32, 0) is 0
+PASS foo(0, 0, 33, 0) is 0
+PASS foo(0, 0, 34, 0) is 0
+PASS foo(0, 0, 35, 0) is 0
+PASS foo(0, 0, 36, 0) is 0
+PASS foo(0, 0, 37, 0) is 0
+PASS foo(0, 0, 38, 0) is 0
+PASS foo(0, 0, 39, 0) is 0
+PASS foo(0, 0, 40, 0) is 0
+PASS foo(0, 0, 41, 0) is 0
+PASS foo(0, 0, 42, 0) is 0
+PASS foo(0, 0, 43, 0) is 0
+PASS foo(0, 0, 44, 0) is 0
+PASS foo(0, 0, 45, 0) is 0
+PASS foo(0, 0, 46, 0) is 0
+PASS foo(0, 0, 47, 0) is 0
+PASS foo(0, 0, 48, 0) is 0
+PASS foo(0, 0, 49, 0) is 0
+PASS foo(0, 0, 50, 0) is 0
+PASS foo(0, 0, 51, 0) is 0
+PASS foo(0, 0, 52, 0) is 0
+PASS foo(0, 0, 53, 0) is 0
+PASS foo(0, 0, 54, 0) is 0
+PASS foo(0, 0, 55, 0) is 0
+PASS foo(0, 0, 56, 0) is 0
+PASS foo(0, 0, 57, 0) is 0
+PASS foo(0, 0, 58, 0) is 0
+PASS foo(0, 0, 59, 0) is 0
+PASS foo(0, 0, 60, 0) is 0
+PASS foo(0, 0, 61, 0) is 0
+PASS foo(0, 0, 62, 0) is 0
+PASS foo(0, 0, 63, 0) is 0
+PASS foo(0, 0, 64, 0) is 0
+PASS foo(0, 0, 65, 0) is 0
+PASS foo(0, 0, 66, 0) is 0
+PASS foo(0, 0, 67, 0) is 0
+PASS foo(0, 0, 68, 0) is 0
+PASS foo(0, 0, 69, 0) is 0
+PASS foo(0, 0, 70, 0) is 0
+PASS foo(0, 0, 71, 0) is 0
+PASS foo(0, 0, 72, 0) is 0
+PASS foo(0, 0, 73, 0) is 0
+PASS foo(0, 0, 74, 0) is 0
+PASS foo(0, 0, 75, 0) is 0
+PASS foo(0, 0, 76, 0) is 0
+PASS foo(0, 0, 77, 0) is 0
+PASS foo(0, 0, 78, 0) is 0
+PASS foo(0, 0, 79, 0) is 0
+PASS foo(0, 0, 80, 0) is 0
+PASS foo(0, 0, 81, 0) is 0
+PASS foo(0, 0, 82, 0) is 0
+PASS foo(0, 0, 83, 0) is 0
+PASS foo(0, 0, 84, 0) is 0
+PASS foo(0, 0, 85, 0) is 0
+PASS foo(0, 0, 86, 0) is 0
+PASS foo(0, 0, 87, 0) is 0
+PASS foo(0, 0, 88, 0) is 0
+PASS foo(0, 0, 89, 0) is 0
+PASS foo(0, 0, 90, 0) is 0
+PASS foo(0, 0, 91, 0) is 0
+PASS foo(0, 0, 92, 0) is 0
+PASS foo(0, 0, 93, 0) is 0
+PASS foo(0, 0, 94, 0) is 0
+PASS foo(0, 0, 95, 0) is 0
+PASS foo(0, 0, 96, 0) is 0
+PASS foo(0, 0, 97, 0) is 0
+PASS foo(0, 0, 98, 0) is 0
+PASS foo(0, 0, 99, 0) is 0
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/fast/js/dfg-mod-by-zero-and-then-or-zero-interesting-reg-alloc.html (0 => 153187)
--- trunk/LayoutTests/fast/js/dfg-mod-by-zero-and-then-or-zero-interesting-reg-alloc.html (rev 0)
+++ trunk/LayoutTests/fast/js/dfg-mod-by-zero-and-then-or-zero-interesting-reg-alloc.html 2013-07-25 04:01:14 UTC (rev 153187)
@@ -0,0 +1,10 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script src=""
+<script src=""
+</body>
+</html>
Added: trunk/LayoutTests/fast/js/dfg-mod-neg2tothe31-by-one-and-then-or-zero-with-interesting-reg-alloc-expected.txt (0 => 153187)
--- trunk/LayoutTests/fast/js/dfg-mod-neg2tothe31-by-one-and-then-or-zero-with-interesting-reg-alloc-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/js/dfg-mod-neg2tothe31-by-one-and-then-or-zero-with-interesting-reg-alloc-expected.txt 2013-07-25 04:01:14 UTC (rev 153187)
@@ -0,0 +1,109 @@
+Tests that the (-2147483648/-1)|0 case in the DFG is handled correctly even when there is some interesting register allocation going on.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS foo(0, 0, -2147483647-1, -1) is 0
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/fast/js/dfg-mod-neg2tothe31-by-one-and-then-or-zero-with-interesting-reg-alloc.html (0 => 153187)
--- trunk/LayoutTests/fast/js/dfg-mod-neg2tothe31-by-one-and-then-or-zero-with-interesting-reg-alloc.html (rev 0)
+++ trunk/LayoutTests/fast/js/dfg-mod-neg2tothe31-by-one-and-then-or-zero-with-interesting-reg-alloc.html 2013-07-25 04:01:14 UTC (rev 153187)
@@ -0,0 +1,10 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script src=""
+<script src=""
+</body>
+</html>
Modified: trunk/LayoutTests/fast/js/jsc-test-list (153186 => 153187)
--- trunk/LayoutTests/fast/js/jsc-test-list 2013-07-25 04:01:11 UTC (rev 153186)
+++ trunk/LayoutTests/fast/js/jsc-test-list 2013-07-25 04:01:14 UTC (rev 153187)
@@ -190,6 +190,9 @@
fast/js/dfg-mul-big-integer-with-small-integer-and-bitor
fast/js/dfg-mul-big-integer-with-small-integer-and-detect-overflow
fast/js/dfg-mul-big-integers
+fast/js/dfg-mod-by-zero-and-then-or-zero-interesting-reg-alloc
+fast/js/dfg-mod-by-neg1-and-then-or-zero-interesting-reg-alloc
+fast/js/dfg-mod-neg2tothe31-by-one-and-then-or-zero-with-interesting-reg-alloc
fast/js/dfg-multi-basic-block-structure-clobber
fast/js/dfg-multiply
fast/js/dfg-negative-array-index
Added: trunk/LayoutTests/fast/js/script-tests/dfg-mod-by-neg1-and-then-or-zero-interesting-reg-alloc.js (0 => 153187)
--- trunk/LayoutTests/fast/js/script-tests/dfg-mod-by-neg1-and-then-or-zero-interesting-reg-alloc.js (rev 0)
+++ trunk/LayoutTests/fast/js/script-tests/dfg-mod-by-neg1-and-then-or-zero-interesting-reg-alloc.js 2013-07-25 04:01:14 UTC (rev 153187)
@@ -0,0 +1,11 @@
+description(
+"Tests that the (x%-1)|0 case in the DFG is handled correctly even when there is some interesting register allocation going on."
+);
+
+function foo(c, d, a, b) {
+ return (c + d) + ((a % b) | 0);
+}
+
+for (var i = 0; i < 100; ++i)
+ shouldBe("foo(0, 0, " + i + ", -1)", "0");
+
Added: trunk/LayoutTests/fast/js/script-tests/dfg-mod-by-zero-and-then-or-zero-interesting-reg-alloc.js (0 => 153187)
--- trunk/LayoutTests/fast/js/script-tests/dfg-mod-by-zero-and-then-or-zero-interesting-reg-alloc.js (rev 0)
+++ trunk/LayoutTests/fast/js/script-tests/dfg-mod-by-zero-and-then-or-zero-interesting-reg-alloc.js 2013-07-25 04:01:14 UTC (rev 153187)
@@ -0,0 +1,11 @@
+description(
+"Tests that the (x/0)|0 case in the DFG is handled correctly even when there is some interesting register allocation going on."
+);
+
+function foo(c, d, a, b) {
+ return (c + d) + ((a % b) | 0);
+}
+
+for (var i = 0; i < 100; ++i)
+ shouldBe("foo(0, 0, " + i + ", 0)", "0");
+
Added: trunk/LayoutTests/fast/js/script-tests/dfg-mod-neg2tothe31-by-one-and-then-or-zero-with-interesting-reg-alloc.js (0 => 153187)
--- trunk/LayoutTests/fast/js/script-tests/dfg-mod-neg2tothe31-by-one-and-then-or-zero-with-interesting-reg-alloc.js (rev 0)
+++ trunk/LayoutTests/fast/js/script-tests/dfg-mod-neg2tothe31-by-one-and-then-or-zero-with-interesting-reg-alloc.js 2013-07-25 04:01:14 UTC (rev 153187)
@@ -0,0 +1,11 @@
+description(
+"Tests that the (-2147483648/-1)|0 case in the DFG is handled correctly even when there is some interesting register allocation going on."
+);
+
+function foo(c, d, a, b) {
+ return (c + d) + ((a % b) | 0);
+}
+
+for (var i = 0; i < 100; ++i)
+ shouldBe("foo(0, 0, -2147483647-1, -1)", "0");
+
Modified: trunk/Source/_javascript_Core/ChangeLog (153186 => 153187)
--- trunk/Source/_javascript_Core/ChangeLog 2013-07-25 04:01:11 UTC (rev 153186)
+++ trunk/Source/_javascript_Core/ChangeLog 2013-07-25 04:01:14 UTC (rev 153187)
@@ -1,3 +1,13 @@
+2013-05-27 Filip Pizlo <fpi...@apple.com>
+
+ fourthTier: DFG ArithMod should have the !nodeUsedAsNumber optimizations that ArithDiv has
+ https://bugs.webkit.org/show_bug.cgi?id=116841
+
+ Reviewed by Mark Hahnenberg.
+
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compileArithMod):
+
2013-05-26 Filip Pizlo <fpi...@apple.com>
fourthTier: clean up ArithDiv/ArithMod in the DFG
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (153186 => 153187)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2013-07-25 04:01:11 UTC (rev 153186)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2013-07-25 04:01:14 UTC (rev 153187)
@@ -3232,9 +3232,8 @@
// produce a double result instead.
if (nodeUsedAsNumber(node->arithNodeFlags()))
speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branchTest32(JITCompiler::NonZero, edx.gpr()));
- else
- done.link(&m_jit);
-
+
+ done.link(&m_jit);
integerResult(eax.gpr(), node);
#elif CPU(APPLE_ARMV7S)
SpeculateIntegerOperand op1(this, node->child1());
@@ -3360,7 +3359,7 @@
#if CPU(X86) || CPU(X86_64)
if (isInt32Constant(node->child2().node())) {
int32_t divisor = valueOfInt32Constant(node->child2().node());
- if (divisor) {
+ if (divisor && divisor != -1) {
GPRReg op1Gpr = op1.gpr();
GPRTemporary eax(this, X86Registers::eax);
@@ -3380,15 +3379,13 @@
m_jit.move(op1Gpr, eax.gpr());
m_jit.move(TrustedImm32(divisor), scratchGPR);
- if (divisor == -1)
- speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branch32(JITCompiler::Equal, eax.gpr(), TrustedImm32(-2147483647-1)));
m_jit.assembler().cdq();
m_jit.assembler().idivl_r(scratchGPR);
- // Check that we're not about to create negative zero.
- // FIXME: if the node use doesn't care about neg zero, we can do this more easily.
- JITCompiler::Jump numeratorPositive = m_jit.branch32(JITCompiler::GreaterThanOrEqual, op1SaveGPR, TrustedImm32(0));
- speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branchTest32(JITCompiler::Zero, edx.gpr()));
- numeratorPositive.link(&m_jit);
+ if (!nodeCanIgnoreNegativeZero(node->arithNodeFlags())) {
+ JITCompiler::Jump numeratorPositive = m_jit.branch32(JITCompiler::GreaterThanOrEqual, op1SaveGPR, TrustedImm32(0));
+ speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branchTest32(JITCompiler::Zero, edx.gpr()));
+ numeratorPositive.link(&m_jit);
+ }
if (op1SaveGPR != op1Gpr)
unlock(op1SaveGPR);
@@ -3437,11 +3434,34 @@
JITCompiler::Jump safeDenominator = m_jit.branch32(JITCompiler::Above, temp, JITCompiler::TrustedImm32(1));
- JITCompiler::Jump done;
- // FIXME: if the node is not used as number then we can do this more easily.
- speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branchTest32(JITCompiler::Zero, op2GPR));
- speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branch32(JITCompiler::Equal, op1GPR, TrustedImm32(-2147483647-1)));
-
+ JITCompiler::JumpList done;
+
+ // FIXME: -2^31 / -1 will actually yield negative zero, so we could have a
+ // separate case for that. But it probably doesn't matter so much.
+ if (nodeUsedAsNumber(node->arithNodeFlags())) {
+ speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branchTest32(JITCompiler::Zero, op2GPR));
+ speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branch32(JITCompiler::Equal, op1GPR, TrustedImm32(-2147483647-1)));
+ } else {
+ // This is the case where we convert the result to an int after we're done, and we
+ // already know that the denominator is either -1 or 0. So, if the denominator is
+ // zero, then the result should be zero. If the denominator is not zero (i.e. it's
+ // -1) and the numerator is -2^31 then the result should be 0. Otherwise we are
+ // happy to fall through to a normal division, since we're just dividing something
+ // by negative 1.
+
+ JITCompiler::Jump notZero = m_jit.branchTest32(JITCompiler::NonZero, op2GPR);
+ m_jit.move(TrustedImm32(0), edx.gpr());
+ done.append(m_jit.jump());
+
+ notZero.link(&m_jit);
+ JITCompiler::Jump notNeg2ToThe31 =
+ m_jit.branch32(JITCompiler::NotEqual, op1GPR, TrustedImm32(-2147483647-1));
+ m_jit.move(TrustedImm32(0), edx.gpr());
+ done.append(m_jit.jump());
+
+ notNeg2ToThe31.link(&m_jit);
+ }
+
safeDenominator.link(&m_jit);
if (op2TempGPR != InvalidGPRReg) {
@@ -3457,14 +3477,16 @@
unlock(op2TempGPR);
// Check that we're not about to create negative zero.
- // FIXME: if the node use doesn't care about neg zero, we can do this more easily.
- JITCompiler::Jump numeratorPositive = m_jit.branch32(JITCompiler::GreaterThanOrEqual, op1SaveGPR, TrustedImm32(0));
- speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branchTest32(JITCompiler::Zero, edx.gpr()));
- numeratorPositive.link(&m_jit);
+ if (!nodeCanIgnoreNegativeZero(node->arithNodeFlags())) {
+ JITCompiler::Jump numeratorPositive = m_jit.branch32(JITCompiler::GreaterThanOrEqual, op1SaveGPR, TrustedImm32(0));
+ speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branchTest32(JITCompiler::Zero, edx.gpr()));
+ numeratorPositive.link(&m_jit);
+ }
if (op1SaveGPR != op1GPR)
unlock(op1SaveGPR);
+ done.link(&m_jit);
integerResult(edx.gpr(), node);
#elif CPU(APPLE_ARMV7S)