8267332: xor value should handle bounded values
Reviewed-by: thartmann, redestad
This commit is contained in:
parent
ee2651b9e5
commit
4ba761381c
@ -920,9 +920,23 @@ const Type* XorINode::Value(PhaseGVN* phase) const {
|
||||
if (in1->eqv_uncast(in2)) {
|
||||
return add_id();
|
||||
}
|
||||
// result of xor can only have bits sets where any of the
|
||||
// inputs have bits set. lo can always become 0.
|
||||
const TypeInt* t1i = t1->is_int();
|
||||
const TypeInt* t2i = t2->is_int();
|
||||
if ((t1i->_lo >= 0) &&
|
||||
(t1i->_hi > 0) &&
|
||||
(t2i->_lo >= 0) &&
|
||||
(t2i->_hi > 0)) {
|
||||
// hi - set all bits below the highest bit. Using round_down to avoid overflow.
|
||||
const TypeInt* t1x = TypeInt::make(0, round_down_power_of_2(t1i->_hi) + (round_down_power_of_2(t1i->_hi) - 1), t1i->_widen);
|
||||
const TypeInt* t2x = TypeInt::make(0, round_down_power_of_2(t2i->_hi) + (round_down_power_of_2(t2i->_hi) - 1), t2i->_widen);
|
||||
return t1x->meet(t2x);
|
||||
}
|
||||
return AddNode::Value(phase);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------add_ring---------------------------------------
|
||||
// Supplied function returns the sum of the inputs IN THE CURRENT RING. For
|
||||
// the logical operations the ring's ADD is really a logical OR function.
|
||||
@ -970,6 +984,19 @@ const Type* XorLNode::Value(PhaseGVN* phase) const {
|
||||
if (in1->eqv_uncast(in2)) {
|
||||
return add_id();
|
||||
}
|
||||
// result of xor can only have bits sets where any of the
|
||||
// inputs have bits set. lo can always become 0.
|
||||
const TypeLong* t1l = t1->is_long();
|
||||
const TypeLong* t2l = t2->is_long();
|
||||
if ((t1l->_lo >= 0) &&
|
||||
(t1l->_hi > 0) &&
|
||||
(t2l->_lo >= 0) &&
|
||||
(t2l->_hi > 0)) {
|
||||
// hi - set all bits below the highest bit. Using round_down to avoid overflow.
|
||||
const TypeLong* t1x = TypeLong::make(0, round_down_power_of_2(t1l->_hi) + (round_down_power_of_2(t1l->_hi) - 1), t1l->_widen);
|
||||
const TypeLong* t2x = TypeLong::make(0, round_down_power_of_2(t2l->_hi) + (round_down_power_of_2(t2l->_hi) - 1), t2l->_widen);
|
||||
return t1x->meet(t2x);
|
||||
}
|
||||
return AddNode::Value(phase);
|
||||
}
|
||||
|
||||
|
139
test/hotspot/jtreg/compiler/types/TestMeetXor.java
Normal file
139
test/hotspot/jtreg/compiler/types/TestMeetXor.java
Normal file
@ -0,0 +1,139 @@
|
||||
/*
|
||||
* Copyright (c) 2021, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @key randomness
|
||||
* @bug 8267332
|
||||
* @summary Test meet on xor
|
||||
* @library /test/lib /
|
||||
* @run main/othervm compiler.types.TestMeetXor -Xbatch -XX::CompileCommand=dontinline,*::test*
|
||||
*/
|
||||
|
||||
package compiler.types;
|
||||
|
||||
import java.util.Random;
|
||||
import jdk.test.lib.Asserts;
|
||||
|
||||
public class TestMeetXor {
|
||||
public static void main(String[] args) throws Exception {
|
||||
for (int i = 0; i < 50_000; i++) {
|
||||
testCase1E();
|
||||
testCase2E();
|
||||
testCase3E();
|
||||
testCase4E();
|
||||
|
||||
testCaseS();
|
||||
}
|
||||
}
|
||||
|
||||
static int[] count = new int[256];
|
||||
static Random r = jdk.test.lib.Utils.getRandomInstance();
|
||||
|
||||
public static void testCase1E() {
|
||||
boolean aiobe = false;
|
||||
try {
|
||||
testBound1E(r.nextInt());
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
aiobe = true;
|
||||
}
|
||||
Asserts.assertTrue(aiobe);
|
||||
}
|
||||
|
||||
public static void testBound1E(int i1) throws ArrayIndexOutOfBoundsException {
|
||||
int index = (i1 >>> 24) ^ -1;
|
||||
count[index]++;
|
||||
}
|
||||
|
||||
public static void testCase2E() {
|
||||
boolean aiobe = false;
|
||||
try {
|
||||
testBound2E(r.nextInt());
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
aiobe = true;
|
||||
}
|
||||
Asserts.assertTrue(aiobe);
|
||||
}
|
||||
|
||||
public static void testBound2E(int i1) throws ArrayIndexOutOfBoundsException {
|
||||
int index = (i1 >>> 24) ^ 0x100;
|
||||
count[index]++;
|
||||
}
|
||||
|
||||
public static void testCase3E() {
|
||||
boolean aiobe = false;
|
||||
try {
|
||||
testBound3E(r.nextInt());
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
aiobe = true;
|
||||
}
|
||||
Asserts.assertTrue(aiobe);
|
||||
}
|
||||
|
||||
public static void testBound3E(int i1) throws ArrayIndexOutOfBoundsException {
|
||||
int index = (i1 >>> 24) ^ Integer.MIN_VALUE;
|
||||
count[index]++;
|
||||
}
|
||||
|
||||
public static void testCase4E() {
|
||||
boolean aiobe = false;
|
||||
try {
|
||||
testBound4E(r.nextInt(), 0xf0f0ff);
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
aiobe = true;
|
||||
}
|
||||
Asserts.assertTrue(aiobe);
|
||||
}
|
||||
|
||||
public static void testBound4E(int i1, int i2) throws ArrayIndexOutOfBoundsException {
|
||||
int index = (i1 >>> 24) ^ i2;
|
||||
count[index]++;
|
||||
}
|
||||
|
||||
public static void testCaseS() {
|
||||
testBound1S(r.nextInt());
|
||||
testBound2S(r.nextInt());
|
||||
testBound3S(r.nextInt(), r.nextInt());
|
||||
testBound4S(r.nextInt());
|
||||
}
|
||||
|
||||
public static void testBound1S(int i1) throws ArrayIndexOutOfBoundsException {
|
||||
int index = (i1 >>> 24) ^ 0x80;
|
||||
count[index]++;
|
||||
}
|
||||
|
||||
public static void testBound2S(int i1) throws ArrayIndexOutOfBoundsException {
|
||||
int index = (i1 >>> 24) ^ 0xff;
|
||||
count[index]++;
|
||||
}
|
||||
|
||||
public static void testBound3S(int i1, int i2) throws ArrayIndexOutOfBoundsException {
|
||||
int index = (i1 >>> 24) ^ (i2 >>> 24);
|
||||
count[index]++;
|
||||
}
|
||||
|
||||
public static void testBound4S(int i1) throws ArrayIndexOutOfBoundsException {
|
||||
int index = (i1 >>> 24) ^ 0;
|
||||
count[index]++;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user