public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] Fix PR44852
@ 2010-07-09 11:22 Richard Guenther
  0 siblings, 0 replies; only message in thread
From: Richard Guenther @ 2010-07-09 11:22 UTC (permalink / raw)
  To: gcc-patches


This fixes PR44852 - ranges_overlap_p does not handle negative offsets
properly which can appear in MEM_REFs now.  The following patch fixes
that by shifting the offsets to positive values.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied.

Richard.

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.

Index: gcc/tree-ssa-alias.c
===================================================================
*** gcc/tree-ssa-alias.c	(revision 161989)
--- gcc/tree-ssa-alias.c	(working copy)
*************** along with GCC; see the file COPYING3.
*** 30,35 ****
--- 30,36 ----
  #include "ggc.h"
  #include "langhooks.h"
  #include "flags.h"
+ #include "toplev.h"
  #include "function.h"
  #include "tree-pretty-print.h"
  #include "tree-dump.h"
*************** indirect_ref_may_alias_decl_p (tree ref1
*** 688,704 ****
  {
    tree ptr1 = TREE_OPERAND (base1, 0);
    tree ptrtype1;
!   HOST_WIDE_INT offset1p = offset1;
  
    if (TREE_CODE (base1) == MEM_REF)
!     offset1p = offset1 + mem_ref_offset (base1).low * BITS_PER_UNIT;
  
    /* 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))
      return false;
    if (!ptr_deref_may_alias_decl_p (ptr1, base2))
      return false;
--- 668,696 ----
  {
    tree ptr1 = TREE_OPERAND (base1, 0);
    tree ptrtype1;
!   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)
!     {
!       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, offset2p, max_size2))
      return false;
    if (!ptr_deref_may_alias_decl_p (ptr1, base2))
      return false;
*************** indirect_refs_may_alias_p (tree ref1 ATT
*** 804,813 ****
    if ((!cfun || gimple_in_ssa_p (cfun))
        && operand_equal_p (ptr1, ptr2, 0))
      {
        if (TREE_CODE (base1) == MEM_REF)
! 	offset1 += mem_ref_offset (base1).low * BITS_PER_UNIT;
        if (TREE_CODE (base2) == MEM_REF)
! 	offset2 += mem_ref_offset (base2).low * BITS_PER_UNIT;
        return ranges_overlap_p (offset1, max_size1, offset2, max_size2);
      }
    if (!ptr_derefs_may_alias_p (ptr1, ptr2))
--- 796,827 ----
    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)
! 	{
! 	  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)
! 	{
! 	  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))
Index: gcc/Makefile.in
===================================================================
*** gcc/Makefile.in	(revision 161989)
--- gcc/Makefile.in	(working copy)
*************** tree-ssa-alias.o : tree-ssa-alias.c $(TR
*** 2592,2598 ****
     $(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-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) \
--- 2592,2598 ----
     $(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 $(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) \
Index: gcc/testsuite/gcc.c-torture/execute/pr44852.c
===================================================================
*** gcc/testsuite/gcc.c-torture/execute/pr44852.c	(revision 0)
--- gcc/testsuite/gcc.c-torture/execute/pr44852.c	(revision 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;
+ }

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2010-07-09 11:22 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-07-09 11:22 [PATCH] Fix PR44852 Richard Guenther

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).