Commit ac8e1875 by Richard Guenther Committed by Richard Biener

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
parent 7e32e652
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> 2011-05-26 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
PR target/49099 PR target/49099
......
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> 2011-05-26 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
PR gcov-profile/48845 PR gcov-profile/48845
......
/* { 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;
}
...@@ -361,8 +361,11 @@ create_mem_ref_raw (tree type, tree alias_ptr_type, struct mem_address *addr, ...@@ -361,8 +361,11 @@ create_mem_ref_raw (tree type, tree alias_ptr_type, struct mem_address *addr,
index2 = addr->base; index2 = addr->base;
} }
/* If possible use a plain MEM_REF instead of a TARGET_MEM_REF. */ /* If possible use a plain MEM_REF instead of a TARGET_MEM_REF.
if (alias_ptr_type ??? 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)) && (!index2 || integer_zerop (index2))
&& (!addr->index || integer_zerop (addr->index))) && (!addr->index || integer_zerop (addr->index)))
return fold_build2 (MEM_REF, type, base, addr->offset); return fold_build2 (MEM_REF, type, base, addr->offset);
......
...@@ -745,11 +745,12 @@ indirect_ref_may_alias_decl_p (tree ref1 ATTRIBUTE_UNUSED, tree base1, ...@@ -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 access is beyond the extent of the variable access.
(the pointer base cannot validly point to an offset less than zero (the pointer base cannot validly point to an offset less than zero
of the variable). of the variable).
They also cannot alias if the pointer may not point to the decl. */ ??? IVOPTs creates bases that do not honor this restriction,
if ((TREE_CODE (base1) != TARGET_MEM_REF so do not apply this optimization for TARGET_MEM_REFs. */
|| (!TMR_INDEX (base1) && !TMR_INDEX2 (base1))) if (TREE_CODE (base1) != TARGET_MEM_REF
&& !ranges_overlap_p (MAX (0, offset1p), -1, offset2p, max_size2)) && !ranges_overlap_p (MAX (0, offset1p), -1, offset2p, max_size2))
return false; return false;
/* They also cannot alias if the pointer may not point to the decl. */
if (!ptr_deref_may_alias_decl_p (ptr1, base2)) if (!ptr_deref_may_alias_decl_p (ptr1, base2))
return false; return false;
...@@ -799,7 +800,7 @@ indirect_ref_may_alias_decl_p (tree ref1 ATTRIBUTE_UNUSED, tree base1, ...@@ -799,7 +800,7 @@ indirect_ref_may_alias_decl_p (tree ref1 ATTRIBUTE_UNUSED, tree base1,
if (!ref2) if (!ref2)
return true; 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. */ we can use for TBAA and an appropriately adjusted offset. */
dbase2 = ref2; dbase2 = ref2;
while (handled_component_p (dbase2)) while (handled_component_p (dbase2))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment