changeset 10603:2e7e7a22940f

RightShiftNode: fix canonicalization for negative input
author Bernhard Urban <bernhard.urban@jku.at>
date Mon, 01 Jul 2013 23:50:27 +0200
parents b8fe1fe004ec
children 953a0d51a11f
files graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/bytecode/BC_lshr02.java graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/optimize/InferStamp01.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/RightShiftNode.java
diffstat 3 files changed, 132 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/bytecode/BC_lshr02.java	Mon Jul 01 23:50:27 2013 +0200
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.jtt.bytecode;
+
+import com.oracle.graal.jtt.*;
+import org.junit.*;
+
+/*
+ */
+public class BC_lshr02 extends JTTTest {
+
+    public static long test0(long arg) {
+        long a = arg >> 32;
+        return a >> 32;
+    }
+
+    @Test
+    public void run0a() throws Throwable {
+        runTest("test0", 1L);
+    }
+
+    @Test
+    public void run0b() throws Throwable {
+        runTest("test0", 0L);
+    }
+
+    @Test
+    public void run0c() throws Throwable {
+        runTest("test0", -1L);
+    }
+
+    @Test
+    public void run0d() throws Throwable {
+        runTest("test0", Long.MAX_VALUE);
+    }
+
+    @Test
+    public void run0e() throws Throwable {
+        runTest("test0", Long.MIN_VALUE);
+    }
+
+    /* testcase for a postive stamp */
+    public static int test1(long[] arg) {
+        int a = arg.length >> 16;
+        return a >> 16;
+    }
+
+    @Test
+    public void run1a() throws Throwable {
+        long[] arg = new long[0x100];
+        runTest("test1", arg);
+    }
+
+    /* testcase for a strictly negative stamp */
+    public static int test2(long[] arg) {
+        int a = (-arg.length - 1) >> 16;
+        return a >> 16;
+    }
+
+    @Test
+    public void run2a() throws Throwable {
+        long[] arg = new long[0x100];
+        runTest("test2", arg);
+    }
+}
--- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/optimize/InferStamp01.java	Tue Jul 02 19:21:59 2013 +0200
+++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/optimize/InferStamp01.java	Mon Jul 01 23:50:27 2013 +0200
@@ -43,6 +43,11 @@
         runTest("testi0", 0x7788_99aa);
     }
 
+    @Test
+    public void runi0neg() throws Throwable {
+        runTest("testi0", 0xf788_99aa);
+    }
+
     public static int testi1(int arg) {
         int a = arg;
         for (int i = 0; i < 2; i++) {
@@ -56,6 +61,11 @@
         runTest("testi1", 0x7788_99aa);
     }
 
+    @Test
+    public void runi1neg() throws Throwable {
+        runTest("testi1", 0xf788_99aa);
+    }
+
     public static int testi2(int arg) {
         int a = arg;
         for (int i = 0; i < 2; i++) {
@@ -69,6 +79,11 @@
         runTest("testi2", 0x7788_99aa);
     }
 
+    @Test
+    public void runi2neg() throws Throwable {
+        runTest("testi2", 0xf788_99aa);
+    }
+
     public static long testl0(long arg) {
         long a = arg;
         for (long i = 0; i < 2; i++) {
@@ -82,6 +97,11 @@
         runTest("testl0", 0x3344_5566_7788_99aaL);
     }
 
+    @Test
+    public void runl0neg() throws Throwable {
+        runTest("testl0", 0xf344_5566_7788_99aaL);
+    }
+
     public static long testl1(long arg) {
         long a = arg;
         for (long i = 0; i < 2; i++) {
@@ -95,6 +115,11 @@
         runTest("testl1", 0x3344_5566_7788_99aaL);
     }
 
+    @Test
+    public void runl1neg() throws Throwable {
+        runTest("testl1", 0xf344_5566_7788_99aaL);
+    }
+
     public static long testl2(long arg) {
         long a = arg;
         for (long i = 0; i < 2; i++) {
@@ -107,4 +132,9 @@
     public void runl2() throws Throwable {
         runTest("testl2", 0x3344_5566_7788_99aaL);
     }
+
+    @Test
+    public void runl2neg() throws Throwable {
+        runTest("testl2", 0xf344_5566_7788_99aaL);
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/RightShiftNode.java	Tue Jul 02 19:21:59 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/RightShiftNode.java	Mon Jul 01 23:50:27 2013 +0200
@@ -26,6 +26,7 @@
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
 
 @NodeInfo(shortName = ">>")
 public final class RightShiftNode extends ShiftNode implements Canonicalizable, LIRLowerable {
@@ -68,7 +69,22 @@
                     if (other instanceof RightShiftNode) {
                         int total = amount + otherAmount;
                         if (total != (total & mask)) {
-                            return ConstantNode.forIntegerKind(kind(), 0, graph());
+                            assert other.x().stamp() instanceof IntegerStamp;
+                            IntegerStamp istamp = (IntegerStamp) other.x().stamp();
+
+                            if (istamp.isPositive()) {
+                                return ConstantNode.forIntegerKind(kind(), 0, graph());
+                            }
+                            if (istamp.isStrictlyNegative()) {
+                                return ConstantNode.forIntegerKind(kind(), -1L, graph());
+                            }
+
+                            /*
+                             * if we cannot replace both shifts with a constant, replace them by a
+                             * full shift for this kind
+                             */
+                            assert total >= mask;
+                            return graph().unique(new RightShiftNode(kind(), other.x(), ConstantNode.forInt(mask, graph())));
                         }
                         return graph().unique(new RightShiftNode(kind(), other.x(), ConstantNode.forInt(total, graph())));
                     }