8331054: C2 MergeStores: assert failed: unexpected basic type after JDK-8318446 and JDK-8329555

Reviewed-by: thartmann, kvn
This commit is contained in:
Emanuel Peter 2024-04-24 19:06:46 +00:00
parent 7b2560b490
commit ea3909acd1
2 changed files with 68 additions and 7 deletions

View File

@ -2972,8 +2972,12 @@ StoreNode* MergePrimitiveArrayStores::run() {
// Only merge stores on arrays, and the stores must have the same size as the elements.
const TypeAryPtr* aryptr_t = _store->adr_type()->isa_aryptr();
if (aryptr_t == nullptr ||
type2aelembytes(aryptr_t->elem()->array_element_basic_type()) != _store->memory_size()) {
if (aryptr_t == nullptr) {
return nullptr;
}
BasicType bt = aryptr_t->elem()->array_element_basic_type();
if (!is_java_primitive(bt) ||
type2aelembytes(bt) != _store->memory_size()) {
return nullptr;
}
@ -3019,8 +3023,13 @@ bool MergePrimitiveArrayStores::is_compatible_store(const StoreNode* other_store
// Check that the size of the stores, and the array elements are all the same.
const TypeAryPtr* aryptr_t1 = _store->adr_type()->is_aryptr();
const TypeAryPtr* aryptr_t2 = other_store->adr_type()->is_aryptr();
int size1 = type2aelembytes(aryptr_t1->elem()->array_element_basic_type());
int size2 = type2aelembytes(aryptr_t2->elem()->array_element_basic_type());
BasicType aryptr_bt1 = aryptr_t1->elem()->array_element_basic_type();
BasicType aryptr_bt2 = aryptr_t2->elem()->array_element_basic_type();
if (!is_java_primitive(aryptr_bt1) || !is_java_primitive(aryptr_bt2)) {
return false;
}
int size1 = type2aelembytes(aryptr_bt1);
int size2 = type2aelembytes(aryptr_bt2);
if (size1 != size2 ||
size1 != _store->memory_size() ||
_store->memory_size() != other_store->memory_size()) {

View File

@ -33,7 +33,7 @@ import java.util.Random;
/*
* @test
* @bug 8318446
* @bug 8318446 8331054
* @summary Test merging of consecutive stores
* @modules java.base/jdk.internal.misc
* @library /test/lib /
@ -42,7 +42,7 @@ import java.util.Random;
/*
* @test
* @bug 8318446
* @bug 8318446 8331054
* @summary Test merging of consecutive stores
* @modules java.base/jdk.internal.misc
* @library /test/lib /
@ -183,6 +183,10 @@ public class TestMergeStores {
// +-----+ +-------------------+
// First use something in range, and after warmup randomize going outside the range.
// Consequence: all RangeChecks stay in the final compilation.
testGroups.put("test600", new HashMap<String,TestFunction>());
testGroups.get("test600").put("test600R", (_,i) -> { return test600R(aB.clone(), aI.clone(), i); });
testGroups.get("test600").put("test600a", (_,i) -> { return test600a(aB.clone(), aI.clone(), i); });
}
@Warmup(100)
@ -215,7 +219,8 @@ public class TestMergeStores {
"test400a",
"test500a",
"test501a",
"test502a"})
"test502a",
"test600a"})
public void runTests(RunInfo info) {
// Repeat many times, so that we also have multiple iterations for post-warmup to potentially recompile
int iters = info.isWarmUp() ? 1_000 : 50_000;
@ -1244,4 +1249,51 @@ public class TestMergeStores {
} catch (ArrayIndexOutOfBoundsException _) {}
return new Object[]{ a, new int[]{ idx } };
}
@DontCompile
static Object[] test600R(byte[] aB, int[] aI, int i) {
Object a = null;
long base = 0;
if (i % 2 == 0) {
a = aB;
base = UNSAFE.ARRAY_BYTE_BASE_OFFSET;
} else {
a = aI;
base = UNSAFE.ARRAY_INT_BASE_OFFSET;
}
UNSAFE.putByte(a, base + 0, (byte)0xbe);
UNSAFE.putByte(a, base + 1, (byte)0xba);
UNSAFE.putByte(a, base + 2, (byte)0xad);
UNSAFE.putByte(a, base + 3, (byte)0xba);
UNSAFE.putByte(a, base + 4, (byte)0xef);
UNSAFE.putByte(a, base + 5, (byte)0xbe);
UNSAFE.putByte(a, base + 6, (byte)0xad);
UNSAFE.putByte(a, base + 7, (byte)0xde);
return new Object[]{ aB, aI };
}
@Test
@IR(counts = {IRNode.STORE_B_OF_CLASS, "bottom\\\\[int:>=0] \\\\(java/lang/Cloneable,java/io/Serializable\\\\)", "8"}) // note: bottom type
static Object[] test600a(byte[] aB, int[] aI, int i) {
Object a = null;
long base = 0;
if (i % 2 == 0) {
a = aB;
base = UNSAFE.ARRAY_BYTE_BASE_OFFSET;
} else {
a = aI;
base = UNSAFE.ARRAY_INT_BASE_OFFSET;
}
// array a is an aryptr, but its element type is unknown, i.e. bottom.
UNSAFE.putByte(a, base + 0, (byte)0xbe);
UNSAFE.putByte(a, base + 1, (byte)0xba);
UNSAFE.putByte(a, base + 2, (byte)0xad);
UNSAFE.putByte(a, base + 3, (byte)0xba);
UNSAFE.putByte(a, base + 4, (byte)0xef);
UNSAFE.putByte(a, base + 5, (byte)0xbe);
UNSAFE.putByte(a, base + 6, (byte)0xad);
UNSAFE.putByte(a, base + 7, (byte)0xde);
return new Object[]{ aB, aI };
}
}