https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83129
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|UNCONFIRMED |ASSIGNED Last reconfirmed| |2017-11-23 Version|unknown |8.0 Assignee|unassigned at gcc dot gnu.org |rguenth at gcc dot gnu.org Ever confirmed|0 |1 --- Comment #1 from Richard Biener <rguenth at gcc dot gnu.org> --- Confirmed - mine. This one is interesting because alias-wise we consider allocation functions not clobbering anything -- dependences for the pointer will prevent any invalid transform. That of course means we'll never visit it via vn_reference_lookup_3. One trick we don't pull is that if there's a must-alloc in the path we can stop walking. Another trick we don't pull is that if we don't find any may-def the memory we load is uninitialized (or in this case zero-initialized as we don't find the calloc as may-def either - an issue for calloc and -Wuninit maybe). So we could in theory optimistically value-number each of those to zero (conservatively to treat calloc "right"). Need to think about that -Wuninitialized case. Ah, we only ever warn using the oracle walking for decls, so never for allocated memory. So in theory the following but it doesn't trigger because of the above. Index: gcc/tree-ssa-sccvn.c =================================================================== --- gcc/tree-ssa-sccvn.c (revision 255093) +++ gcc/tree-ssa-sccvn.c (working copy) @@ -2412,6 +2417,21 @@ vn_reference_lookup_3 (ao_ref *ref, tree return NULL; } + /* 7) calloc, optimize ref to all zeros. */ + else if (is_gimple_reg_type (vr->type) + && gimple_call_builtin_p (def_stmt, BUILT_IN_CALLOC) + && TREE_CODE (base) == MEM_REF + && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME + && SSA_VAL (TREE_OPERAND (base, 0)) != VN_TOP + && SSA_VAL (TREE_OPERAND (base, 0)) == gimple_call_lhs (def_stmt)) + { + /* We do not bother to check whether the ref is in range because + we'll usually not be able to anyway. */ + tree val = build_zero_cst (vr->type); + return vn_reference_lookup_or_insert_for_pieces + (vuse, vr->set, vr->type, vr->operands, val); + } + /* Bail out and stop walking. */ return (void *)-1; }