Hi all, In some targets, initialization code for char array may be split into two parts even if the initialization consists of all zeros:
/* example */ extern void foo(char*); void test(void) { char a[256] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 }; foo(a); } ;; Xtensa (xtensa-lx106) .LC0: .string "" .string "" .string "" .string "" .string "" .string "" .string "" .string "" .string "" .string "" .zero 246 test: movi a9, 0x110 sub sp, sp, a9 l32r a3, .LC1 movi.n a4, 0xa mov.n a2, sp s32i a0, sp, 268 call0 memcpy movi a4, 0xf6 movi.n a3, 0 addi.n a2, sp, 10 call0 memset mov.n a2, sp call0 foo l32i a0, sp, 268 movi a9, 0x110 add.n sp, sp, a9 ret.n ;; H8/300 (-mh -mint32) .LC0: .string "" .string "" .string "" .string "" .string "" .string "" .string "" .string "" .string "" .string "" .zero 246 _test: sub.l #256,er7 sub.l er2,er2 add.b #10,r2l mov.l #.LC0,er1 mov.l er7,er0 jsr @_memcpy sub.l er2,er2 add.b #246,r2l sub.l er1,er1 sub.l er0,er0 add.b #10,r0l add.l er7,er0 jsr @_memset mov.l er7,er0 jsr @_foo add.l #256,er7 rts i386 target (both 32 and 64bit) does not show such behavior. gcc/ChangeLog: * expr.cc (store_expr): Add check if the initialization content consists of all zeros. --- gcc/expr.cc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/gcc/expr.cc b/gcc/expr.cc index 7197996cec7..f94310dc7b9 100644 --- a/gcc/expr.cc +++ b/gcc/expr.cc @@ -6015,6 +6015,7 @@ store_expr (tree exp, rtx target, int call_param_p, rtx dest_mem; tree str = TREE_CODE (exp) == STRING_CST ? exp : TREE_OPERAND (TREE_OPERAND (exp, 0), 0); + char ch; exp_len = int_expr_size (exp); if (exp_len <= 0) @@ -6032,6 +6033,12 @@ store_expr (tree exp, rtx target, int call_param_p, } str_copy_len = TREE_STRING_LENGTH (str); + /* If str contains only zeroes, no need to store to target. */ + ch = 0; + for (HOST_WIDE_INT i = 0; i < str_copy_len; ++i) + ch |= TREE_STRING_POINTER (str)[i]; + if (ch == 0) + str_copy_len = 0; if ((STORE_MAX_PIECES & (STORE_MAX_PIECES - 1)) == 0) { str_copy_len += STORE_MAX_PIECES - 1; -- 2.20.1