From patchwork Mon Aug 16 18:15:34 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Artem Shinkarov X-Patchwork-Id: 61825 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 32F36B70A8 for ; Tue, 17 Aug 2010 04:16:12 +1000 (EST) Received: (qmail 30252 invoked by alias); 16 Aug 2010 18:16:09 -0000 Received: (qmail 30238 invoked by uid 22791); 16 Aug 2010 18:16:06 -0000 X-SWARE-Spam-Status: No, hits=-1.9 required=5.0 tests=AWL, BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE, TW_TM, T_TO_NO_BRKTS_FREEMAIL X-Spam-Check-By: sourceware.org Received: from mail-qw0-f47.google.com (HELO mail-qw0-f47.google.com) (209.85.216.47) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 16 Aug 2010 18:15:57 +0000 Received: by qwi2 with SMTP id 2so180341qwi.20 for ; Mon, 16 Aug 2010 11:15:55 -0700 (PDT) Received: by 10.229.52.26 with SMTP id f26mr44390qcg.244.1281982555163; Mon, 16 Aug 2010 11:15:55 -0700 (PDT) MIME-Version: 1.0 Received: by 10.229.66.165 with HTTP; Mon, 16 Aug 2010 11:15:34 -0700 (PDT) From: Artem Shinkarov Date: Mon, 16 Aug 2010 19:15:34 +0100 Message-ID: Subject: Vector misalignment To: gcc-patches@gcc.gnu.org Cc: Richard Guenther X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org 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 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);