Message ID | 07f101d87b38$8c2b42a0$a481c7e0$@nextmovesoftware.com |
---|---|
State | New |
Headers | show |
Series | PR middle-end/105874: Use EXPAND_MEMORY to fix ada bootstrap. | expand |
> The fix is to ensure that we call expand_expr with EXPAND_MEMORY > when processing the VAR_DECL's returned by get_inner_reference. > > This patch has been tested on x86_64-pc-linux-gnu with make bootstrap > and make -k check (with no new failures), but also with > --enable-languages="ada" where it allows the bootstrap to finish, > and with no unexpected failures in the acats and gnat testsuites. > Ok for mainline? Yes, thanks (modulo the nit in the ChangeLog). > 2022-06-08 Roger Sayle <roger@nextmovesoftware.com> > > gcc/ChangeLog > PR middle-end/105874 > * gcc/expr.cc (expand_expr_real_1) <normal_inner_ref>: New local > variable tem_modifier for calculating the expand_modifier enum to > use for expanding tem. If tem is a VAR_DECL, use EXPAND_MEMORY. gcc/ prefix to be stripped
On Wed, Jun 8, 2022 at 4:14 PM Eric Botcazou via Gcc-patches <gcc-patches@gcc.gnu.org> wrote: > > > The fix is to ensure that we call expand_expr with EXPAND_MEMORY > > when processing the VAR_DECL's returned by get_inner_reference. > > > > This patch has been tested on x86_64-pc-linux-gnu with make bootstrap > > and make -k check (with no new failures), but also with > > --enable-languages="ada" where it allows the bootstrap to finish, > > and with no unexpected failures in the acats and gnat testsuites. > > Ok for mainline? > > Yes, thanks (modulo the nit in the ChangeLog). + /* If tem is a VAR_DECL, we need a memory reference. */ + enum expand_modifier tem_modifier = modifier; + if (tem_modifier == EXPAND_SUM) + tem_modifier = EXPAND_NORMAL; + if (TREE_CODE (tem) == VAR_DECL) + tem_modifier = EXPAND_MEMORY; that changes EXPAND_WRITE to EXPAND_MEMORY for VAR_DECL for example - what's 'modifier' in the problematic case? I do not understand how 'VAR_DECL' is special here btw. - it seems to be a condition making sure the new optimization doesn't trigger rather than a condition that will always require memory? Richard. > > 2022-06-08 Roger Sayle <roger@nextmovesoftware.com> > > > > gcc/ChangeLog > > PR middle-end/105874 > > * gcc/expr.cc (expand_expr_real_1) <normal_inner_ref>: New local > > variable tem_modifier for calculating the expand_modifier enum to > > use for expanding tem. If tem is a VAR_DECL, use EXPAND_MEMORY. > > gcc/ prefix to be stripped > > -- > Eric Botcazou > >
> + /* If tem is a VAR_DECL, we need a memory reference. */ > + enum expand_modifier tem_modifier = modifier; > + if (tem_modifier == EXPAND_SUM) > + tem_modifier = EXPAND_NORMAL; > + if (TREE_CODE (tem) == VAR_DECL) > + tem_modifier = EXPAND_MEMORY; > > that changes EXPAND_WRITE to EXPAND_MEMORY for VAR_DECL > for example - what's 'modifier' in the problematic case? My understanding is that it was EXPAND_NORMAL. > I do not understand how 'VAR_DECL' is special here btw. - it seems to be a > condition making sure the new optimization doesn't trigger rather than a > condition that will always require memory? It may indeed be too big a hammer. Roger, would it be sufficient to use EXPAND_MEMORY only when must_force_mem computed a few lines below if true?
diff --git a/gcc/expr.cc b/gcc/expr.cc index fb062dc..a013650 100644 --- a/gcc/expr.cc +++ b/gcc/expr.cc @@ -11183,6 +11183,13 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode, infinitely recurse. */ gcc_assert (tem != exp); + /* If tem is a VAR_DECL, we need a memory reference. */ + enum expand_modifier tem_modifier = modifier; + if (tem_modifier == EXPAND_SUM) + tem_modifier = EXPAND_NORMAL; + if (TREE_CODE (tem) == VAR_DECL) + tem_modifier = EXPAND_MEMORY; + /* If TEM's type is a union of variable size, pass TARGET to the inner computation, since it will need a temporary and TARGET is known to have to do. This occurs in unchecked conversion in Ada. */ @@ -11194,9 +11201,7 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode, != INTEGER_CST) && modifier != EXPAND_STACK_PARM ? target : NULL_RTX), - VOIDmode, - modifier == EXPAND_SUM ? EXPAND_NORMAL : modifier, - NULL, true); + VOIDmode, tem_modifier, NULL, true); /* If the field has a mode, we want to access it in the field's mode, not the computed mode. diff --git a/gcc/testsuite/g++.dg/opt/pr105874.C b/gcc/testsuite/g++.dg/opt/pr105874.C new file mode 100644 index 0000000..58699a6 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr105874.C @@ -0,0 +1,30 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -std=c++11" } */ +#include <array> + +static constexpr int NBR_SHIFT = 4; + +static constexpr int MAXBOARDSIZE = 25; + +static constexpr int MAXSQ = ((MAXBOARDSIZE + 2) * (MAXBOARDSIZE + 2)); + +enum square_t : char { + BLACK = 0, WHITE = 1, EMPTY = 2, INVAL = 3 + }; + +const std::array<int, 2> s_eyemask = { + 4 * (1 << (NBR_SHIFT * BLACK)), + 4 * (1 << (NBR_SHIFT * WHITE)) +}; + +/* counts of neighboring stones */ +std::array<unsigned short, MAXSQ> m_neighbours; + +int is_eye(const int color, const int i) { + /* check for 4 neighbors of the same color */ + int ownsurrounded = (m_neighbours[i] & s_eyemask[color]); + + return ownsurrounded; +} + +/* { dg-final { scan-assembler "s_eyemask" } } */