Thu, 27 Feb 2020 05:58:53 +0000
8181872: C1: possible overflow when strength reducing integer multiply by constant
Reviewed-by: kvn, andrew
1.1 --- a/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp Thu Feb 27 05:40:59 2020 +0000 1.2 +++ b/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp Thu Feb 27 05:58:53 2020 +0000 1.3 @@ -233,8 +233,8 @@ 1.4 } 1.5 1.6 1.7 -bool LIRGenerator::strength_reduce_multiply(LIR_Opr left, int c, LIR_Opr result, LIR_Opr tmp) { 1.8 - if (tmp->is_valid()) { 1.9 +bool LIRGenerator::strength_reduce_multiply(LIR_Opr left, jint c, LIR_Opr result, LIR_Opr tmp) { 1.10 + if (tmp->is_valid() && c > 0 && c < max_jint) { 1.11 if (is_power_of_2(c + 1)) { 1.12 __ move(left, tmp); 1.13 __ shift_left(left, log2_jint(c + 1), left); 1.14 @@ -602,8 +602,8 @@ 1.15 bool use_constant = false; 1.16 bool use_tmp = false; 1.17 if (right_arg->is_constant()) { 1.18 - int iconst = right_arg->get_jint_constant(); 1.19 - if (iconst > 0) { 1.20 + jint iconst = right_arg->get_jint_constant(); 1.21 + if (iconst > 0 && iconst < max_jint) { 1.22 if (is_power_of_2(iconst)) { 1.23 use_constant = true; 1.24 } else if (is_power_of_2(iconst - 1) || is_power_of_2(iconst + 1)) {
2.1 --- a/src/share/vm/c1/c1_LIRGenerator.cpp Thu Feb 27 05:40:59 2020 +0000 2.2 +++ b/src/share/vm/c1/c1_LIRGenerator.cpp Thu Feb 27 05:58:53 2020 +0000 2.3 @@ -539,11 +539,11 @@ 2.4 2.5 case Bytecodes::_imul: 2.6 { 2.7 - bool did_strength_reduce = false; 2.8 + bool did_strength_reduce = false; 2.9 2.10 if (right->is_constant()) { 2.11 - int c = right->as_jint(); 2.12 - if (is_power_of_2(c)) { 2.13 + jint c = right->as_jint(); 2.14 + if (c > 0 && is_power_of_2(c)) { 2.15 // do not need tmp here 2.16 __ shift_left(left_op, exact_log2(c), result_op); 2.17 did_strength_reduce = true;
3.1 --- a/src/share/vm/c1/c1_LIRGenerator.hpp Thu Feb 27 05:40:59 2020 +0000 3.2 +++ b/src/share/vm/c1/c1_LIRGenerator.hpp Thu Feb 27 05:58:53 2020 +0000 3.3 @@ -308,7 +308,7 @@ 3.4 // is_strictfp is only needed for mul and div (and only generates different code on i486) 3.5 void arithmetic_op(Bytecodes::Code code, LIR_Opr result, LIR_Opr left, LIR_Opr right, bool is_strictfp, LIR_Opr tmp, CodeEmitInfo* info = NULL); 3.6 // machine dependent. returns true if it emitted code for the multiply 3.7 - bool strength_reduce_multiply(LIR_Opr left, int constant, LIR_Opr result, LIR_Opr tmp); 3.8 + bool strength_reduce_multiply(LIR_Opr left, jint constant, LIR_Opr result, LIR_Opr tmp); 3.9 3.10 void store_stack_parameter (LIR_Opr opr, ByteSize offset_from_sp_in_bytes); 3.11
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/test/compiler/c1/MultiplyByMaxInt.java Thu Feb 27 05:58:53 2020 +0000 4.3 @@ -0,0 +1,53 @@ 4.4 +/* 4.5 + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. 4.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4.7 + * 4.8 + * This code is free software; you can redistribute it and/or modify it 4.9 + * under the terms of the GNU General Public License version 2 only, as 4.10 + * published by the Free Software Foundation. 4.11 + * 4.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 4.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 4.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 4.15 + * version 2 for more details (a copy is included in the LICENSE file that 4.16 + * accompanied this code). 4.17 + * 4.18 + * You should have received a copy of the GNU General Public License version 4.19 + * 2 along with this work; if not, write to the Free Software Foundation, 4.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 4.21 + * 4.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 4.23 + * or visit www.oracle.com if you need additional information or have any 4.24 + * questions. 4.25 + */ 4.26 + 4.27 +/* 4.28 + * @test 4.29 + * @bug 8181872 4.30 + * 4.31 + * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions 4.32 + * -XX:CompileThreshold=100 -XX:+TieredCompilation -XX:TieredStopAtLevel=1 4.33 + * -XX:-BackgroundCompilation -XX:CompileCommand=dontinline,compiler.c1.MultiplyByMaxInt::test 4.34 + * compiler.c1.MultiplyByMaxInt 4.35 + * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-BackgroundCompilation 4.36 + * -XX:CompileThreshold=100 -XX:+TieredCompilation -XX:TieredStopAtLevel=3 4.37 + * -XX:CompileCommand=dontinline,compiler.c1.MultiplyByMaxInt::test 4.38 + * compiler.c1.MultiplyByMaxInt 4.39 + */ 4.40 +package compiler.c1; 4.41 + 4.42 +public class MultiplyByMaxInt { 4.43 + static int test(int x) { 4.44 + int loops = (x >>> 4) & 7; 4.45 + while (loops-- > 0) { 4.46 + x = (x * 2147483647) % 16807; 4.47 + } 4.48 + return x; 4.49 + } 4.50 + 4.51 + public static void main(String[] args) { 4.52 + for (int i = 0; i < 20000; i++) { 4.53 + test(i); 4.54 + } 4.55 + } 4.56 +}