Path: blob/master/test/hotspot/jtreg/compiler/conversions/TestMoveConvI2LOrCastIIThruAddIs.java
41149 views
/*1* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223package compiler.conversions;2425import java.util.Objects;26import java.util.Random;27import jdk.test.lib.Asserts;2829/*30* @test31* @bug 8254317 825673032* @requires vm.compiler2.enabled33* @summary Exercises the optimization that moves integer-to-long conversions34* upwards through different shapes of integer addition35* subgraphs. Contains three small functional tests and two stress36* tests that resulted in a compilation time and memory explosion37* before fixing bug 8254317. The stress tests run with -Xbatch to wait38* for C2, so that a timeout or an out-of-memory error is triggered if39* there was an explosion. These tests use a timeout of 30s to catch40* the explosion earlier.41* @library /test/lib /42* @run main/othervm43* compiler.conversions.TestMoveConvI2LOrCastIIThruAddIs functional44* @run main/othervm/timeout=30 -Xbatch45* compiler.conversions.TestMoveConvI2LOrCastIIThruAddIs stress146* @run main/othervm/timeout=30 -Xbatch47* compiler.conversions.TestMoveConvI2LOrCastIIThruAddIs stress248* @run main/othervm/timeout=30 -Xbatch49* compiler.conversions.TestMoveConvI2LOrCastIIThruAddIs stress350* @run main/othervm/timeout=30 -Xbatch51* compiler.conversions.TestMoveConvI2LOrCastIIThruAddIs stress452*/5354public class TestMoveConvI2LOrCastIIThruAddIs {5556// Number of repetitions of each test. Should be sufficiently large for the57// method under test to be compiled with C2.58static final int N = 100_000;5960// Chain-shaped functional test.61static long testChain(boolean cnd) {62int a = cnd ? 1 : 2;63int b = a + a;64int c = b + b;65int d = c + c;66return d;67}6869// Tree-shaped functional test.70static long testTree(boolean cnd) {71int a0 = cnd ? 1 : 2;72int a1 = cnd ? 1 : 2;73int a2 = cnd ? 1 : 2;74int a3 = cnd ? 1 : 2;75int a4 = cnd ? 1 : 2;76int a5 = cnd ? 1 : 2;77int a6 = cnd ? 1 : 2;78int a7 = cnd ? 1 : 2;79int b0 = a0 + a1;80int b1 = a2 + a3;81int b2 = a4 + a5;82int b3 = a6 + a7;83int c0 = b0 + b1;84int c1 = b2 + b3;85int d = c0 + c1;86return d;87}8889// DAG-shaped functional test.90static long testDAG(boolean cnd) {91int a0 = cnd ? 1 : 2;92int a1 = cnd ? 1 : 2;93int a2 = cnd ? 1 : 2;94int a3 = cnd ? 1 : 2;95int b0 = a0 + a1;96int b1 = a1 + a2;97int b2 = a2 + a3;98int c0 = b0 + b1;99int c1 = b1 + b2;100int d = c0 + c1;101return d;102}103104// Chain-shaped stress test. Before fixing bug 8254317, this test would105// result in an out-of-memory error after minutes running.106static long testStress1(boolean cnd) {107// C2 infers a finite, small value range for a. Note that there are108// different ways to achieve this, for example a might take the value of109// the induction variable in an outer counted loop.110int a = cnd ? 1 : 2;111// C2 fully unrolls this loop, creating a long chain of AddIs.112for (int i = 0; i < 28; i++) {113a = a + a;114}115// C2 places a ConvI2L at the end of the AddI chain.116return a;117}118119// DAG-shaped stress test. Before fixing bug 8254317, this test would result120// in an out-of-memory error after minutes running.121static long testStress2(boolean cnd) {122int a = cnd ? 1 : 2;123int b = a;124int c = a + a;125for (int i = 0; i < 20; i++) {126b = b + c;127c = b + c;128}129int d = b + c;130return d;131}132133// Same as testStress1 for CastII134static long testStress3(int a) {135Objects.checkIndex(a, 2);136for (int i = 0; i < 28; i++) {137a = a + a;138}139return Objects.checkIndex(a, 2);140}141142// Same as testStress2 for CastII143static long testStress4(int a) {144a = Objects.checkIndex(a, 2);145int b = a;146int c = a + a;147for (int i = 0; i < 20; i++) {148b = b + c;149c = b + c;150}151int d = b + c;152return Objects.checkIndex(d, 2);153}154155public static void main(String[] args) {156// We use a random number generator to avoid constant propagation in C2157// and produce a variable ("a" in the different tests) with a finite,158// small value range.159Random rnd = new Random();160switch(args[0]) {161case "functional":162// Small, functional tests.163for (int i = 0; i < N; i++) {164boolean cnd = rnd.nextBoolean();165Asserts.assertEQ(testChain(cnd), cnd ? 8L : 16L);166Asserts.assertEQ(testTree(cnd), cnd ? 8L : 16L);167Asserts.assertEQ(testDAG(cnd), cnd ? 8L : 16L);168}169break;170case "stress1":171// Chain-shaped stress test.172for (int i = 0; i < N; i++) {173boolean cnd = rnd.nextBoolean();174Asserts.assertEQ(testStress1(cnd),175cnd ? 268435456L : 536870912L);176}177break;178case "stress2":179// DAG-shaped stress test.180for (int i = 0; i < N; i++) {181boolean cnd = rnd.nextBoolean();182Asserts.assertEQ(testStress2(cnd),183cnd ? 701408733L : 1402817466L);184}185break;186case "stress3":187for (int i = 0; i < N; i++) {188testStress3(0);189}190break;191case "stress4":192// DAG-shaped stress test.193for (int i = 0; i < N; i++) {194testStress4(0);195}196break;197default:198System.out.println("invalid mode");199}200}201}202203204