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]

Vector misalignment


This patch adds several new warnings for possible misaligned vector
types. For example the following code

#define vector(elcount, type)  \
__attribute__((vector_size((elcount)*sizeof(type)))) type

int *array;
vector (4, int) vec;

array = (int *) malloc (128 * sizeof (int));
*((vector (4, int) *) &array[1]) = vec;

would produce no warnings, but causes a segmentation fault on intel
and powerpc architecture.

New warning type Wmisaligned is introduced.

Changelog:

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

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

        gcc/doc/
        * invoke.texi: Adjust.

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


bootstrapped and tested on x86-unknown-linux.
Index: gcc/doc/invoke.texi
===================================================================
--- gcc/doc/invoke.texi	(revision 163280)
+++ gcc/doc/invoke.texi	(working copy)
@@ -249,7 +249,7 @@ Objective-C and Objective-C++ Dialects}.
 -Wmain  -Wmissing-braces  -Wmissing-field-initializers @gol
 -Wmissing-format-attribute  -Wmissing-include-dirs @gol
 -Wno-mudflap @gol
--Wno-multichar  -Wnonnull  -Wno-overflow @gol
+-Wno-multichar  -Wnonnull  -Wno-overflow @gol -Wmisaligned
 -Woverlength-strings  -Wpacked  -Wpacked-bitfield-compat  -Wpadded @gol
 -Wparentheses  -Wpedantic-ms-format -Wno-pedantic-ms-format @gol
 -Wpointer-arith  -Wno-pointer-to-int-cast @gol
@@ -4317,6 +4317,25 @@ struct bar @{
 @end group
 @end smallexample
 
+@item -Wmisaligned
+@opindex Wmisaligned
+@opindex Wno-misaligned
+Warn if an expression can cause misalignment. Commonly it is useful
+for vector operations. If you cast a misaligned memory to a vector
+type it is possible to end up with a segmentation fault. Like in
+the following example.
+
+@smallexample
+#define vector(elcount, type)  \
+__attribute__((vector_size((elcount)*sizeof(type)))) type
+
+int *array;
+vector (4, int) vec;
+
+array = (int *) malloc (128 * sizeof (int));
+*((vector (4, int) *) &array[1]) = vec;
+@end smallexample
+
 @item -Wpacked-bitfield-compat
 @opindex Wpacked-bitfield-compat
 @opindex Wno-packed-bitfield-compat
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 -Wmisaligned" } */
+#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_Wmisaligned, 
+                          "Possible vector-pointer missaligned cast");
+        }
+      
       if (warn_strict_aliasing <= 2)
         strict_aliasing_warning (otype, type, expr);
 
Index: gcc/common.opt
===================================================================
--- gcc/common.opt	(revision 163280)
+++ gcc/common.opt	(working copy)
@@ -176,6 +176,10 @@ Wpacked
 Common Var(warn_packed) Warning
 Warn when the packed attribute has no effect on struct layout
 
+Wmisaligned
+Common Var(warn_misaligned) Warning
+Warn about possible misalignments
+
 Wpadded
 Common Var(warn_padded) Warning
 Warn when padding is required to align structure members
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,67 @@ type_for_widest_vector_mode (enum machin
     }
 }
 
+
+/* Cache the location for not giving a warning more than once per line.  */
+static location_t loc_cache = UNKNOWN_LOCATION;
+
+/* 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 (optimize == 0) 
+    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)
+              && loc_cache != loc)
+            warning_at (loc_cache = loc, OPT_Wmisaligned, 
+                        "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)
+          && loc_cache != loc)
+        warning_at (loc_cache = loc, OPT_Wmisaligned, 
+                    "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)
+              && loc_cache != loc)
+            warning_at (loc_cache = loc, OPT_Wmisaligned, 
+                        "Possibly misalignment vector-pointer assignment");
+        }   
+    }
+}
+
 /* Process one statement.  If we identify a vector operation, expand it.  */
 
 static void
@@ -396,6 +458,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;
 
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_Wmisaligned, 
+                          "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);

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