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][C] Gimplify &ARRAY as (T *)&ARRAY with fixed ADDR_EXPR type


This fixes the long standing bug of the C frontend generating invalid
GENERIC trees for array-to-pointer decay.  The frontend emits
ADDR_EXPRs of pointer-to-element type with the object having the
address taken as an array.  The fixup is done during c_gimplify_expr
which adjusts the type of the ADDR_EXPR and pre-pends a conversion
to the desired type.

The patch also gets rid of the hack in the gimple type verifier and
adjusts a few vectorizer testcases where PRE now can properly CSE
reads from constant initializers.

Bootstrapped on x86_64-unknown-linux-gnu, testing in progress together
with the address-to-array folding patch sent earlier.

Ok for trunk?

(You may remember two or three tries to fix this in the frontend
rather than in the gimplifier - but this runs into tons of issues
with existing warning code, thus now this more pragmatic approach)

Thanks,
Richard.

2009-04-06  Richard Guenther  <rguenther@suse.de>

	* c-gimplify.c (c_gimplify_expr): Fix the invalid GENERIC
	&ARRAY addresses by adjusting their types and prepending
	a conversion.
	* tree-cfg.c (verify_gimple_assign_single): Verify that
	addresses are correct.

	* gcc.dg/vect/vect-54.c: Make constant input data file-scope
	to prevent constant propagation.
	* gcc.dg/vect/vect-56.c: Likewise.
	* gcc.dg/vect/vect-58.c: Likewise.
	* gcc.dg/vect/vect-60.c: Likewise.
	* gcc.dg/vect/no-vfa-vect-57.c: Likewise.
	* gcc.dg/vect/no-vfa-vect-61.c: Likewise.

Index: gcc/c-gimplify.c
===================================================================
*** gcc/c-gimplify.c.orig	2009-04-06 16:18:47.000000000 +0200
--- gcc/c-gimplify.c	2009-04-06 16:19:16.000000000 +0200
*************** c_gimplify_expr (tree *expr_p, gimple_se
*** 196,200 ****
--- 196,214 ----
        && !warn_init_self)
      TREE_NO_WARNING (DECL_EXPR_DECL (*expr_p)) = 1;
  
+   /* The C frontend is the only one producing &ARRAY with pointer-to-element
+      type.  This is invalid in gimple, so produce a properly typed
+      ADDR_EXPR instead and wrap a conversion around it.  */
+   if (code == ADDR_EXPR
+       && TREE_CODE (TREE_TYPE (TREE_OPERAND (*expr_p, 0))) == ARRAY_TYPE
+       && TREE_CODE (TREE_TYPE (TREE_TYPE (*expr_p))) != ARRAY_TYPE)
+     {
+       tree type = TREE_TYPE (*expr_p);
+       TREE_TYPE (*expr_p)
+ 	= build_pointer_type (TREE_TYPE (TREE_OPERAND (*expr_p, 0)));
+       *expr_p = build1 (NOP_EXPR, type, *expr_p);
+       return GS_OK;
+     }
+ 
    return GS_UNHANDLED;
  }
Index: gcc/tree-cfg.c
===================================================================
*** gcc/tree-cfg.c.orig	2009-04-06 16:18:47.000000000 +0200
--- gcc/tree-cfg.c	2009-04-06 16:19:16.000000000 +0200
*************** verify_gimple_assign_single (gimple stmt
*** 3697,3707 ****
  	    return true;
  	  }
  
! 	if (!one_pointer_to_useless_type_conversion_p (lhs_type, TREE_TYPE (op))
! 	    /* FIXME: a longstanding wart, &a == &a[0].  */
! 	    && (TREE_CODE (TREE_TYPE (op)) != ARRAY_TYPE
! 		|| !one_pointer_to_useless_type_conversion_p (lhs_type,
! 		      TREE_TYPE (TREE_TYPE (op)))))
  	  {
  	    error ("type mismatch in address expression");
  	    debug_generic_stmt (lhs_type);
--- 3697,3704 ----
  	    return true;
  	  }
  
! 	if (!one_pointer_to_useless_type_conversion_p (lhs_type,
! 						       TREE_TYPE (op)))
  	  {
  	    error ("type mismatch in address expression");
  	    debug_generic_stmt (lhs_type);
Index: gcc/testsuite/gcc.dg/vect/vect-54.c
===================================================================
*** gcc/testsuite/gcc.dg/vect/vect-54.c.orig	2009-04-06 16:18:47.000000000 +0200
--- gcc/testsuite/gcc.dg/vect/vect-54.c	2009-04-06 16:19:16.000000000 +0200
*************** void bar (float *pa, float *pb, float *p
*** 26,38 ****
     vect-58.c is similar to this one with one difference:
          the loop bound is unknown.  */
  
  __attribute__ ((noinline)) int
  main1 ()
  {
    int i;
    float a[N] __attribute__ ((__aligned__(16)));
-   float b[N] __attribute__ ((__aligned__(16))) = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57};
-   float c[N] __attribute__ ((__aligned__(16))) = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
    float *pa = a;
    float *pb = b;
    float *pc = c;
--- 26,39 ----
     vect-58.c is similar to this one with one difference:
          the loop bound is unknown.  */
  
+ float b[N] __attribute__ ((__aligned__(16))) = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57};
+ float c[N] __attribute__ ((__aligned__(16))) = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
+ 
  __attribute__ ((noinline)) int
  main1 ()
  {
    int i;
    float a[N] __attribute__ ((__aligned__(16)));
    float *pa = a;
    float *pb = b;
    float *pc = c;
Index: gcc/testsuite/gcc.dg/vect/vect-56.c
===================================================================
*** gcc/testsuite/gcc.dg/vect/vect-56.c.orig	2009-04-06 16:18:47.000000000 +0200
--- gcc/testsuite/gcc.dg/vect/vect-56.c	2009-04-06 16:19:16.000000000 +0200
*************** void bar (float *pa, float *pb, float *p
*** 30,42 ****
     vect-57.c is similar to this one with two differences:
          aliasing is a problem, and the write access has unknown alignment.  */
  
  __attribute__ ((noinline)) int
  main1 ()
  {
    int i;
    float a[N] __attribute__ ((__aligned__(16)));
-   float b[N] __attribute__ ((__aligned__(16))) = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57};
-   float c[N] __attribute__ ((__aligned__(16))) = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
    float *pa = a;
    float *pb = b;
    float *pc = c;
--- 30,43 ----
     vect-57.c is similar to this one with two differences:
          aliasing is a problem, and the write access has unknown alignment.  */
  
+ float b[N] __attribute__ ((__aligned__(16))) = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57};
+ float c[N] __attribute__ ((__aligned__(16))) = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
+ 
  __attribute__ ((noinline)) int
  main1 ()
  {
    int i;
    float a[N] __attribute__ ((__aligned__(16)));
    float *pa = a;
    float *pb = b;
    float *pc = c;
Index: gcc/testsuite/gcc.dg/vect/vect-58.c
===================================================================
*** gcc/testsuite/gcc.dg/vect/vect-58.c.orig	2009-04-06 16:18:47.000000000 +0200
--- gcc/testsuite/gcc.dg/vect/vect-58.c	2009-04-06 16:19:16.000000000 +0200
*************** void bar (float *pa, float *pb, float *p
*** 26,36 ****
     vect-54.c is similar to this one with one difference:
          the loop bound is known.  */
  
  __attribute__ ((noinline)) int
  main1 (int n)
  {
    int i;
-   float a[N] __attribute__ ((__aligned__(16)));  float b[N] __attribute__ ((__aligned__(16))) = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57};  float c[N] __attribute__ ((__aligned__(16))) = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
    float *pa = a;
    float *pb = b;
    float *pc = c;
--- 26,37 ----
     vect-54.c is similar to this one with one difference:
          the loop bound is known.  */
  
+ float a[N] __attribute__ ((__aligned__(16)));  float b[N] __attribute__ ((__aligned__(16))) = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57};  float c[N] __attribute__ ((__aligned__(16))) = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
+ 
  __attribute__ ((noinline)) int
  main1 (int n)
  {
    int i;
    float *pa = a;
    float *pb = b;
    float *pc = c;
Index: gcc/testsuite/gcc.dg/vect/vect-60.c
===================================================================
*** gcc/testsuite/gcc.dg/vect/vect-60.c.orig	2009-04-06 16:18:47.000000000 +0200
--- gcc/testsuite/gcc.dg/vect/vect-60.c	2009-04-06 16:19:16.000000000 +0200
*************** void bar (float *pa, float *pb, float *p
*** 30,42 ****
     vect-61.c is similar to this one with two differences:
          aliasing is not a problem, and the write access has unknown alignment.  */
  
  __attribute__ ((noinline)) int
  main1 (int n)
  {
    int i;
    float a[N] __attribute__ ((__aligned__(16)));
-   float b[N] __attribute__ ((__aligned__(16))) = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57};
-   float c[N] __attribute__ ((__aligned__(16))) = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
    float *pa = a;
    float *pb = b;
    float *pc = c;
--- 30,43 ----
     vect-61.c is similar to this one with two differences:
          aliasing is not a problem, and the write access has unknown alignment.  */
  
+ float b[N] __attribute__ ((__aligned__(16))) = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57};
+ float c[N] __attribute__ ((__aligned__(16))) = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
+ 
  __attribute__ ((noinline)) int
  main1 (int n)
  {
    int i;
    float a[N] __attribute__ ((__aligned__(16)));
    float *pa = a;
    float *pb = b;
    float *pc = c;
Index: gcc/testsuite/gcc.dg/vect/no-vfa-vect-57.c
===================================================================
*** gcc/testsuite/gcc.dg/vect/no-vfa-vect-57.c.orig	2009-04-06 16:18:47.000000000 +0200
--- gcc/testsuite/gcc.dg/vect/no-vfa-vect-57.c	2009-04-06 16:35:36.000000000 +0200
***************
*** 1,6 ****
--- 1,7 ----
  /* { dg-require-effective-target vect_float } */
  
  #include <stdarg.h>
+ #include <string.h>
  #include "tree-vect.h"
  
  #define N 256
*************** void bar (float *pa, float *pb, float *p
*** 20,25 ****
--- 21,35 ----
    return;
  }
  
+ __attribute__ ((noinline))
+ void foo (float *pb, float *pc)
+ {
+   float b[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57};
+   float c[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
+   memcpy (pb, b, sizeof (b));
+   memcpy (pc, c, sizeof (c));
+ }
+ 
  /* Unaligned pointer read accesses with known alignment,
     and an unaligned write access with unknown alignment.
     The loop bound is known and divisible by the vectorization factor.
*************** __attribute__ ((noinline)) int
*** 33,43 ****
  main1 (float *pa)
  {
    int i;
!   float b[N] __attribute__ ((__aligned__(16))) = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57};
!   float c[N] __attribute__ ((__aligned__(16))) = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
    float *pb = b;
    float *pc = c;
  
    for (i = 0; i < N/2; i++)
      {
        pa[i] = pb[i+1] * pc[i+1];
--- 43,55 ----
  main1 (float *pa)
  {
    int i;
!   float b[N] __attribute__ ((__aligned__(16)));
!   float c[N] __attribute__ ((__aligned__(16)));
    float *pb = b;
    float *pc = c;
  
+   foo (pb, pc);
+ 
    for (i = 0; i < N/2; i++)
      {
        pa[i] = pb[i+1] * pc[i+1];
Index: gcc/testsuite/gcc.dg/vect/no-vfa-vect-61.c
===================================================================
*** gcc/testsuite/gcc.dg/vect/no-vfa-vect-61.c.orig	2009-04-06 16:18:47.000000000 +0200
--- gcc/testsuite/gcc.dg/vect/no-vfa-vect-61.c	2009-04-06 16:40:02.000000000 +0200
***************
*** 2,7 ****
--- 2,8 ----
  /* { dg-require-effective-target vect_float } */
  
  #include <stdarg.h>
+ #include <string.h>
  #include "tree-vect.h"
  
  #define N 256
*************** void bar (float *pa, float *pb, float *p
*** 21,26 ****
--- 22,36 ----
    return;
  }
  
+ __attribute__ ((noinline))
+ void foo (float *pb, float *pc)
+ {
+   float b[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57};
+   float c[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
+   memcpy (pb, b, sizeof (b));
+   memcpy (pc, c, sizeof (c));
+ }
+ 
  /* Unaligned pointer read accesses with known alignment,
     and an unaligned write access with unknown alignment.
     The loop bound is iunknown.
*************** __attribute__ ((noinline)) int
*** 34,44 ****
  main1 (int n , float *pa)
  {
    int i;
!   float b[N] __attribute__ ((__aligned__(16))) = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57};
!   float c[N] __attribute__ ((__aligned__(16))) = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
    float *pb = b;
    float *pc = c;
  
    for (i = 0; i < n/2; i++)
      {
        pa[i] = pb[i+1] * pc[i+1];
--- 44,56 ----
  main1 (int n , float *pa)
  {
    int i;
!   float b[N] __attribute__ ((__aligned__(16)));
!   float c[N] __attribute__ ((__aligned__(16)));
    float *pb = b;
    float *pc = c;
  
+   foo (pb, pc);
+ 
    for (i = 0; i < n/2; i++)
      {
        pa[i] = pb[i+1] * pc[i+1];


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