From 2d797dadf7e4e2736dcb313a6310102af203b20e Mon Sep 17 00:00:00 2001 From: twisti Date: Mon, 16 Feb 2009 07:19:26 -0800 Subject: [PATCH] 6805724: ModLNode::Ideal() generates functionally incorrect graph when divisor is any (2^k-1) constant. Summary: C2, ModLNode::Ideal() generates functionally incorrect graph when divisor is any (2^k-1) constant. Reviewed-by: rasbold --- src/share/vm/opto/divnode.cpp | 2 +- src/share/vm/utilities/globalDefinitions.hpp | 8 ++ test/compiler/6805724/Test6805724.java | 80 ++++++++++++++++++++ 3 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 test/compiler/6805724/Test6805724.java diff --git a/src/share/vm/opto/divnode.cpp b/src/share/vm/opto/divnode.cpp index 2d41af4e8..67cad0679 100644 --- a/src/share/vm/opto/divnode.cpp +++ b/src/share/vm/opto/divnode.cpp @@ -1007,7 +1007,7 @@ Node *ModLNode::Ideal(PhaseGVN *phase, bool can_reshape) { // Expand mod if( con >= 0 && con < max_jlong && is_power_of_2_long(con+1) ) { - uint k = log2_long(con); // Extract k + uint k = exact_log2_long(con+1); // Extract k // Basic algorithm by David Detlefs. See fastmod_long.java for gory details. // Used to help a popular random number generator which does a long-mod diff --git a/src/share/vm/utilities/globalDefinitions.hpp b/src/share/vm/utilities/globalDefinitions.hpp index 3f1d9c4d4..ba03f7194 100644 --- a/src/share/vm/utilities/globalDefinitions.hpp +++ b/src/share/vm/utilities/globalDefinitions.hpp @@ -907,6 +907,14 @@ inline int exact_log2(intptr_t x) { return log2_intptr(x); } +//* the argument must be exactly a power of 2 +inline int exact_log2_long(jlong x) { + #ifdef ASSERT + if (!is_power_of_2_long(x)) basic_fatal("x must be a power of 2"); + #endif + return log2_long(x); +} + // returns integer round-up to the nearest multiple of s (s must be a power of two) inline intptr_t round_to(intptr_t x, uintx s) { diff --git a/test/compiler/6805724/Test6805724.java b/test/compiler/6805724/Test6805724.java new file mode 100644 index 000000000..f05d8e6bf --- /dev/null +++ b/test/compiler/6805724/Test6805724.java @@ -0,0 +1,80 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/** + * @test + * @bug 6805724 + * @summary ModLNode::Ideal() generates functionally incorrect graph when divisor is any (2^k-1) constant. + * + * @run main/othervm -Xcomp -XX:CompileOnly=Test6805724.fcomp Test6805724 + */ + +import java.net.URLClassLoader; + +public class Test6805724 implements Runnable { + // Initialize DIVISOR so that it is final in this class. + static final long DIVISOR; // 2^k-1 constant + + static { + long value = 0; + try { + value = Long.decode(System.getProperty("divisor")); + } catch (Throwable t) { + // This one is required for the Class.forName() in main. + } + DIVISOR = value; + } + + static long fint(long x) { + return x % DIVISOR; + } + + static long fcomp(long x) { + return x % DIVISOR; + } + + public void run() { + long a = 0x617981E1L; + + long expected = fint(a); + long result = fcomp(a); + + if (result != expected) + throw new InternalError(result + " != " + expected); + } + + public static void main(String args[]) throws Exception { + Class cl = Class.forName("Test6805724"); + URLClassLoader apploader = (URLClassLoader) cl.getClassLoader(); + + // Iterate over all 2^k-1 divisors. + for (int k = 1; k < Long.SIZE; k++) { + long divisor = (1L << k) - 1; + System.setProperty("divisor", "" + divisor); + ClassLoader loader = new URLClassLoader(apploader.getURLs(), apploader.getParent()); + Class c = loader.loadClass("Test6805724"); + Runnable r = (Runnable) c.newInstance(); + r.run(); + } + } +} -- GitLab