[PATCH] Fix up wrong-code caused by store_expr (PR middle-end/90025)

Richard Biener rguenther@suse.de
Wed Apr 10 08:12:00 GMT 2019


On Wed, 10 Apr 2019, Jakub Jelinek wrote:

> Hi!
> 
> In r268957 aka PR66152 fix I've slightly changed the store_expr
> code which does store_by_pieces for just a part of an array and
> clear_storage for the rest and since then the following testcase
> is miscompiled on s390x-linux.  I believe one could construct other testcase
> that would be miscompiled before as well though.
> 
> The problem is that store_by_pieces with RETURN_END returns a MEM object
> with QImode and thus also MEM_SIZE of 1, we then adjust_address it to
> BLKmode which doesn't change MEM_SIZE and nothing at least in the generic
> clear_storage code tweaks that MEM_SIZE later on (and while perhaps some
> targets do, e.g. s390 does not).  Because in this case the size is
> really known and constant, the following patch makes sure we do
> what adjust_address does, but in addition make sure to set MEM_SIZE
> properly.  When MEM_SIZE is 1 and in the testcase there is a store after
> it to the first few bytes of the remainder, RTL DSE happily removes that
> memory clear insn emitted for clear_storage, because if it was really size
> 1, it would be indeed redundant, but there are 20 bytes that are not
> redundant after it.
> 
> Bootstrapped/regtested on {x86_64,i686,s390x,powerpc64le}-linux, ok for
> trunk?

OK.

Richard.

> 2019-04-10  Jakub Jelinek  <jakub@redhat.com>
> 
> 	PR middle-end/90025
> 	* expr.c (store_expr): Set properly size on the MEM passed to
> 	clear_storage.
> 
> 	* gcc.c-torture/execute/pr90025.c: New test.
> 
> --- gcc/expr.c.jj	2019-02-21 00:01:59.418057433 +0100
> +++ gcc/expr.c	2019-04-09 12:49:20.704457867 +0200
> @@ -5658,7 +5658,8 @@ store_expr (tree exp, rtx target, int ca
>        dest_mem = store_by_pieces (target, str_copy_len, string_cst_read_str,
>  				  (void *) str, MEM_ALIGN (target), false,
>  				  RETURN_END);
> -      clear_storage (adjust_address (dest_mem, BLKmode, 0),
> +      clear_storage (adjust_address_1 (dest_mem, BLKmode, 0, 1, 1, 0,
> +				       exp_len - str_copy_len),
>  		     GEN_INT (exp_len - str_copy_len), BLOCK_OP_NORMAL);
>        return NULL_RTX;
>      }
> --- gcc/testsuite/gcc.c-torture/execute/pr90025.c.jj	2019-04-09 12:59:35.876449686 +0200
> +++ gcc/testsuite/gcc.c-torture/execute/pr90025.c	2019-04-09 12:59:20.156705430 +0200
> @@ -0,0 +1,28 @@
> +/* PR middle-end/90025 */
> +
> +__attribute__((noipa)) void
> +bar (char *p)
> +{
> +  int i;
> +  for (i = 0; i < 6; i++)
> +    if (p[i] != "foobar"[i])
> +      __builtin_abort ();
> +  for (; i < 32; i++)
> +    if (p[i] != '\0')
> +      __builtin_abort ();
> +}
> +
> +__attribute__((noipa)) void
> +foo (unsigned int x)
> +{
> +  char s[32] = { 'f', 'o', 'o', 'b', 'a', 'r', 0 };
> +  ((unsigned int *) s)[2] = __builtin_bswap32 (x);
> +  bar (s);
> +}
> +
> +int
> +main ()
> +{
> +  foo (0);
> +  return 0;
> +}
> 
> 	Jakub
> 

-- 
Richard Biener <rguenther@suse.de>
SUSE Linux GmbH, Maxfeldstrasse 5, 90409 Nuernberg, Germany;
GF: Felix Imendörffer, Mary Higgins, Sri Rasiah; HRB 21284 (AG NÌrnberg)


More information about the Gcc-patches mailing list