[PATCH] Fix PR84003
Richard Biener
rguenther@suse.de
Sat Jan 27 11:04:00 GMT 2018
On Fri, 26 Jan 2018, Richard Biener wrote:
> On Fri, 26 Jan 2018, Jakub Jelinek wrote:
>
> > On Thu, Jan 25, 2018 at 12:18:21PM +0100, Richard Biener wrote:
> > > 2018-01-25 Richard Biener <rguenther@suse.de>
> > >
> > > PR rtl-optimization/84003
> > > * dse.c (dse_step1): When removing redundant stores make sure
> > > to adjust the earlier stores alias-set to match semantics of
> > > the removed one and its own.
> > > (dse_step6): Likewise.
> > >
> > > * g++.dg/torture/pr77745.C: Mark foo noinline to trigger
> > > latent bug in DSE.
> > >
> > > Index: gcc/dse.c
> > > ===================================================================
> > > --- gcc/dse.c (revision 257043)
> > > +++ gcc/dse.c (working copy)
> > > @@ -2725,6 +2725,19 @@ dse_step1 (void)
> > > "eliminated\n",
> > > INSN_UID (ptr->insn),
> > > INSN_UID (s_info->redundant_reason->insn));
> > > + /* If the later store we delete could have changed the
> > > + dynamic type of the memory make sure the one we
> > > + preserve serves as a store for all loads that could
> > > + validly have accessed the one we delete. */
> > > + store_info *r_info = s_info->redundant_reason->store_rec;
> > > + while (r_info)
> > > + {
> > > + if (r_info->is_set
> > > + && (MEM_ALIAS_SET (s_info->mem)
> > > + != MEM_ALIAS_SET (r_info->mem)))
> > > + set_mem_alias_set (r_info->mem, 0);
> >
> > Is alias set 0 the only easily computable choice if there is a mismatch?
> > Also, isn't it fine if one of the alias set is a subset of the other one?
> >
> > More importantly, I think set_mem_alias_set (r_info->mem, 0) can't work,
> > r_info->mem is a result of canon_rtx (SET_DEST (body)), so sometimes could
> > be the MEM that appears in the instruction, but at other times could be a
> > different pointer and changing that wouldn't change anything in the actual
> > instruction. So, in order to do this you'd need to add probably another
> > field and record the original SET_DEST (body) record_store is called with.
>
> Uh, indeed. See my mail in response to Richard which comes up with
> an alternate patch avoiding this issue.
>
> > Even that doesn't need to be something that really appears in the
> > instruction, but the exception in that case is the memset call and that
> > semantically has alias set of 0.
> >
> > > --- gcc/testsuite/g++.dg/torture/pr77745.C (revision 257043)
> > > +++ gcc/testsuite/g++.dg/torture/pr77745.C (working copy)
> > > @@ -2,7 +2,7 @@
> > >
> > > inline void* operator new(__SIZE_TYPE__, void* __p) noexcept { return __p; }
> > >
> > > -long foo(char *c1, char *c2)
> > > +long __attribute__((noinline)) foo(char *c1, char *c2)
> > > {
> > > long *p1 = new (c1) long;
> > > *p1 = 100;
> >
> > Is it desirable to modify an existing test, rather than say macroize this
> > and add pr77745-2.C that will define some macro and include this pr77745.C,
> > such that we cover both noinline and without noinline?
>
> Yeah, I'll do that.
This is what I have applied, bootstrapped and tested on
x86_64-unknown-linux-gnu.
Richard.
2018-01-26 Richard Biener <rguenther@suse.de>
PR rtl-optimization/84003
* dse.c (record_store): Only record redundant stores when
the earlier store aliases at least all accesses the later one does.
* g++.dg/torture/pr77745.C: Mark foo noinline to trigger
latent bug in DSE if NOINLINE is appropriately defined.
* g++.dg/torture/pr77745-2.C: New testcase including pr77745.C
and defining NOINLINE.
Index: gcc/dse.c
===================================================================
--- gcc/dse.c (revision 257077)
+++ gcc/dse.c (working copy)
@@ -1532,7 +1532,12 @@ record_store (rtx body, bb_info_t bb_inf
&& known_subrange_p (offset, width,
s_info->offset, s_info->width)
&& all_positions_needed_p (s_info, offset - s_info->offset,
- width))
+ width)
+ /* We can only remove the later store if the earlier aliases
+ at least all accesses the later one. */
+ && (MEM_ALIAS_SET (mem) == MEM_ALIAS_SET (s_info->mem)
+ || alias_set_subset_of (MEM_ALIAS_SET (mem),
+ MEM_ALIAS_SET (s_info->mem))))
{
if (GET_MODE (mem) == BLKmode)
{
Index: gcc/testsuite/g++.dg/torture/pr77745.C
===================================================================
--- gcc/testsuite/g++.dg/torture/pr77745.C (revision 257080)
+++ gcc/testsuite/g++.dg/torture/pr77745.C (working copy)
@@ -1,8 +1,12 @@
// { dg-do run }
+#ifndef NOINLINE
+#define NOINLINE /* */
+#endif
+
inline void* operator new(__SIZE_TYPE__, void* __p) noexcept { return __p; }
-long foo(char *c1, char *c2)
+long NOINLINE foo(char *c1, char *c2)
{
long *p1 = new (c1) long;
*p1 = 100;
Index: gcc/testsuite/g++.dg/torture/pr77745-2.C
===================================================================
--- gcc/testsuite/g++.dg/torture/pr77745-2.C (nonexistent)
+++ gcc/testsuite/g++.dg/torture/pr77745-2.C (working copy)
@@ -0,0 +1,4 @@
+// { dg-do run }
+
+#define NOINLINE __attribute__((noinline))
+#include "pr77745.C"
More information about the Gcc-patches
mailing list