https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83185
Jakub Jelinek changed:
What|Removed |Added
CC||jakub at gcc dot gnu.org
--- Comment #2 from Jakub Jelinek ---
So, the ICE is because without -fsanitize=address we have:
struct [0:D.1901][1] * aps.0;
struct [1] * _7;
aps.0_10 = __builtin_alloca_with_align (_8, 64);
_7 = &*aps.0_10[4];
__builtin_va_start (_7, 0);
but with -fsanitize=address
struct [1] * _7;
struct [0:D.2257][1] * _17;
struct [0:D.2257][1] * _18;
_17 = __builtin_alloca_with_align (_16, 256);
_18 = _17 + 32;
__builtin___asan_alloca_poison (_18, _8);
_7 = [(struct [0:D.2257][1] *)_17 + 32B][4];
__builtin_va_start (_7, 0);
Now, tree-cfg.c verification is happy about this, in both
&*aps.0_10[4]
as well as
[(struct [0:D.2257][1] *)_17 + 32B][4]
but when the backend feeds that to build_simple_mem_ref_loc we reach:
4687 /* For convenience allow addresses that collapse to a simple base
4688 and offset. */
4689 if (TREE_CODE (ptr) == ADDR_EXPR
4690 && (handled_component_p (TREE_OPERAND (ptr, 0))
4691 || TREE_CODE (TREE_OPERAND (ptr, 0)) == MEM_REF))
4692{
4693 ptr = get_addr_base_and_unit_offset (TREE_OPERAND (ptr, 0),
);
4694 gcc_assert (ptr);
4695 ptr = build_fold_addr_expr (ptr);
4696 gcc_assert (is_gimple_reg (ptr) || is_gimple_min_invariant
(ptr));
4697}
which ICEs in the -fsanitize=address case, in the former case ptr after
build_fold_addr_expr is a SSA_NAME, but in the latter _REF[SSA_NAME + 32],
and because the base is SSA_NAME, not ADDR_EXPR, we don't really merge the two
offsets together.
So, is this a forwprop bug + checking bug that it created such ADDR_EXPR -
in cddce3 we still had:
_17 = __builtin_alloca_with_align (_16, 256);
_18 = _17 + 32;
__builtin___asan_alloca_poison (_18, _8);
_7 = &*_18[4];
__builtin_va_start (_7, 0);
and then forwprop4 turns that into:
_17 = __builtin_alloca_with_align (_16, 256);
_18 = _17 + 32;
__builtin___asan_alloca_poison (_18, _8);
_7 = [(struct [0:D.2257][1] *)_17 + 32B][4];
__builtin_va_start (_7, 0);
Or should build_simple_mem_ref_loc deal also with this case (such as seeing
that if ptr fails the above assert, but is ADDR_EXPR of a MEM_REF with SSA_NAME
base and constant, use the ptr base as the constant and add the offset to
offset)? Or should all the backends and other spots that call
build_simple_mem_ref_loc gimplify the address instead?