http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45978
Richard Guenther <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Priority|P3 |P2 --- Comment #3 from Richard Guenther <rguenth at gcc dot gnu.org> 2011-02-08 13:37:48 UTC --- Something like Index: gimple-fold.c =================================================================== --- gimple-fold.c (revision 169917) +++ gimple-fold.c (working copy) @@ -212,6 +212,7 @@ maybe_fold_offset_to_array_ref (location tree min_idx, idx, idx_type, elt_offset = integer_zero_node; tree array_type, elt_type, elt_size; tree domain_type; + tree no_warning = false; /* If BASE is an ARRAY_REF, we can pick up another offset (this time measured in units of the size of elements type) from that ARRAY_REF). @@ -308,26 +309,34 @@ maybe_fold_offset_to_array_ref (location char *(c[4]); c[3][2]; should not be simplified into (*c)[14] or tree-vrp will - give false warnings. - This is only an issue for multi-dimensional arrays. */ - if (TREE_CODE (elt_type) == ARRAY_TYPE - && domain_type) + give false warnings. For multi-dimensional arrays + avoid this transformation, for one-dimensional arrays + set TREE_NO_WARNING on out-of-bound references. */ + if (domain_type) { + bool oob = false; if (TYPE_MAX_VALUE (domain_type) && TREE_CODE (TYPE_MAX_VALUE (domain_type)) == INTEGER_CST && tree_int_cst_lt (TYPE_MAX_VALUE (domain_type), idx)) - return NULL_TREE; + oob = true; else if (TYPE_MIN_VALUE (domain_type) && TREE_CODE (TYPE_MIN_VALUE (domain_type)) == INTEGER_CST && tree_int_cst_lt (idx, TYPE_MIN_VALUE (domain_type))) - return NULL_TREE; + oob = true; else if (compare_tree_int (idx, 0) < 0) + oob = true; + if (oob) + { + if (TREE_CODE (elt_type) == ARRAY_TYPE) return NULL_TREE; + no_warning = true; + } } { tree t = build4 (ARRAY_REF, elt_type, base, idx, NULL_TREE, NULL_TREE); SET_EXPR_LOCATION (t, loc); + TREE_NO_WARNING (t) = no_warning; return t; } } fixes this but will cause us to omit all warnings for C array accesses that are out-of-bounds: FAIL: gcc.dg/Warray-bounds.c (test for warnings, line 59) FAIL: gcc.dg/Warray-bounds.c (test for warnings, line 60) FAIL: gcc.dg/Warray-bounds.c (test for warnings, line 65) FAIL: gcc.dg/Warray-bounds.c (test for warnings, line 66) FAIL: gcc.dg/Warray-bounds.c (test for warnings, line 72) FAIL: gcc.dg/Warray-bounds.c (test for warnings, line 73) In general I'd say we should not warn from VRP after loop opts, and for address-taking operations we should have a distinct warning, eventually looking at object sizes, not only type bounds. This bug is a regression only because we now vectorize the testcase to xorps %xmm0, %xmm0 movq %rdi, %rax movlps %xmm0, (%rdi) movhps %xmm0, 8(%rdi) movlps %xmm0, 16(%rdi) movlps %xmm0, 24(%rdi) compared to xorl %edx, %edx movq %rdi, %rax movl %edx, (%rdi) movl %edx, 4(%rdi) movl %edx, 8(%rdi) movl %edx, 12(%rdi) movl %edx, 16(%rdi) movl %edx, 20(%rdi) movl %edx, 24(%rdi) movl %edx, 28(%rdi) which is a good thing. Eventually we can mitigate the problem from inside the vectorizer by not using vect_p.7_13 = &MEM[(struct Y *)&<retval>].ar[0]; but instead vect_p.7_13 = &<retval> + off style initial addresses. Unfortunately that isn't very easy to do.