aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2010-07-09 11:24:09 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2010-07-09 11:24:09 +0000
commitdbfcc0597ce9ec0cd4b05b17f132b8680394eb83 (patch)
tree1fcafc2809dd670b86812169efbe8489bbd17817 /gcc
parent8bcc87780adc7e6501de6ba406484af1b7b29340 (diff)
downloadgcc-dbfcc0597ce9ec0cd4b05b17f132b8680394eb83.zip
gcc-dbfcc0597ce9ec0cd4b05b17f132b8680394eb83.tar.gz
gcc-dbfcc0597ce9ec0cd4b05b17f132b8680394eb83.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/Makefile.in2
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr44852.c22
-rw-r--r--gcc/tree-ssa-alias.c45
5 files changed, 77 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 4666f4c..9784a99 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,14 @@
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
* tree-vect-stmts.c (vectorizable_store): Do not assert alias
sets do conflict.
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 5e99006..a807e8e 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -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) \
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index fc80a93..332664e 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr44852.c b/gcc/testsuite/gcc.c-torture/execute/pr44852.c
new file mode 100644
index 0000000..440653e
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr44852.c
@@ -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;
+}
diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c
index 2460804..d73ff59 100644
--- a/gcc/tree-ssa-alias.c
+++ b/gcc/tree-ssa-alias.c
@@ -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))