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)