re PR tree-optimization/48702 (optimization regression with gcc-4.6 on x86_64-unknown-linux-gnu)

2011-05-26  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/48702
	* tree-ssa-address.c (create_mem_ref_raw): Create MEM_REFs
	only when we know the base address is within bounds.
	* tree-ssa-alias.c (indirect_ref_may_alias_decl_p): Do not
	assume the base address of TARGET_MEM_REFs is in bounds.

	* gcc.dg/torture/pr48702.c: New testcase.

From-SVN: r174282
This commit is contained in:
Richard Guenther 2011-05-26 13:01:48 +00:00 committed by Richard Biener
parent 7e32e6521a
commit ac8e18759f
5 changed files with 70 additions and 6 deletions

View File

@ -1,3 +1,11 @@
2011-05-26 Richard Guenther <rguenther@suse.de>
PR tree-optimization/48702
* tree-ssa-address.c (create_mem_ref_raw): Create MEM_REFs
only when we know the base address is within bounds.
* tree-ssa-alias.c (indirect_ref_may_alias_decl_p): Do not
assume the base address of TARGET_MEM_REFs is in bounds.
2011-05-26 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
PR target/49099

View File

@ -1,3 +1,8 @@
2011-05-26 Richard Guenther <rguenther@suse.de>
PR tree-optimization/48702
* gcc.dg/torture/pr48702.c: New testcase.
2011-05-26 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
PR gcov-profile/48845

View File

@ -0,0 +1,47 @@
/* { dg-do run } */
extern void abort (void);
#define LEN 4
static inline void unpack(int array[LEN])
{
int ii, val;
val = 1;
for (ii = 0; ii < LEN; ii++) {
array[ii] = val % 2;
val = val / 2;
}
}
static inline int pack(int array[LEN])
{
int ans, ii;
ans = 0;
for (ii = LEN-1; ii >= 0; ii--) {
ans = 2 * ans + array[ii];
}
return ans;
}
int __attribute__((noinline))
foo()
{
int temp, ans;
int array[LEN];
unpack(array);
temp = array[0];
array[0] = array[2];
array[2] = temp;
ans = pack(array);
return ans;
}
int main(void)
{
int val;
val = foo();
if (val != 4)
abort ();
return 0;
}

View File

@ -361,8 +361,11 @@ create_mem_ref_raw (tree type, tree alias_ptr_type, struct mem_address *addr,
index2 = addr->base;
}
/* If possible use a plain MEM_REF instead of a TARGET_MEM_REF. */
if (alias_ptr_type
/* If possible use a plain MEM_REF instead of a TARGET_MEM_REF.
??? As IVOPTs does not follow restrictions to where the base
pointer may point to create a MEM_REF only if we know that
base is valid. */
if (TREE_CODE (base) == ADDR_EXPR
&& (!index2 || integer_zerop (index2))
&& (!addr->index || integer_zerop (addr->index)))
return fold_build2 (MEM_REF, type, base, addr->offset);

View File

@ -745,11 +745,12 @@ indirect_ref_may_alias_decl_p (tree ref1 ATTRIBUTE_UNUSED, tree base1,
the pointer access is beyond the extent of the variable access.
(the pointer base cannot validly point to an offset less than zero
of the variable).
They also cannot alias if the pointer may not point to the decl. */
if ((TREE_CODE (base1) != TARGET_MEM_REF
|| (!TMR_INDEX (base1) && !TMR_INDEX2 (base1)))
??? IVOPTs creates bases that do not honor this restriction,
so do not apply this optimization for TARGET_MEM_REFs. */
if (TREE_CODE (base1) != TARGET_MEM_REF
&& !ranges_overlap_p (MAX (0, offset1p), -1, offset2p, max_size2))
return false;
/* They also cannot alias if the pointer may not point to the decl. */
if (!ptr_deref_may_alias_decl_p (ptr1, base2))
return false;
@ -799,7 +800,7 @@ indirect_ref_may_alias_decl_p (tree ref1 ATTRIBUTE_UNUSED, tree base1,
if (!ref2)
return true;
/* If the decl is accressed via a MEM_REF, reconstruct the base
/* If the decl is accessed via a MEM_REF, reconstruct the base
we can use for TBAA and an appropriately adjusted offset. */
dbase2 = ref2;
while (handled_component_p (dbase2))