diff mbox

Vector misalignment

Message ID AANLkTi=eQz+XYXxZz_M4emxxPbHHGLpUZJ4uu3v93-dr@mail.gmail.com
State New
Headers show

Commit Message

Artem Shinkarov Aug. 18, 2010, 2:59 p.m. UTC
Considering Andrews comments the type of warning was changed to
-Wcast-align, and in -O3 case we perform checking at the second run of
veclower, where we have an alignment information propagated as far as
possible.

Changelog:

2010-08-16 Artem Shinkarov <artyom.shinkaroff@gmail.com>

       gcc/
       * c-typeck.c (build_c_cast): Add warning.
       * tree-vect-generic.c (check_alignment): Check possible misalignment
       in vector types.
       (expand_vector_operations_1): Adjust.
       (expand_vector_operations1): New gate function.
       * Makefile.in: New dependency.
       * convert.c (convert_to_pointer): Add warning.

       gcc/testsuite/
       * gcc.dg/vector-check-align.c: New test-case.
diff mbox

Patch

Index: gcc/testsuite/gcc.dg/vector-check-align.c
===================================================================
--- gcc/testsuite/gcc.dg/vector-check-align.c	(revision 0)
+++ gcc/testsuite/gcc.dg/vector-check-align.c	(revision 0)
@@ -0,0 +1,25 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O0 -Wcast-align" } */
+#define vector(elcount, type)  \
+__attribute__((vector_size((elcount)*sizeof(type)))) type
+
+typedef int unaligned_intv __attribute__((vector_size(16), aligned(4)));
+
+vector (4, int) *
+loadu (int *p) {
+  return (unaligned_intv *)p; /* { dg-warning "" } */
+}
+
+
+int main (int argc, char *argv[]) {
+    int * array;
+    vector (4, int) v = {argc, 1,2,3};
+
+    array = (int *) __builtin_malloc (137 * sizeof (int));
+    *((vector(4, int) *)(1+ array)) = v; /* { dg-warning "" } */
+    *(loadu (&array[0])) = v; 
+
+    return array[argc];
+}
+
+
Index: gcc/c-typeck.c
===================================================================
--- gcc/c-typeck.c	(revision 163280)
+++ gcc/c-typeck.c	(working copy)
@@ -4674,6 +4674,17 @@  build_c_cast (location_t loc, tree type,
 		    OPT_Wint_to_pointer_cast, "cast to pointer from integer "
 		    "of different size");
 
+      if (TREE_CODE (type) == POINTER_TYPE 
+          && TREE_CODE (TREE_TYPE (type)) == VECTOR_TYPE
+          && TREE_CODE (TREE_TYPE (expr)) == POINTER_TYPE)
+        {
+            if (TYPE_ALIGN (TREE_TYPE (type))
+                >  MAX (TYPE_ALIGN (TREE_TYPE (TREE_TYPE (expr))),
+                        get_pointer_alignment (expr, 0)))
+              warning_at (loc, OPT_Wcast_align, 
+                          "Possible vector-pointer misaligned cast");
+        }
+      
       if (warn_strict_aliasing <= 2)
         strict_aliasing_warning (otype, type, expr);
 
Index: gcc/tree-vect-generic.c
===================================================================
--- gcc/tree-vect-generic.c	(revision 163280)
+++ gcc/tree-vect-generic.c	(working copy)
@@ -30,6 +30,7 @@  along with GCC; see the file COPYING3.  
 #include "tree-pass.h"
 #include "flags.h"
 #include "ggc.h"
+#include "diagnostic.h"
 
 /* Need to include rtl.h, expr.h, etc. for optabs.  */
 #include "expr.h"
@@ -383,6 +384,64 @@  type_for_widest_vector_mode (enum machin
     }
 }
 
+
+/* Gate to the check_alignment function.  */
+static int enable_misaligned_warn = 0;
+
+/* Show warning if alignemnt in vector assignment or alignment in 
+   vector-type mem_ref is incorrect. Works only when optimized == 1  */
+static void
+check_alignment (gimple_stmt_iterator *gsi)
+{
+  gimple stmt = gsi_stmt (*gsi);
+  tree lhs, rhs, rtype;
+  location_t loc = gimple_location (stmt);
+
+  if (!enable_misaligned_warn) 
+    return;
+
+  if (gimple_assign_single_p (stmt))
+    {
+      lhs = gimple_assign_lhs (stmt);
+      rhs = gimple_assign_rhs1 (stmt);
+      rtype = TREE_TYPE (rhs);
+
+      if (TREE_CODE (rhs) == MEM_REF 
+          && TREE_CODE (TREE_TYPE (rhs)) == VECTOR_TYPE)
+        {
+          if (TYPE_ALIGN (TREE_TYPE (rhs))
+              > get_object_alignment (rhs, BIGGEST_ALIGNMENT))
+            warning_at (loc, OPT_Wcast_align, 
+                        "Possibly misaligned vector-type memory refernce "
+                        "on the assignment right hand side");
+        }
+    }
+  else
+    return;
+
+  if (TREE_CODE (lhs) == MEM_REF 
+      && TREE_CODE (TREE_TYPE (lhs)) == VECTOR_TYPE)
+    {
+      if (TYPE_ALIGN (TREE_TYPE (lhs)) 
+          > get_object_alignment (lhs, BIGGEST_ALIGNMENT))
+        warning_at (loc, OPT_Wcast_align, 
+                    "Possibly misaligned vector-type memory reference");
+    }
+
+  if (POINTER_TYPE_P (TREE_TYPE (lhs))
+      && TREE_CODE (TREE_TYPE (TREE_TYPE (lhs))) == VECTOR_TYPE)
+    {
+      if (TREE_CODE (rhs) == ADDR_EXPR
+          && TREE_CODE (TREE_TYPE (rtype)) == VECTOR_TYPE)
+        {
+          if (TYPE_ALIGN (TREE_TYPE (TREE_TYPE (lhs)))
+              > get_pointer_alignment (rhs, BIGGEST_ALIGNMENT))
+            warning_at (loc, OPT_Wcast_align, 
+                        "Possibly misalignment vector-pointer assignment");
+        }   
+    }
+}
+
 /* Process one statement.  If we identify a vector operation, expand it.  */
 
 static void
@@ -396,6 +455,8 @@  expand_vector_operations_1 (gimple_stmt_
   enum gimple_rhs_class rhs_class;
   tree new_rhs;
 
+  check_alignment (gsi);
+
   if (gimple_code (stmt) != GIMPLE_ASSIGN)
     return;
 
@@ -544,6 +605,14 @@  expand_vector_operations (void)
   return 0;
 }
 
+static unsigned int
+expand_vector_operations1 (void)
+{
+  enable_misaligned_warn = 1;
+  return expand_vector_operations ();
+}
+
+
 struct gimple_opt_pass pass_lower_vector =
 {
  {
@@ -570,7 +639,7 @@  struct gimple_opt_pass pass_lower_vector
   GIMPLE_PASS,
   "veclower2",				/* name */
   gate_expand_vector_operations,	/* gate */
-  expand_vector_operations,		/* execute */
+  expand_vector_operations1,		/* execute */
   NULL,					/* sub */
   NULL,					/* next */
   0,					/* static_pass_number */
Index: gcc/Makefile.in
===================================================================
--- gcc/Makefile.in	(revision 163280)
+++ gcc/Makefile.in	(working copy)
@@ -3156,7 +3156,7 @@  tree-vect-generic.o : tree-vect-generic.
     $(TM_H) $(TREE_FLOW_H) $(GIMPLE_H) tree-iterator.h $(TREE_PASS_H) \
     $(FLAGS_H) $(OPTABS_H) $(MACHMODE_H) $(EXPR_H) \
     langhooks.h $(FLAGS_H) $(DIAGNOSTIC_H) gt-tree-vect-generic.h $(GGC_H) \
-    coretypes.h insn-codes.h
+    coretypes.h insn-codes.h diagnostic.h
 df-core.o : df-core.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
    insn-config.h $(RECOG_H) $(FUNCTION_H) $(REGS_H) alloc-pool.h \
    hard-reg-set.h $(BASIC_BLOCK_H) $(DF_H) $(BITMAP_H) sbitmap.h $(TIMEVAR_H) \
Index: gcc/convert.c
===================================================================
--- gcc/convert.c	(revision 163280)
+++ gcc/convert.c	(working copy)
@@ -60,7 +60,19 @@  convert_to_pointer (tree type, tree expr
 	addr_space_t to_as = TYPE_ADDR_SPACE (TREE_TYPE (type));
 	addr_space_t from_as = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (expr)));
 
-	if (to_as == from_as)
+        if (TREE_CODE (TREE_TYPE (TREE_TYPE (expr))) == VECTOR_TYPE)
+          {
+            /* Check whether implicit vector conversion preserves
+               alignment.  */
+            if (TREE_CODE (type) == POINTER_TYPE
+                && TYPE_ALIGN (TREE_TYPE (type))
+                   > MAX (TYPE_ALIGN (TREE_TYPE (TREE_TYPE (expr))),
+                          get_pointer_alignment (expr, 0)))
+              warning_at (loc, OPT_Wcast_align, 
+                          "Possible vector-pointer missaligned cast");
+          }
+
+        if (to_as == from_as)
 	  return fold_build1_loc (loc, NOP_EXPR, type, expr);
 	else
 	  return fold_build1_loc (loc, ADDR_SPACE_CONVERT_EXPR, type, expr);