On Thu, 15 Jul 2021, Jakub Jelinek wrote:

> Hi!
> 
> Andrew's recent change to optimize away during gimplification not just
> assignments of zero sized types, but also assignments of empty types,
> caused infinite recursion in the gimplifier.
> If such assignment is optimized away, we gimplify separately the to_p
> and from_p operands and throw away the result.  When gimplifying the
> operand that is volatile, we run into the gimplifier code below, which has
> different handling for types with non-BLKmode mode, tries to gimplify
> those as vol.N = expr, and for BLKmode just throws those away.
> Zero sized types will always have BLKmode and so are fine, but for the
> non-BLKmode ones like struct S in the testcase, the vol.N = expr
> gimplification will reach again the gimplify_modify_expr code, see it is
> assignment of empty type and will gimplify again vol.N separately
> (non-volatile, so ok) and expr, on which it will recurse again.
> 
> The following patch breaks that infinite recursion by ignoring bare
> volatile loads from empty types.
> If a volatile load or store for aggregates are supposed to be member-wise
> loads or stores, then there are no non-padding members in the empty types that
> should be copied and so it is probably ok.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

OK.

Thanks,
Richard.

> 2021-07-15  Jakub Jelinek  <ja...@redhat.com>
> 
>       PR middle-end/101437
>       * gimplify.c (gimplify_expr): Throw away volatile reads from empty
>       types even if they have non-BLKmode TYPE_MODE.
> 
>       * gcc.c-torture/compile/pr101437.c: New test.
> 
> --- gcc/gimplify.c.jj 2021-06-25 10:36:22.232019090 +0200
> +++ gcc/gimplify.c    2021-07-14 13:24:28.860486677 +0200
> @@ -15060,7 +15060,8 @@ gimplify_expr (tree *expr_p, gimple_seq
>         *expr_p = NULL;
>       }
>        else if (COMPLETE_TYPE_P (TREE_TYPE (*expr_p))
> -            && TYPE_MODE (TREE_TYPE (*expr_p)) != BLKmode)
> +            && TYPE_MODE (TREE_TYPE (*expr_p)) != BLKmode
> +            && !is_empty_type (TREE_TYPE (*expr_p)))
>       {
>         /* Historically, the compiler has treated a bare reference
>            to a non-BLKmode volatile lvalue as forcing a load.  */
> --- gcc/testsuite/gcc.c-torture/compile/pr101437.c.jj 2021-07-14 
> 13:35:57.155100700 +0200
> +++ gcc/testsuite/gcc.c-torture/compile/pr101437.c    2021-07-14 
> 13:35:41.430314232 +0200
> @@ -0,0 +1,29 @@
> +/* PR middle-end/101437 */
> +
> +struct S { int : 1; };
> +
> +void
> +foo (volatile struct S *p)
> +{
> +  struct S s = {};
> +  *p = s;
> +}
> +
> +void
> +bar (volatile struct S *p)
> +{
> +  *p;
> +}
> +
> +void
> +baz (volatile struct S *p)
> +{
> +  struct S s;
> +  s = *p;
> +}
> +
> +void
> +qux (volatile struct S *p, volatile struct S *q)
> +{
> +  *p = *q;
> +}
> 
>       Jakub
> 
> 

-- 
Richard Biener <rguent...@suse.de>
SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg,
Germany; GF: Felix Imendörffer; HRB 36809 (AG Nuernberg)

Reply via email to