This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix PR50838


This fixes PR50838.

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

Richard.

2011-10-24  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/50838
	* tree-data-ref.c (dr_analyze_indices): Properly canonicalize
	a MEM_REF base if we change it.

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

Index: gcc/tree-data-ref.c
===================================================================
*** gcc/tree-data-ref.c	(revision 180374)
--- gcc/tree-data-ref.c	(working copy)
*************** static void
*** 855,861 ****
  dr_analyze_indices (struct data_reference *dr, loop_p nest, loop_p loop)
  {
    VEC (tree, heap) *access_fns = NULL;
!   tree ref, aref, op;
    tree base, off, access_fn;
    basic_block before_loop;
  
--- 855,861 ----
  dr_analyze_indices (struct data_reference *dr, loop_p nest, loop_p loop)
  {
    VEC (tree, heap) *access_fns = NULL;
!   tree ref, *aref, op;
    tree base, off, access_fn;
    basic_block before_loop;
  
*************** dr_analyze_indices (struct data_referenc
*** 886,935 ****
      }
  
    /* Analyze access functions of dimensions we know to be independent.  */
!   aref = ref;
!   while (handled_component_p (aref))
      {
!       if (TREE_CODE (aref) == ARRAY_REF)
  	{
! 	  op = TREE_OPERAND (aref, 1);
  	  access_fn = analyze_scalar_evolution (loop, op);
  	  access_fn = instantiate_scev (before_loop, loop, access_fn);
  	  VEC_safe_push (tree, heap, access_fns, access_fn);
  	  /* For ARRAY_REFs the base is the reference with the index replaced
  	     by zero if we can not strip it as the outermost component.  */
! 	  if (aref == ref)
! 	    ref = TREE_OPERAND (ref, 0);
  	  else
! 	    TREE_OPERAND (aref, 1) = build_int_cst (TREE_TYPE (op), 0);
  	}
  
!       aref = TREE_OPERAND (aref, 0);
      }
  
    /* If the address operand of a MEM_REF base has an evolution in the
       analyzed nest, add it as an additional independent access-function.  */
!   if (TREE_CODE (aref) == MEM_REF)
      {
!       op = TREE_OPERAND (aref, 0);
        access_fn = analyze_scalar_evolution (loop, op);
        access_fn = instantiate_scev (before_loop, loop, access_fn);
        if (TREE_CODE (access_fn) == POLYNOMIAL_CHREC)
  	{
  	  base = initial_condition (access_fn);
  	  split_constant_offset (base, &base, &off);
  	  /* Fold the MEM_REF offset into the evolutions initial
  	     value to make more bases comparable.  */
! 	  if (!integer_zerop (TREE_OPERAND (aref, 1)))
  	    {
  	      off = size_binop (PLUS_EXPR, off,
  				fold_convert (ssizetype,
! 					      TREE_OPERAND (aref, 1)));
! 	      TREE_OPERAND (aref, 1)
! 		= build_int_cst (TREE_TYPE (TREE_OPERAND (aref, 1)), 0);
  	    }
  	  access_fn = chrec_replace_initial_condition
! 	      (access_fn, fold_convert (TREE_TYPE (base), off));
! 	  TREE_OPERAND (aref, 0) = base;
  	  VEC_safe_push (tree, heap, access_fns, access_fn);
  	}
      }
--- 886,943 ----
      }
  
    /* Analyze access functions of dimensions we know to be independent.  */
!   aref = &ref;
!   while (handled_component_p (*aref))
      {
!       if (TREE_CODE (*aref) == ARRAY_REF)
  	{
! 	  op = TREE_OPERAND (*aref, 1);
  	  access_fn = analyze_scalar_evolution (loop, op);
  	  access_fn = instantiate_scev (before_loop, loop, access_fn);
  	  VEC_safe_push (tree, heap, access_fns, access_fn);
  	  /* For ARRAY_REFs the base is the reference with the index replaced
  	     by zero if we can not strip it as the outermost component.  */
! 	  if (*aref == ref)
! 	    {
! 	      *aref = TREE_OPERAND (*aref, 0);
! 	      continue;
! 	    }
  	  else
! 	    TREE_OPERAND (*aref, 1) = build_int_cst (TREE_TYPE (op), 0);
  	}
  
!       aref = &TREE_OPERAND (*aref, 0);
      }
  
    /* If the address operand of a MEM_REF base has an evolution in the
       analyzed nest, add it as an additional independent access-function.  */
!   if (TREE_CODE (*aref) == MEM_REF)
      {
!       op = TREE_OPERAND (*aref, 0);
        access_fn = analyze_scalar_evolution (loop, op);
        access_fn = instantiate_scev (before_loop, loop, access_fn);
        if (TREE_CODE (access_fn) == POLYNOMIAL_CHREC)
  	{
+ 	  tree orig_type;
  	  base = initial_condition (access_fn);
+ 	  orig_type = TREE_TYPE (base);
+ 	  STRIP_USELESS_TYPE_CONVERSION (base);
  	  split_constant_offset (base, &base, &off);
  	  /* Fold the MEM_REF offset into the evolutions initial
  	     value to make more bases comparable.  */
! 	  if (!integer_zerop (TREE_OPERAND (*aref, 1)))
  	    {
  	      off = size_binop (PLUS_EXPR, off,
  				fold_convert (ssizetype,
! 					      TREE_OPERAND (*aref, 1)));
! 	      TREE_OPERAND (*aref, 1)
! 		= build_int_cst (TREE_TYPE (TREE_OPERAND (*aref, 1)), 0);
  	    }
  	  access_fn = chrec_replace_initial_condition
! 	      (access_fn, fold_convert (orig_type, off));
! 	  *aref = fold_build2_loc (EXPR_LOCATION (*aref),
! 				   MEM_REF, TREE_TYPE (*aref),
! 				   base, TREE_OPERAND (*aref, 1));
  	  VEC_safe_push (tree, heap, access_fns, access_fn);
  	}
      }
Index: gcc/testsuite/gcc.dg/torture/pr50838.c
===================================================================
*** gcc/testsuite/gcc.dg/torture/pr50838.c	(revision 0)
--- gcc/testsuite/gcc.dg/torture/pr50838.c	(revision 0)
***************
*** 0 ****
--- 1,27 ----
+ /* { dg-do compile } */
+ 
+ typedef void * gcv_object_t;
+ typedef gcv_object_t object;
+ typedef const void * Pseudofun;
+ extern struct pseudocode_tab_ {
+     Pseudofun pseudo_eql;
+     Pseudofun pseudo_iconv_wcslen;
+     Pseudofun pseudo_iconv_wcstombs;
+     Pseudofun pseudo_iconv_range;
+ }
+ pseudocode_tab;
+ extern struct symbol_tab_ {
+     object pointer[1024];
+ } pseudofun_tab;
+ int
+ init_memory (void)
+ {
+   object* ptr2 = &pseudofun_tab.pointer[0];
+   const Pseudofun* ptr1 = (const Pseudofun*)&pseudocode_tab;
+   unsigned int count = (sizeof(pseudocode_tab)/sizeof(Pseudofun));
+   while (count--)
+     {
+       *ptr2++ = (gcv_object_t)(((unsigned char *)((*ptr1))));
+       ptr1++;
+     }
+ }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]