https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83185
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jakub at gcc dot gnu.org --- Comment #2 from Jakub Jelinek <jakub at gcc dot gnu.org> --- 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 = &MEM[(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 &MEM[(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), &offset); 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 &MEM_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 = &MEM[(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?