re PR middle-end/44852 (miscompilation (of e.g. newlib dtoa.c) after mem-ref2 merge)

2010-07-09  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/44852
	* tree-ssa-alias.c: Include toplev.h for exact_log2.
	(indirect_ref_may_alias_decl_p): Properly handle negative offsets
	in MEM_REF.
	(indirect_refs_may_alias_p): Likewise.
	* Makefile.in (tree-ssa-alias.o): Add $(TOPLEV_H).

	* gcc.c-torture/execute/pr44852.c: New testcase.

From-SVN: r161994
This commit is contained in:
Richard Guenther 2010-07-09 11:24:09 +00:00 committed by Richard Biener
parent 8bcc87780a
commit dbfcc0597c
5 changed files with 77 additions and 6 deletions

View File

@ -1,3 +1,12 @@
2010-07-09 Richard Guenther <rguenther@suse.de>
PR tree-optimization/44852
* tree-ssa-alias.c: Include toplev.h for exact_log2.
(indirect_ref_may_alias_decl_p): Properly handle negative offsets
in MEM_REF.
(indirect_refs_may_alias_p): Likewise.
* Makefile.in (tree-ssa-alias.o): Add $(TOPLEV_H).
2010-07-09 Richard Guenther <rguenther@suse.de>
PR tree-optimization/44882

View File

@ -2592,7 +2592,7 @@ tree-ssa-alias.o : tree-ssa-alias.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
$(TREE_DUMP_H) $(TREE_PASS_H) $(PARAMS_H) $(BASIC_BLOCK_H) $(DIAGNOSTIC_H) \
$(GIMPLE_H) $(VEC_H) \
$(IPA_TYPE_ESCAPE_H) vecprim.h pointer-set.h alloc-pool.h \
tree-pretty-print.h
tree-pretty-print.h $(TOPLEV_H)
tree-ssa-reassoc.o : tree-ssa-reassoc.c $(TREE_FLOW_H) $(CONFIG_H) \
$(SYSTEM_H) $(TREE_H) $(DIAGNOSTIC_H) $(TIMEVAR_H) \
$(TM_H) coretypes.h $(TREE_DUMP_H) $(TREE_PASS_H) $(FLAGS_H) \

View File

@ -1,3 +1,8 @@
2010-07-09 Richard Guenther <rguenther@suse.de>
PR tree-optimization/44852
* gcc.c-torture/execute/pr44852.c: New testcase.
2010-07-09 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
* gcc.target/x86_64/abi/asm-support.S (snapshot): Replace

View File

@ -0,0 +1,22 @@
__attribute__ ((__noinline__))
char *sf(char *s, char *s0)
{
asm ("");
while (*--s == '9')
if (s == s0)
{
*s = '0';
break;
}
++*s++;
return s;
}
int main()
{
char s[] = "999999";
char *x = sf (s+2, s);
if (x != s+1 || __builtin_strcmp (s, "199999") != 0)
__builtin_abort ();
return 0;
}

View File

@ -30,6 +30,7 @@ along with GCC; see the file COPYING3. If not see
#include "ggc.h"
#include "langhooks.h"
#include "flags.h"
#include "toplev.h"
#include "function.h"
#include "tree-pretty-print.h"
#include "tree-dump.h"
@ -688,17 +689,29 @@ indirect_ref_may_alias_decl_p (tree ref1 ATTRIBUTE_UNUSED, tree base1,
{
tree ptr1 = TREE_OPERAND (base1, 0);
tree ptrtype1;
HOST_WIDE_INT offset1p = offset1;
HOST_WIDE_INT offset1p = offset1, offset2p = offset2;
/* The offset embedded in MEM_REFs can be negative. Bias them
so that the resulting offset adjustment is positive. */
if (TREE_CODE (base1) == MEM_REF)
offset1p = offset1 + mem_ref_offset (base1).low * BITS_PER_UNIT;
{
double_int moff = mem_ref_offset (base1);
moff = double_int_lshift (moff,
BITS_PER_UNIT == 8
? 3 : exact_log2 (BITS_PER_UNIT),
HOST_BITS_PER_DOUBLE_INT, true);
if (double_int_negative_p (moff))
offset2p += double_int_neg (moff).low;
else
offset1p += moff.low;
}
/* If only one reference is based on a variable, they cannot alias if
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 (!ranges_overlap_p (MAX (0, offset1p), -1, offset2, max_size2))
if (!ranges_overlap_p (MAX (0, offset1p), -1, offset2p, max_size2))
return false;
if (!ptr_deref_may_alias_decl_p (ptr1, base2))
return false;
@ -804,10 +817,32 @@ indirect_refs_may_alias_p (tree ref1 ATTRIBUTE_UNUSED, tree base1,
if ((!cfun || gimple_in_ssa_p (cfun))
&& operand_equal_p (ptr1, ptr2, 0))
{
/* The offset embedded in MEM_REFs can be negative. Bias them
so that the resulting offset adjustment is positive. */
if (TREE_CODE (base1) == MEM_REF)
offset1 += mem_ref_offset (base1).low * BITS_PER_UNIT;
{
double_int moff = mem_ref_offset (base1);
moff = double_int_lshift (moff,
BITS_PER_UNIT == 8
? 3 : exact_log2 (BITS_PER_UNIT),
HOST_BITS_PER_DOUBLE_INT, true);
if (double_int_negative_p (moff))
offset2 += double_int_neg (moff).low;
else
offset1 += moff.low;
}
if (TREE_CODE (base2) == MEM_REF)
offset2 += mem_ref_offset (base2).low * BITS_PER_UNIT;
{
double_int moff = mem_ref_offset (base2);
moff = double_int_lshift (moff,
BITS_PER_UNIT == 8
? 3 : exact_log2 (BITS_PER_UNIT),
HOST_BITS_PER_DOUBLE_INT, true);
if (double_int_negative_p (moff))
offset1 += double_int_neg (moff).low;
else
offset2 += moff.low;
}
return ranges_overlap_p (offset1, max_size1, offset2, max_size2);
}
if (!ptr_derefs_may_alias_p (ptr1, ptr2))