diff options
-rw-r--r-- | gcc/testsuite/g++.dg/pr69123.C | 95 | ||||
-rw-r--r-- | gcc/var-tracking.c | 12 |
2 files changed, 101 insertions, 6 deletions
diff --git a/gcc/testsuite/g++.dg/pr69123.C b/gcc/testsuite/g++.dg/pr69123.C new file mode 100644 index 00000000000..0546e2074a5 --- /dev/null +++ b/gcc/testsuite/g++.dg/pr69123.C @@ -0,0 +1,95 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -g" } */ + +/* This was reduced from gcc/tree-vect-slp.c by H.J.Lu. */ + +struct xxx_def; +typedef xxx_def *xxx; + +union rtxxx +{ + const char *rt_str; + xxx rt_xxx; +}; + +struct xxx_def { + union u { + rtxxx fld[1]; + } u; +}; + +extern xxx bar (void); +extern int foo1 (xxx); + +static inline xxx +foo2 (xxx arg0, xxx arg1) +{ + xxx rt; + rt = bar (); + (((rt)->u.fld[0]).rt_xxx) = arg0; + (((rt)->u.fld[1]).rt_xxx) = arg1; + return rt; +} + +static inline xxx +foo4 (const char *arg0 ) +{ + xxx rt; + rt = bar (); + (((rt)->u.fld[0]).rt_str) = arg0; + (((rt)->u.fld[1]).rt_xxx) = (xxx) 0; + return rt; +} + +extern xxx foo5 (long); + +struct address_cost_data +{ + unsigned costs[2][2][2][2]; +}; + +void +get_address_cost (address_cost_data *data) +{ + unsigned acost; + long i; + long rat, off = 0; + unsigned sym_p, var_p, off_p, rat_p; + xxx addr, base; + xxx reg0, reg1; + + reg1 = bar (); + addr = foo2 (reg1, (xxx) 0); + rat = 1; + acost = 0; + reg0 = bar (); + reg1 = bar (); + + for (i = 0; i < 16; i++) + { + sym_p = i & 1; + var_p = (i >> 1) & 1; + off_p = (i >> 2) & 1; + rat_p = (i >> 3) & 1; + + addr = reg0; + if (rat_p) + addr = foo2 (addr, foo5 (rat)) ; + + if (var_p) + addr = foo2 (addr, reg1); + + if (sym_p) + base = foo4 (""); + else if (off_p) + base = foo5 (off); + else + base = (xxx) 0; + + if (base) + addr = foo2 (addr, base); + + acost = foo1 (addr); + data->costs[sym_p][var_p][off_p][rat_p] = acost; + } +} diff --git a/gcc/var-tracking.c b/gcc/var-tracking.c index 023a73eddc3..86183b3f0cd 100644 --- a/gcc/var-tracking.c +++ b/gcc/var-tracking.c @@ -2224,7 +2224,7 @@ struct overlapping_mems }; /* Remove all MEMs that overlap with COMS->LOC from the location list - of a hash table entry for a value. COMS->ADDR must be a + of a hash table entry for a onepart variable. COMS->ADDR must be a canonicalized form of COMS->LOC's address, and COMS->LOC must be canonicalized itself. */ @@ -2235,7 +2235,7 @@ drop_overlapping_mem_locs (variable **slot, overlapping_mems *coms) rtx mloc = coms->loc, addr = coms->addr; variable *var = *slot; - if (var->onepart == ONEPART_VALUE) + if (var->onepart != NOT_ONEPART) { location_chain *loc, **locp; bool changed = false; @@ -4682,11 +4682,11 @@ dataflow_set_preserve_mem_locs (variable **slot, dataflow_set *set) { for (loc = var->var_part[0].loc_chain; loc; loc = loc->next) { - /* We want to remove dying MEMs that doesn't refer to DECL. */ + /* We want to remove dying MEMs that don't refer to DECL. */ if (GET_CODE (loc->loc) == MEM && (MEM_EXPR (loc->loc) != decl || INT_MEM_OFFSET (loc->loc) != 0) - && !mem_dies_at_call (loc->loc)) + && mem_dies_at_call (loc->loc)) break; /* We want to move here MEMs that do refer to DECL. */ else if (GET_CODE (loc->loc) == VALUE @@ -4769,14 +4769,14 @@ dataflow_set_preserve_mem_locs (variable **slot, dataflow_set *set) } /* Remove all MEMs from the location list of a hash table entry for a - value. */ + onepart variable. */ int dataflow_set_remove_mem_locs (variable **slot, dataflow_set *set) { variable *var = *slot; - if (var->onepart == ONEPART_VALUE) + if (var->onepart != NOT_ONEPART) { location_chain *loc, **locp; bool changed = false; |