[PATCH] Improve alias information for arrays

Richard Guenther rguenther@suse.de
Sat Jan 7 17:43:00 GMT 2006


This is the merge of array aliasing which I maintained as patch
for IAB for the last months.  It passes bootstrap and regtesting
on i686-pc-linux-gnu and x86_64-unknown-linux-gnu for all languages
including Ada, apart from causing ACATS ca11c01 to fail.  Maybe
some Ada folks can give me a hint what is going wrong here - I have
been digging for one and a half day now with no success.

So, I'm tempted to ask - ok for mainline?  (The patch is now much
smaller thanks to the already merged bits)

Thanks,
Richard.

2006-01-06  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/22548
	PR tree-optimization/22555
	PR tree-optimization/22501
	* Makefile.in (tree-ssa-structalias.o): Depend on $(PARAMS_H).
	* params.def (salias-max-array-elements): New parameter.
	* params.h (SALIAS_MAX_ARRAY_ELEMENTS): Define.
	* doc/invoke.texi (salias-max-array-elements): Document.
	* tree-flow-inline.h (var_can_have_subvars): We also handle
	arrays now.
	* tree-ssa-alias.c (find_used_portions): Handle ARRAY_REF like
	COMPONENT_REF.
	* tree-ssa-structalias.c (params.h): Include.
	(push_fields_onto_fieldstack): Handle ARRAY_TYPE.
	(find_func_aliases): Remove unused need_anyoffset.  Handle
	multiple constraints from ARRAY_REF.
	(get_constraint_for): For ADDR_EXPR operating on something
	containing an ARRAY_REF, add all subvars to the solution.
	(handle_ptr_arith): Handle ARRAY_TYPE like RECORD_TYPE types,
	for accesses beyond the end of an array simply give up.
	* tree-ssa-operands.c (parse_ssa_operands): Handle ARRAY_REF
	for creating MUST_DEFs.
	(get_expr_operands): Treat ARRAY_REF like COMPONENT_REF wrt subvars.

	* gcc.dg/tree-ssa/alias-[456789].c: New testcases.
	* gcc.dg/tree-ssa/alias-1[012].c: Likewise.

Index: doc/invoke.texi
===================================================================
*** doc/invoke.texi	(revision 109424)
--- doc/invoke.texi	(working copy)
*************** The maximum number of fields in a variab
*** 5744,5749 ****
--- 5744,5753 ----
  structure accesses for which structure aliasing will consider trying 
  to track each field.  The default is 5
  
+ @item salias-max-array-elements
+ The maximum number of elements an array can have and its elements
+ still be tracked individually by structure aliasing. The default is 4
+ 
  @item sra-max-structure-size
  The maximum structure size, in bytes, at which the scalar replacement
  of aggregates (SRA) optimization will perform block copies.  The
Index: params.h
===================================================================
*** params.h	(revision 109424)
--- params.h	(working copy)
*************** typedef enum compiler_param
*** 91,96 ****
--- 91,98 ----
  /* Macros for the various parameters.  */
  #define SALIAS_MAX_IMPLICIT_FIELDS \
    PARAM_VALUE (PARAM_SALIAS_MAX_IMPLICIT_FIELDS)
+ #define SALIAS_MAX_ARRAY_ELEMENTS \
+   PARAM_VALUE (PARAM_SALIAS_MAX_ARRAY_ELEMENTS)
  #define SRA_MAX_STRUCTURE_SIZE \
    PARAM_VALUE (PARAM_SRA_MAX_STRUCTURE_SIZE)
  #define SRA_MAX_STRUCTURE_COUNT \
Index: tree-ssa-alias.c
===================================================================
*** tree-ssa-alias.c	(revision 109424)
--- tree-ssa-alias.c	(working copy)
*************** find_used_portions (tree *tp, int *walk_
*** 2697,2702 ****
--- 2697,2703 ----
      case REALPART_EXPR:
      case IMAGPART_EXPR:
      case COMPONENT_REF:
+     case ARRAY_REF:
        {
  	HOST_WIDE_INT bitsize;
  	HOST_WIDE_INT bitmaxsize;
Index: tree-flow-inline.h
===================================================================
*** tree-flow-inline.h	(revision 109424)
--- tree-flow-inline.h	(working copy)
*************** get_subvar_at (tree var, unsigned HOST_W
*** 1489,1496 ****
  }
  
  /* Return true if V is a tree that we can have subvars for.
!    Normally, this is any aggregate type, however, due to implementation
!    limitations ATM, we exclude array types as well.  Also complex
     types which are not gimple registers can have subvars.  */
  
  static inline bool
--- 1489,1495 ----
  }
  
  /* Return true if V is a tree that we can have subvars for.
!    Normally, this is any aggregate type.  Also complex
     types which are not gimple registers can have subvars.  */
  
  static inline bool
*************** var_can_have_subvars (tree v)
*** 1500,1508 ****
    if (!DECL_P (v) || MTAG_P (v))
      return false;
  
!   /* Aggregates besides arrays can have subvars.  */
!   if (AGGREGATE_TYPE_P (TREE_TYPE (v))
!       && TREE_CODE (TREE_TYPE (v)) != ARRAY_TYPE)
      return true;
  
    /* Complex types variables which are not also a gimple register can
--- 1499,1506 ----
    if (!DECL_P (v) || MTAG_P (v))
      return false;
  
!   /* Aggregates can have subvars.  */
!   if (AGGREGATE_TYPE_P (TREE_TYPE (v)))
      return true;
  
    /* Complex types variables which are not also a gimple register can
Index: Makefile.in
===================================================================
*** Makefile.in	(revision 109424)
--- Makefile.in	(working copy)
*************** stor-layout.o : stor-layout.c $(CONFIG_H
*** 1791,1797 ****
  tree-ssa-structalias.o: tree-ssa-structalias.c tree-ssa-structalias.h \
     $(SYSTEM_H) $(CONFIG_H) $(GGC_H) $(TREE_H) $(TREE_FLOW_H) \
     $(TM_H) coretypes.h cgraph.h tree-pass.h $(TIMEVAR_H) \
!    gt-tree-ssa-structalias.h
  tree-ssa.o : tree-ssa.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
     $(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) output.h $(DIAGNOSTIC_H) \
     toplev.h function.h $(TIMEVAR_H) $(TM_H) coretypes.h \
--- 1791,1797 ----
  tree-ssa-structalias.o: tree-ssa-structalias.c tree-ssa-structalias.h \
     $(SYSTEM_H) $(CONFIG_H) $(GGC_H) $(TREE_H) $(TREE_FLOW_H) \
     $(TM_H) coretypes.h cgraph.h tree-pass.h $(TIMEVAR_H) \
!    gt-tree-ssa-structalias.h $(PARAMS_H)
  tree-ssa.o : tree-ssa.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
     $(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) output.h $(DIAGNOSTIC_H) \
     toplev.h function.h $(TIMEVAR_H) $(TM_H) coretypes.h \
Index: params.def
===================================================================
*** params.def	(revision 109424)
--- params.def	(working copy)
*************** DEFPARAM (PARAM_SALIAS_MAX_IMPLICIT_FIEL
*** 47,53 ****
  	  "salias-max-implicit-fields",
  	  "The maximum number of fields in a structure variable without direct structure accesses that GCC will attempt to track separately",
  	  5, 0, 0)
!    
  /* The maximum structure size at which the scalar replacement of
     aggregates (SRA) pass will perform block copies.  The default
     value, 0, implies that GCC will select the most appropriate size
--- 47,60 ----
  	  "salias-max-implicit-fields",
  	  "The maximum number of fields in a structure variable without direct structure accesses that GCC will attempt to track separately",
  	  5, 0, 0)
! 
! /* The maximum number of array elements structure aliasing will decompose
!    an array for.  The default is 4.  */
! DEFPARAM (PARAM_SALIAS_MAX_ARRAY_ELEMENTS,
! 	  "salias-max-array-elements",
! 	  "The maximum number of elements in an array for wich we track its elements separately",
! 	  4, 0, 0)
! 
  /* The maximum structure size at which the scalar replacement of
     aggregates (SRA) pass will perform block copies.  The default
     value, 0, implies that GCC will select the most appropriate size
Index: tree-ssa-operands.c
===================================================================
*** tree-ssa-operands.c	(revision 109424)
--- tree-ssa-operands.c	(working copy)
*************** parse_ssa_operands (tree stmt)
*** 732,739 ****
  	if (TREE_CODE (lhs) == VIEW_CONVERT_EXPR)
  	  lhs = TREE_OPERAND (lhs, 0);
  
! 	if (TREE_CODE (lhs) != ARRAY_REF
! 	    && TREE_CODE (lhs) != ARRAY_RANGE_REF
  	    && TREE_CODE (lhs) != BIT_FIELD_REF)
  	  lhs_flags |= opf_kill_def;
  
--- 732,738 ----
  	if (TREE_CODE (lhs) == VIEW_CONVERT_EXPR)
  	  lhs = TREE_OPERAND (lhs, 0);
  
! 	if (TREE_CODE (lhs) != ARRAY_RANGE_REF
  	    && TREE_CODE (lhs) != BIT_FIELD_REF)
  	  lhs_flags |= opf_kill_def;
  
*************** get_expr_operands (tree stmt, tree *expr
*** 1103,1109 ****
        get_tmr_operands (stmt, expr, flags);
        return;
  
-     case ARRAY_REF:
      case ARRAY_RANGE_REF:
        /* Treat array references as references to the virtual variable
  	 representing the array.  The virtual variable for an ARRAY_REF
--- 1102,1107 ----
*************** get_expr_operands (tree stmt, tree *expr
*** 1122,1127 ****
--- 1120,1126 ----
        get_expr_operands (stmt, &TREE_OPERAND (expr, 3), opf_none);
        return;
  
+     case ARRAY_REF:
      case COMPONENT_REF:
      case REALPART_EXPR:
      case IMAGPART_EXPR:
*************** get_expr_operands (tree stmt, tree *expr
*** 1169,1174 ****
--- 1168,1179 ----
  	      s_ann->has_volatile_ops = true; 
  	    get_expr_operands (stmt, &TREE_OPERAND (expr, 2), opf_none);
  	  }
+ 	else if (code == ARRAY_REF)
+ 	  {
+             get_expr_operands (stmt, &TREE_OPERAND (expr, 1), opf_none);
+             get_expr_operands (stmt, &TREE_OPERAND (expr, 2), opf_none);
+             get_expr_operands (stmt, &TREE_OPERAND (expr, 3), opf_none);
+ 	  }
  	return;
        }
      case WITH_SIZE_EXPR:
*************** get_expr_operands (tree stmt, tree *expr
*** 1199,1206 ****
  	op = TREE_OPERAND (expr, 0);
  	if (TREE_CODE (op) == WITH_SIZE_EXPR)
  	  op = TREE_OPERAND (expr, 0);
! 	if (TREE_CODE (op) == ARRAY_REF
! 	    || TREE_CODE (op) == ARRAY_RANGE_REF
  	    || TREE_CODE (op) == REALPART_EXPR
  	    || TREE_CODE (op) == IMAGPART_EXPR)
  	  subflags = opf_is_def;
--- 1204,1210 ----
  	op = TREE_OPERAND (expr, 0);
  	if (TREE_CODE (op) == WITH_SIZE_EXPR)
  	  op = TREE_OPERAND (expr, 0);
! 	if (TREE_CODE (op) == ARRAY_RANGE_REF
  	    || TREE_CODE (op) == REALPART_EXPR
  	    || TREE_CODE (op) == IMAGPART_EXPR)
  	  subflags = opf_is_def;

Index: tree-ssa-structalias.c
===================================================================
*** tree-ssa-structalias.c	(revision 109448)
--- tree-ssa-structalias.c	(working copy)
*************** Foundation, Inc., 51 Franklin Street, Fi
*** 48,53 ****
--- 48,54 ----
  #include "timevar.h"
  #include "alloc-pool.h"
  #include "splay-tree.h"
+ #include "params.h"
  #include "tree-ssa-structalias.h"
  #include "cgraph.h"
  
*************** get_constraint_for (tree t, VEC (ce_s, h
*** 2513,2518 ****
--- 2514,2538 ----
  	      unsigned int i;
  
  	      get_constraint_for (TREE_OPERAND (t, 0), results, anyoffset);
+ 	      if ((handled_component_p (TREE_OPERAND (t, 0))
+ 		   && ref_contains_array_ref (TREE_OPERAND (t, 0)))
+ 		  || TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 0))) == ARRAY_TYPE)
+ 		{
+ 		  struct constraint_expr *origrhs;
+ 		  varinfo_t origvar;
+ 		  struct constraint_expr tmp;
+ 
+ 		  gcc_assert (VEC_length (ce_s, *results) == 1);
+ 		  origrhs = VEC_last (ce_s, *results);
+ 		  tmp = *origrhs;
+ 		  VEC_pop (ce_s, *results);
+ 		  origvar = get_varinfo (origrhs->var);
+ 		  for (; origvar; origvar = origvar->next)
+ 		    {
+ 		      tmp.var = origvar->id;
+ 		      VEC_safe_push (ce_s, heap, *results, &tmp);
+ 		    }
+ 		}
  	      for (i = 0; VEC_iterate (ce_s, *results, i, c); i++)
  		{
  		  if (c->type == DEREF)
*************** handle_ptr_arith (VEC (ce_s, heap) *lhsc
*** 3169,3175 ****
  
    get_constraint_for (op0, &temp, NULL);
    if (POINTER_TYPE_P (TREE_TYPE (op0))
-       && TREE_CODE (TREE_TYPE (TREE_TYPE (op0))) == RECORD_TYPE
        && TREE_CODE (op1) == INTEGER_CST)
      {
        rhsoffset = TREE_INT_CST_LOW (op1) * BITS_PER_UNIT;
--- 3189,3194 ----
*************** find_func_aliases (tree origt)
*** 3386,3392 ****
  		  case tcc_unary:
  		      {
  			unsigned int j;
- 			bool need_anyoffset = false;
  			tree strippedrhs = rhsop;
  			tree rhstype;
  
--- 3405,3410 ----
*************** find_func_aliases (tree origt)
*** 3395,3403 ****
  			STRIP_NOPS (strippedrhs);
  			rhstype = TREE_TYPE (strippedrhs);
  			
! 			get_constraint_for (rhsop, &rhsc, &need_anyoffset);
  			if (TREE_CODE (strippedrhs) == ADDR_EXPR
! 			    && AGGREGATE_TYPE_P (TREE_TYPE (rhstype)))
  			  {
  			    struct constraint_expr *origrhs;
  			    varinfo_t origvar;
--- 3413,3422 ----
  			STRIP_NOPS (strippedrhs);
  			rhstype = TREE_TYPE (strippedrhs);
  			
! 			get_constraint_for (rhsop, &rhsc, NULL);
  			if (TREE_CODE (strippedrhs) == ADDR_EXPR
! 			    && AGGREGATE_TYPE_P (TREE_TYPE (rhstype))
! 			    && VEC_length (ce_s, rhsc) == 1)
  			  {
  			    struct constraint_expr *origrhs;
  			    varinfo_t origvar;
*************** push_fields_onto_fieldstack (tree type, 
*** 3587,3592 ****
--- 3606,3666 ----
        return 2;
      }
  
+   if (TREE_CODE (type) == ARRAY_TYPE)
+     {
+       tree sz = TYPE_SIZE (type);
+       tree elsz = TYPE_SIZE (TREE_TYPE (type));
+       HOST_WIDE_INT nr;
+       int i;
+ 
+       if (! sz || ! host_integerp (sz, 1)
+ 	  || TREE_INT_CST_LOW (sz) == 0
+ 	  || ! elsz || ! host_integerp (elsz, 1)
+ 	  || TREE_INT_CST_LOW (elsz) == 0)
+ 	return 0;
+ 
+       nr = TREE_INT_CST_LOW (sz) / TREE_INT_CST_LOW (elsz);
+       if (nr > SALIAS_MAX_ARRAY_ELEMENTS)
+ 	return 0;
+ 
+       for (i = 0; i<nr; ++i)
+ 	{
+ 	  bool push = false;
+ 	  int pushed = 0;
+ 	
+ 	  if (has_union 
+ 	      && (TREE_CODE (TREE_TYPE (type)) == QUAL_UNION_TYPE
+ 		  || TREE_CODE (TREE_TYPE (type)) == UNION_TYPE))
+ 	    *has_union = true;
+ 	
+ 	  if (!AGGREGATE_TYPE_P (TREE_TYPE (type))) /* var_can_have_subvars */
+ 	    push = true;
+ 	  else if (!(pushed = push_fields_onto_fieldstack
+ 		     (TREE_TYPE (type), fieldstack,
+ 		      offset + i * TREE_INT_CST_LOW (elsz), has_union)))
+ 	    /* Empty structures may have actual size, like in C++. So
+ 	       see if we didn't push any subfields and the size is
+ 	       nonzero, push the field onto the stack */
+ 	    push = true;
+ 
+ 	  if (push)
+ 	    {
+ 	      fieldoff_s *pair;
+ 
+ 	      pair = VEC_safe_push (fieldoff_s, heap, *fieldstack, NULL);
+ 	      pair->type = TREE_TYPE (type);
+ 	      pair->size = elsz;
+ 	      pair->decl = NULL_TREE;
+ 	      pair->offset = offset + i * TREE_INT_CST_LOW (elsz);
+ 	      count++;
+ 	    }
+ 	  else
+ 	    count += pushed;
+ 	}
+ 
+       return count;
+     }
+ 
    for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
      if (TREE_CODE (field) == FIELD_DECL)
        {
Index: testsuite/gcc.dg/tree-ssa/alias-8.c
===================================================================
*** testsuite/gcc.dg/tree-ssa/alias-8.c	(revision 0)
--- testsuite/gcc.dg/tree-ssa/alias-8.c	(revision 0)
***************
*** 0 ****
--- 1,15 ----
+ /* { dg-do run } */
+ /* { dg-options "-O2" } */
+ 
+ void abort(void);
+ int main()
+ {
+   int a[2];
+   int i = 1;
+   a[0] = 1;
+   a[1] = 2;
+   if (*(a + i) != 2)
+     abort();
+   return 0;
+ }
+ 
Index: testsuite/gcc.dg/tree-ssa/alias-9.c
===================================================================
*** testsuite/gcc.dg/tree-ssa/alias-9.c	(revision 0)
--- testsuite/gcc.dg/tree-ssa/alias-9.c	(revision 0)
***************
*** 0 ****
--- 1,15 ----
+ /* { dg-do run } */
+ /* { dg-options "-O2" } */
+ 
+ void abort(void);
+ int main()
+ {
+   int a[32];
+   int i = 1;
+   a[0] = 1;
+   a[1] = 2;
+   if (*(a + i) != 2)
+     abort();
+   return 0;
+ }
+ 
Index: testsuite/gcc.dg/tree-ssa/alias-4.c
===================================================================
*** testsuite/gcc.dg/tree-ssa/alias-4.c	(revision 0)
--- testsuite/gcc.dg/tree-ssa/alias-4.c	(revision 0)
***************
*** 0 ****
--- 1,21 ----
+ /* { dg-do compile } */
+ /* { dg-options "-O2 -fdump-tree-optimized" } */
+ 
+ struct {
+ 	int i;
+ 	struct {
+ 		int x[2];
+ 	} b;
+ } a;
+ 
+ int foo(void)
+ {
+ 	a.i = 1;
+ 	a.b.x[0] = 0;
+ 	a.b.x[1] = 1;
+ 	return a.i + a.b.x[0];
+ }
+ 
+ /* { dg-final { scan-tree-dump "return 1;" "optimized" } } */
+ /* { dg-final { cleanup-tree-dump "optimized" } } */
+ 
Index: testsuite/gcc.dg/tree-ssa/alias-5.c
===================================================================
*** testsuite/gcc.dg/tree-ssa/alias-5.c	(revision 0)
--- testsuite/gcc.dg/tree-ssa/alias-5.c	(revision 0)
***************
*** 0 ****
--- 1,23 ----
+ /* { dg-do compile } */
+ /* { dg-options "-O2 -fdump-tree-optimized" } */
+ 
+ struct {
+ 	int i;
+ 	struct {
+ 		struct {
+ 			int i;
+ 		} x[2];
+ 	} b;
+ } a;
+ 
+ int foo(void)
+ {
+ 	a.i = 1;
+ 	a.b.x[0].i = 0;
+ 	a.b.x[1].i = 1;
+ 	return a.i + a.b.x[0].i;
+ }
+ 
+ /* { dg-final { scan-tree-dump "return 1;" "optimized" } } */
+ /* { dg-final { cleanup-tree-dump "optimized" } } */
+ 
Index: testsuite/gcc.dg/tree-ssa/alias-10.c
===================================================================
*** testsuite/gcc.dg/tree-ssa/alias-10.c	(revision 0)
--- testsuite/gcc.dg/tree-ssa/alias-10.c	(revision 0)
***************
*** 0 ****
--- 1,20 ----
+ /* { dg-do compile } */
+ /* { dg-options "-O2 -fdump-tree-optimized" } */
+ 
+ struct {
+ 	int i;
+ 	int x[2];
+ 	int j;
+ } a;
+ 
+ int foo(int i)
+ {
+ 	a.i = 1;
+ 	a.j = 2;
+ 	a.x[i] = 0;
+ 	return a.i + a.j;
+ }
+ 
+ /* { dg-final { scan-tree-dump "return 3;" "optimized" } } */
+ /* { dg-final { cleanup-tree-dump "optimized" } } */
+ 
Index: testsuite/gcc.dg/tree-ssa/alias-6.c
===================================================================
*** testsuite/gcc.dg/tree-ssa/alias-6.c	(revision 0)
--- testsuite/gcc.dg/tree-ssa/alias-6.c	(revision 0)
***************
*** 0 ****
--- 1,19 ----
+ /* { dg-do compile } */
+ /* { dg-options "-O2 -fdump-tree-optimized" } */
+ 
+ struct param { int *a; };
+ void foo(struct param *p);
+ int bar(void)
+ {
+   int a[2];
+   struct param p;
+   a[0] = 1;
+   a[1] = 1;
+   p.a = &a[0];
+   foo(&p);
+   return a[0] + *p.a;
+ }
+ 
+ /* { dg-final { scan-tree-dump "return a.0. \\\+ \\*p\\.a;" "optimized" } } */
+ /* { dg-final { cleanup-tree-dump "optimized" } } */
+ 
Index: testsuite/gcc.dg/tree-ssa/alias-11.c
===================================================================
*** testsuite/gcc.dg/tree-ssa/alias-11.c	(revision 0)
--- testsuite/gcc.dg/tree-ssa/alias-11.c	(revision 0)
***************
*** 0 ****
--- 1,19 ----
+ /* { dg-do compile } */
+ /* { dg-options "-O2 -fdump-tree-optimized" } */
+ 
+ struct param { int *a; };
+ void foo(struct param *p);
+ int bar(void)
+ {
+   int a[32];
+   struct param p;
+   a[0] = 1;
+   a[1] = 1;
+   p.a = &a[0];
+   foo(&p);
+   return a[0] + *p.a;
+ }
+ 
+ /* { dg-final { scan-tree-dump "return a.0. \\\+ \\*p\\.a;" "optimized" } } */
+ /* { dg-final { cleanup-tree-dump "optimized" } } */
+ 
Index: testsuite/gcc.dg/tree-ssa/alias-7.c
===================================================================
*** testsuite/gcc.dg/tree-ssa/alias-7.c	(revision 0)
--- testsuite/gcc.dg/tree-ssa/alias-7.c	(revision 0)
***************
*** 0 ****
--- 1,17 ----
+ /* { dg-do run } */
+ /* { dg-options "-O2" } */
+ 
+ void abort(void);
+ int main()
+ {
+   int a[2];
+   int *p = a;
+   int i;
+   a[0] = 1;
+   a[1] = 2;
+   for (i=0; i<2; ++i)
+     if (p[i] != i+1)
+       abort();
+   return 0;
+ }
+ 
Index: testsuite/gcc.dg/tree-ssa/alias-12.c
===================================================================
*** testsuite/gcc.dg/tree-ssa/alias-12.c	(revision 0)
--- testsuite/gcc.dg/tree-ssa/alias-12.c	(revision 0)
***************
*** 0 ****
--- 1,18 ----
+ /* { dg-do compile } */
+ /* { dg-options "-O2 -fdump-tree-alias1-vops" } */
+ 
+ struct {
+ 	int i;
+ 	int x[128];
+ 	int j;
+ } a;
+ 
+ int foo(int i)
+ {
+ 	a.x[i] = 0;
+ 	return a.x[i];
+ }
+ 
+ /* { dg-final { scan-tree-dump "V_MAY_DEF" "alias1" } } */
+ /* { dg-final { cleanup-tree-dump "alias1" } } */
+ 




More information about the Gcc-patches mailing list