re PR rtl-optimization/40924 (miscompiles with -O3 (seemingly related to attribute may_alias))
PR rtl-optimization/40924 * dse.c (canon_address): Before calling cselib_expand_value_rtx make sure canon_rtx (mem_address) isn't simpler than canon_rtx (expanded_mem_address). * g++.dg/torture/pr40924.C: New test. From-SVN: r150483
This commit is contained in:
parent
64393e407d
commit
403c752036
4 changed files with 202 additions and 61 deletions
|
@ -1,3 +1,10 @@
|
|||
2009-08-05 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR rtl-optimization/40924
|
||||
* dse.c (canon_address): Before calling cselib_expand_value_rtx
|
||||
make sure canon_rtx (mem_address) isn't simpler than
|
||||
canon_rtx (expanded_mem_address).
|
||||
|
||||
2009-08-05 Li Feng <nemokingdom@gmail.com>
|
||||
|
||||
* graphite-sese-to-poly.c (build_pbb_drs): Remove build alias set
|
||||
|
|
140
gcc/dse.c
140
gcc/dse.c
|
@ -1070,6 +1070,8 @@ canon_address (rtx mem,
|
|||
{
|
||||
rtx mem_address = XEXP (mem, 0);
|
||||
rtx expanded_address, address;
|
||||
int expanded;
|
||||
|
||||
/* Make sure that cselib is has initialized all of the operands of
|
||||
the address before asking it to do the subst. */
|
||||
|
||||
|
@ -1114,72 +1116,88 @@ canon_address (rtx mem,
|
|||
fprintf (dump_file, "\n");
|
||||
}
|
||||
|
||||
/* Use cselib to replace all of the reg references with the full
|
||||
expression. This will take care of the case where we have
|
||||
|
||||
r_x = base + offset;
|
||||
val = *r_x;
|
||||
|
||||
by making it into
|
||||
|
||||
val = *(base + offset);
|
||||
*/
|
||||
|
||||
expanded_address = cselib_expand_value_rtx (mem_address, scratch, 5);
|
||||
|
||||
/* If this fails, just go with the mem_address. */
|
||||
if (!expanded_address)
|
||||
expanded_address = mem_address;
|
||||
|
||||
/* Split the address into canonical BASE + OFFSET terms. */
|
||||
address = canon_rtx (expanded_address);
|
||||
|
||||
*offset = 0;
|
||||
|
||||
if (dump_file)
|
||||
/* First see if just canon_rtx (mem_address) is const or frame,
|
||||
if not, try cselib_expand_value_rtx and call canon_rtx on that. */
|
||||
address = NULL_RTX;
|
||||
for (expanded = 0; expanded < 2; expanded++)
|
||||
{
|
||||
fprintf (dump_file, "\n after cselib_expand address: ");
|
||||
print_inline_rtx (dump_file, expanded_address, 0);
|
||||
fprintf (dump_file, "\n");
|
||||
|
||||
fprintf (dump_file, "\n after canon_rtx address: ");
|
||||
print_inline_rtx (dump_file, address, 0);
|
||||
fprintf (dump_file, "\n");
|
||||
}
|
||||
|
||||
if (GET_CODE (address) == CONST)
|
||||
address = XEXP (address, 0);
|
||||
|
||||
if (GET_CODE (address) == PLUS && CONST_INT_P (XEXP (address, 1)))
|
||||
{
|
||||
*offset = INTVAL (XEXP (address, 1));
|
||||
address = XEXP (address, 0);
|
||||
}
|
||||
|
||||
if (const_or_frame_p (address))
|
||||
{
|
||||
group_info_t group = get_group_info (address);
|
||||
|
||||
if (dump_file)
|
||||
fprintf (dump_file, " gid=%d offset=%d \n", group->id, (int)*offset);
|
||||
*base = NULL;
|
||||
*group_id = group->id;
|
||||
}
|
||||
else
|
||||
{
|
||||
*base = cselib_lookup (address, Pmode, true);
|
||||
*group_id = -1;
|
||||
|
||||
if (*base == NULL)
|
||||
if (expanded)
|
||||
{
|
||||
if (dump_file)
|
||||
fprintf (dump_file, " no cselib val - should be a wild read.\n");
|
||||
return false;
|
||||
/* Use cselib to replace all of the reg references with the full
|
||||
expression. This will take care of the case where we have
|
||||
|
||||
r_x = base + offset;
|
||||
val = *r_x;
|
||||
|
||||
by making it into
|
||||
|
||||
val = *(base + offset); */
|
||||
|
||||
expanded_address = cselib_expand_value_rtx (mem_address,
|
||||
scratch, 5);
|
||||
|
||||
/* If this fails, just go with the address from first
|
||||
iteration. */
|
||||
if (!expanded_address)
|
||||
break;
|
||||
}
|
||||
else
|
||||
expanded_address = mem_address;
|
||||
|
||||
/* Split the address into canonical BASE + OFFSET terms. */
|
||||
address = canon_rtx (expanded_address);
|
||||
|
||||
*offset = 0;
|
||||
|
||||
if (dump_file)
|
||||
fprintf (dump_file, " varying cselib base=%d offset = %d\n",
|
||||
(*base)->value, (int)*offset);
|
||||
{
|
||||
if (expanded)
|
||||
{
|
||||
fprintf (dump_file, "\n after cselib_expand address: ");
|
||||
print_inline_rtx (dump_file, expanded_address, 0);
|
||||
fprintf (dump_file, "\n");
|
||||
}
|
||||
|
||||
fprintf (dump_file, "\n after canon_rtx address: ");
|
||||
print_inline_rtx (dump_file, address, 0);
|
||||
fprintf (dump_file, "\n");
|
||||
}
|
||||
|
||||
if (GET_CODE (address) == CONST)
|
||||
address = XEXP (address, 0);
|
||||
|
||||
if (GET_CODE (address) == PLUS
|
||||
&& CONST_INT_P (XEXP (address, 1)))
|
||||
{
|
||||
*offset = INTVAL (XEXP (address, 1));
|
||||
address = XEXP (address, 0);
|
||||
}
|
||||
|
||||
if (const_or_frame_p (address))
|
||||
{
|
||||
group_info_t group = get_group_info (address);
|
||||
|
||||
if (dump_file)
|
||||
fprintf (dump_file, " gid=%d offset=%d \n",
|
||||
group->id, (int)*offset);
|
||||
*base = NULL;
|
||||
*group_id = group->id;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
*base = cselib_lookup (address, Pmode, true);
|
||||
*group_id = -1;
|
||||
|
||||
if (*base == NULL)
|
||||
{
|
||||
if (dump_file)
|
||||
fprintf (dump_file, " no cselib val - should be a wild read.\n");
|
||||
return false;
|
||||
}
|
||||
if (dump_file)
|
||||
fprintf (dump_file, " varying cselib base=%d offset = %d\n",
|
||||
(*base)->value, (int)*offset);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2009-08-05 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR rtl-optimization/40924
|
||||
* g++.dg/torture/pr40924.C: New test.
|
||||
|
||||
2009-08-05 Manuel López-Ibáñez <manu@gcc.gnu.org>
|
||||
|
||||
PR c++/36069
|
||||
|
|
111
gcc/testsuite/g++.dg/torture/pr40924.C
Normal file
111
gcc/testsuite/g++.dg/torture/pr40924.C
Normal file
|
@ -0,0 +1,111 @@
|
|||
// PR rtl-optimization/40924
|
||||
// { dg-do run }
|
||||
|
||||
extern "C" void abort (void);
|
||||
|
||||
#define MAY_ALIAS __attribute__((__may_alias__))
|
||||
|
||||
typedef struct { float v[2]; } floata;
|
||||
typedef struct { int v[2]; } inta;
|
||||
|
||||
typedef unsigned int uint MAY_ALIAS;
|
||||
typedef signed int sint MAY_ALIAS;
|
||||
typedef float flt MAY_ALIAS;
|
||||
|
||||
static inline unsigned short
|
||||
less_than (inta a, inta b)
|
||||
{
|
||||
unsigned short r = 0;
|
||||
const uint *p1 = (const uint *) &a;
|
||||
const uint *p2 = (const uint *) &b;
|
||||
for (int i=0; i < 2; i++)
|
||||
if (p1[i] < p2[i]) r |= (1 << i);
|
||||
return r;
|
||||
}
|
||||
|
||||
static inline inta
|
||||
multiply (inta b, inta c)
|
||||
{
|
||||
inta r;
|
||||
sint *p3 = (sint *) &c;
|
||||
for (int i=0; i < 2; i++)
|
||||
r.v[i] = (int) (b.v[i] * p3[i] & 0xFFFFFFFF);
|
||||
return r;
|
||||
}
|
||||
|
||||
static inline floata
|
||||
gather (inta indexes, const void *baseAddr)
|
||||
{
|
||||
floata r;
|
||||
|
||||
sint *idx = (sint *) &indexes;
|
||||
flt *src = (flt *) baseAddr;
|
||||
for (int i=0; i < 2; i++)
|
||||
r.v[i] = *(src + idx[i]);
|
||||
return r;
|
||||
}
|
||||
|
||||
static inline inta
|
||||
add (const inta &b, const inta &c)
|
||||
{
|
||||
inta result;
|
||||
sint *r = (sint *) &result;
|
||||
|
||||
for (int i=0; i < 2; i++)
|
||||
r[i] = b.v[i] + c.v[i];
|
||||
return result;
|
||||
}
|
||||
|
||||
struct uintv
|
||||
{
|
||||
inta data;
|
||||
inline uintv () { data.v[0] = 0; data.v[1] = 1; }
|
||||
inline uintv (unsigned int a)
|
||||
{
|
||||
for (int i=0; i < 2; i++)
|
||||
*(uint *) &data.v[i] = a;
|
||||
}
|
||||
inline uintv (inta x) : data (x) {}
|
||||
inline uintv operator* (const uintv &x) const
|
||||
{ return multiply (data, x.data); }
|
||||
inline uintv operator+ (const uintv &x) const
|
||||
{ return uintv (add (data, x.data)); }
|
||||
inline unsigned short operator< (const uintv &x) const
|
||||
{ return less_than (data, x.data); }
|
||||
};
|
||||
|
||||
struct floatv
|
||||
{
|
||||
floata data;
|
||||
explicit inline floatv (const uintv &x)
|
||||
{
|
||||
uint *p2 = (uint *) &x.data;
|
||||
for (int i=0; i < 2; i++)
|
||||
data.v[i] = p2[i];
|
||||
}
|
||||
inline floatv (const float *array, const uintv &indexes)
|
||||
{
|
||||
const uintv &offsets = indexes * uintv (1);
|
||||
data = gather (offsets.data, array);
|
||||
}
|
||||
unsigned short operator== (const floatv &x) const
|
||||
{
|
||||
unsigned short r = 0;
|
||||
for (int i=0; i < 2; i++)
|
||||
if (data.v[i] == x.data.v[i]) r |= (1 << i);
|
||||
return r;
|
||||
}
|
||||
};
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
const float array[2] = { 2, 3 };
|
||||
for (uintv i; (i < 2) == 3; i = i + 2)
|
||||
{
|
||||
const floatv ii (i + 2);
|
||||
floatv a (array, i);
|
||||
if ((a == ii) != 3)
|
||||
abort ();
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue