http://gcc.gnu.org/bugzilla/show_bug.cgi?id=61060
--- Comment #4 from Richard Biener <rguenth at gcc dot gnu.org> ---
At -O0? Well... it seems the expander doesn't yet see it's zero:
/* If the LEN parameter is zero, return DEST. */
if (integer_zerop (len))
{
/* Evaluate and ignore VAL in case it has side-effects. */
expand_expr (val, const0_rtx, VOIDmode, EXPAND_NORMAL);
return expand_expr (dest, target, mode, EXPAND_NORMAL);
that is because len is len_5 at -O0 (no CCP), but it is TERed and thus
len_5 = 0 is expanded in-place.
I'd say the backend should better deal with this. Or we have to
double-check (or delay) the zero-length check until after
len_rtx = expand_normal (len);
sth like
Index: gcc/builtins.c
===================================================================
--- gcc/builtins.c (revision 209890)
+++ gcc/builtins.c (working copy)
@@ -3685,20 +3685,20 @@ expand_builtin_memset_args (tree dest, t
if (expected_align < dest_align)
expected_align = dest_align;
+ /* Stabilize the arguments in case we fail. */
+ dest = builtin_save_expr (dest);
+ val = builtin_save_expr (val);
+ len = builtin_save_expr (len);
+
+ len_rtx = expand_normal (len);
/* If the LEN parameter is zero, return DEST. */
- if (integer_zerop (len))
+ if (len_rtx == const0_rtx)
{
/* Evaluate and ignore VAL in case it has side-effects. */
expand_expr (val, const0_rtx, VOIDmode, EXPAND_NORMAL);
return expand_expr (dest, target, mode, EXPAND_NORMAL);
}
- /* Stabilize the arguments in case we fail. */
- dest = builtin_save_expr (dest);
- val = builtin_save_expr (val);
- len = builtin_save_expr (len);
-
- len_rtx = expand_normal (len);
determine_block_size (len, len_rtx, &min_size, &max_size,
&probable_max_size);
dest_mem = get_memory_rtx (dest, len);
probably applies to almost all builtin expansions.
But I'd say the backend should be more fault-tolerant here. It can't
simply reserve len == 0 for itself.