Hi, For ILP32 on AARCH64, we have ptr_mode != Pmode (we have ptr_mode being SImode while Pmode is DImode and POINTER_SIZE is 32). This breaks ipa-polymorphic-call assumption that Pmode is the correct mode for pointers. Right now before this patch we get many testcase failures in the C++ testsuite due to this. Some of the tests fail due to the wrong devirtualization happening (using the base class rather the current class).
This patch fixes the issue by using POINTER_SIZE in place of GET_MODE_BITSIZE (Pmode) all over the file. OK? Bootstrapped and tested on x86_64 and cross built and tested for aarch64-elf with no regressions. Thanks, Andrew Pinski ChangeLog: ipa/63981 * ipa-polymorphic-call.c (possible_placement_new): Use POINTER_SIZE instead of GET_MODE_BITSIZE (Pmode). (ipa_polymorphic_call_context::restrict_to_inner_class): Likewise. (extr_type_from_vtbl_ptr_store): Likewise.
diff --git a/gcc/ipa-polymorphic-call.c b/gcc/ipa-polymorphic-call.c index 452f2d2..a746c49 100644 --- a/gcc/ipa-polymorphic-call.c +++ b/gcc/ipa-polymorphic-call.c @@ -112,7 +112,7 @@ possible_placement_new (tree type, tree expected_type, || !tree_fits_shwi_p (TYPE_SIZE (type)) || (cur_offset + (expected_type ? tree_to_uhwi (TYPE_SIZE (expected_type)) - : GET_MODE_BITSIZE (Pmode)) + : POINTER_SIZE) <= tree_to_uhwi (TYPE_SIZE (type))))); } @@ -155,7 +155,7 @@ ipa_polymorphic_call_context::restrict_to_inner_class (tree otr_type, HOST_WIDE_INT cur_offset = offset; bool speculative = false; bool size_unknown = false; - unsigned HOST_WIDE_INT otr_type_size = GET_MODE_BITSIZE (Pmode); + unsigned HOST_WIDE_INT otr_type_size = POINTER_SIZE; /* Update OUTER_TYPE to match EXPECTED_TYPE if it is not set. */ if (!outer_type) @@ -316,7 +316,7 @@ ipa_polymorphic_call_context::restrict_to_inner_class (tree otr_type, if (pos <= (unsigned HOST_WIDE_INT)cur_offset && (pos + size) >= (unsigned HOST_WIDE_INT)cur_offset - + GET_MODE_BITSIZE (Pmode) + + POINTER_SIZE && (!otr_type || !TYPE_SIZE (TREE_TYPE (fld)) || !tree_fits_shwi_p (TYPE_SIZE (TREE_TYPE (fld))) @@ -1243,7 +1243,7 @@ extr_type_from_vtbl_ptr_store (gimple stmt, struct type_change_info *tci, print_generic_expr (dump_file, tci->instance, TDF_SLIM); fprintf (dump_file, " with offset %i\n", (int)tci->offset); } - return tci->offset > GET_MODE_BITSIZE (Pmode) ? error_mark_node : NULL_TREE; + return tci->offset > POINTER_SIZE ? error_mark_node : NULL_TREE; } if (offset != tci->offset || size != POINTER_SIZE @@ -1252,9 +1252,9 @@ extr_type_from_vtbl_ptr_store (gimple stmt, struct type_change_info *tci, if (dump_file) fprintf (dump_file, " wrong offset %i!=%i or size %i\n", (int)offset, (int)tci->offset, (int)size); - return offset + GET_MODE_BITSIZE (Pmode) <= tci->offset + return offset + POINTER_SIZE <= tci->offset || (max_size != -1 - && tci->offset + GET_MODE_BITSIZE (Pmode) > offset + max_size) + && tci->offset + POINTER_SIZE > offset + max_size) ? error_mark_node : NULL; } }