From 76e2c821a4c49fa870a5af4c24501bb821afda93 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Mon, 1 Aug 2016 09:39:52 +0000 Subject: [PATCH] extend shift count warnings to vector types gcc/c/ 2016-08-01 Jan Beulich * c-fold.c (c_fully_fold_internal): Also emit shift count warnings for vector types. * c-typeck.c (build_binary_op): Likewise. gcc/testsuite/ 2016-08-01 Jan Beulich * gcc.dg/vshift-6.c, gcc.dg/vshift-7.c: New. From-SVN: r238936 --- gcc/c/ChangeLog | 6 ++++ gcc/c/c-fold.c | 18 +++++++--- gcc/c/c-typeck.c | 58 ++++++++++++++++++++------------- gcc/testsuite/ChangeLog | 4 +++ gcc/testsuite/gcc.dg/vshift-6.c | 42 ++++++++++++++++++++++++ gcc/testsuite/gcc.dg/vshift-7.c | 47 ++++++++++++++++++++++++++ 6 files changed, 148 insertions(+), 27 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/vshift-6.c create mode 100644 gcc/testsuite/gcc.dg/vshift-7.c diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 06507581fad..1c0688b29a1 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,9 @@ +2016-08-01 Jan Beulich + + * c-fold.c (c_fully_fold_internal): Also emit shift count + warnings for vector types. + * c-typeck.c (build_binary_op): Likewise. + 2016-07-29 Marek Polacek PR c/71742 diff --git a/gcc/c/c-fold.c b/gcc/c/c-fold.c index 6c82f242bf1..8bc3a9c178f 100644 --- a/gcc/c/c-fold.c +++ b/gcc/c/c-fold.c @@ -320,8 +320,6 @@ c_fully_fold_internal (tree expr, bool in_init, bool *maybe_const_operands, if ((code == LSHIFT_EXPR || code == RSHIFT_EXPR) && TREE_CODE (orig_op1) != INTEGER_CST && TREE_CODE (op1) == INTEGER_CST - && (TREE_CODE (TREE_TYPE (orig_op0)) == INTEGER_TYPE - || TREE_CODE (TREE_TYPE (orig_op0)) == FIXED_POINT_TYPE) && TREE_CODE (TREE_TYPE (orig_op1)) == INTEGER_TYPE && c_inhibit_evaluation_warnings == 0) { @@ -330,13 +328,23 @@ c_fully_fold_internal (tree expr, bool in_init, bool *maybe_const_operands, (code == LSHIFT_EXPR ? G_("left shift count is negative") : G_("right shift count is negative"))); - else if (compare_tree_int (op1, - TYPE_PRECISION (TREE_TYPE (orig_op0))) - >= 0) + else if ((TREE_CODE (TREE_TYPE (orig_op0)) == INTEGER_TYPE + || TREE_CODE (TREE_TYPE (orig_op0)) == FIXED_POINT_TYPE) + && compare_tree_int (op1, + TYPE_PRECISION (TREE_TYPE (orig_op0))) + >= 0) warning_at (loc, OPT_Wshift_count_overflow, (code == LSHIFT_EXPR ? G_("left shift count >= width of type") : G_("right shift count >= width of type"))); + else if (TREE_CODE (TREE_TYPE (orig_op0)) == VECTOR_TYPE + && compare_tree_int (op1, + TYPE_PRECISION (TREE_TYPE (TREE_TYPE (orig_op0)))) + >= 0) + warning_at (loc, OPT_Wshift_count_overflow, + code == LSHIFT_EXPR + ? G_("left shift count >= width of vector element") + : G_("right shift count >= width of vector element")); } if (code == LSHIFT_EXPR /* If either OP0 has been folded to INTEGER_CST... */ diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c index 07e39ef04d1..33c06d40417 100644 --- a/gcc/c/c-typeck.c +++ b/gcc/c/c-typeck.c @@ -10986,21 +10986,16 @@ build_binary_op (location_t location, enum tree_code code, Also set SHORT_SHIFT if shifting rightward. */ case RSHIFT_EXPR: - if (code0 == VECTOR_TYPE && code1 == INTEGER_TYPE - && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE) - { - result_type = type0; - converted = 1; - } - else if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE - && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE - && TREE_CODE (TREE_TYPE (type1)) == INTEGER_TYPE - && TYPE_VECTOR_SUBPARTS (type0) == TYPE_VECTOR_SUBPARTS (type1)) + if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE + && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE + && TREE_CODE (TREE_TYPE (type1)) == INTEGER_TYPE + && TYPE_VECTOR_SUBPARTS (type0) == TYPE_VECTOR_SUBPARTS (type1)) { result_type = type0; converted = 1; } - else if ((code0 == INTEGER_TYPE || code0 == FIXED_POINT_TYPE) + else if ((code0 == INTEGER_TYPE || code0 == FIXED_POINT_TYPE + || code0 == VECTOR_TYPE) && code1 == INTEGER_TYPE) { doing_shift = true; @@ -11013,6 +11008,18 @@ build_binary_op (location_t location, enum tree_code code, warning_at (location, OPT_Wshift_count_negative, "right shift count is negative"); } + else if (code0 == VECTOR_TYPE) + { + if (compare_tree_int (op1, + TYPE_PRECISION (TREE_TYPE (type0))) + >= 0) + { + int_const = false; + if (c_inhibit_evaluation_warnings == 0) + warning_at (location, OPT_Wshift_count_overflow, + "right shift count >= width of vector element"); + } + } else { if (!integer_zerop (op1)) @@ -11036,21 +11043,16 @@ build_binary_op (location_t location, enum tree_code code, break; case LSHIFT_EXPR: - if (code0 == VECTOR_TYPE && code1 == INTEGER_TYPE - && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE) - { - result_type = type0; - converted = 1; - } - else if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE - && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE - && TREE_CODE (TREE_TYPE (type1)) == INTEGER_TYPE - && TYPE_VECTOR_SUBPARTS (type0) == TYPE_VECTOR_SUBPARTS (type1)) + if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE + && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE + && TREE_CODE (TREE_TYPE (type1)) == INTEGER_TYPE + && TYPE_VECTOR_SUBPARTS (type0) == TYPE_VECTOR_SUBPARTS (type1)) { result_type = type0; converted = 1; } - else if ((code0 == INTEGER_TYPE || code0 == FIXED_POINT_TYPE) + else if ((code0 == INTEGER_TYPE || code0 == FIXED_POINT_TYPE + || code0 == VECTOR_TYPE) && code1 == INTEGER_TYPE) { doing_shift = true; @@ -11074,6 +11076,18 @@ build_binary_op (location_t location, enum tree_code code, warning_at (location, OPT_Wshift_count_negative, "left shift count is negative"); } + else if (code0 == VECTOR_TYPE) + { + if (compare_tree_int (op1, + TYPE_PRECISION (TREE_TYPE (type0))) + >= 0) + { + int_const = false; + if (c_inhibit_evaluation_warnings == 0) + warning_at (location, OPT_Wshift_count_overflow, + "left shift count >= width of vector element"); + } + } else if (compare_tree_int (op1, TYPE_PRECISION (type0)) >= 0) { int_const = false; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ec6d798e1be..c16b2698624 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2016-08-01 Jan Beulich + + * gcc.dg/vshift-6.c, gcc.dg/vshift-7.c: New. + 2016-07-31 Bill Schmidt * gcc.target/powerpc/divkc3-1.c: Require POWER8 hardware. diff --git a/gcc/testsuite/gcc.dg/vshift-6.c b/gcc/testsuite/gcc.dg/vshift-6.c new file mode 100644 index 00000000000..6f7a0b05b88 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vshift-6.c @@ -0,0 +1,42 @@ +/* { dg-do compile } */ +/* { dg-options "-Wshift-count-negative -Wshift-count-overflow" } */ + +typedef unsigned int v1qi_t __attribute__((mode(QI), vector_size(1))); +typedef unsigned int v1hi_t __attribute__((mode(HI), vector_size(2))); +typedef unsigned int v1si_t __attribute__((mode(SI), vector_size(4))); + +v1qi_t test1qi(v1qi_t x, int c) { + switch(c) { + case 0: return x << -1; /* { dg-warning "shift count is negative" } */ + case 1: return x << 7; + case 2: return x << 8; /* { dg-warning "shift count >= width" } */ + case ~0: return x >> -1; /* { dg-warning "shift count is negative" } */ + case ~1: return x >> 7; + case ~2: return x >> 8; /* { dg-warning "shift count >= width" } */ + } + return c < 0 ? x >> -c : x << c; +} + +v1hi_t test1hi(v1hi_t x, int c) { + switch(c) { + case 0: return x << -1; /* { dg-warning "shift count is negative" } */ + case 1: return x << 15; + case 2: return x << 16; /* { dg-warning "shift count >= width" } */ + case ~0: return x >> -1; /* { dg-warning "shift count is negative" } */ + case ~1: return x >> 15; + case ~2: return x >> 16; /* { dg-warning "shift count >= width" } */ + } + return c < 0 ? x >> -c : x << c; +} + +v1si_t test1si(v1si_t x, int c) { + switch(c) { + case 0: return x << -1; /* { dg-warning "shift count is negative" } */ + case 1: return x << 31; + case 2: return x << 32; /* { dg-warning "shift count >= width" } */ + case ~0: return x >> -1; /* { dg-warning "shift count is negative" } */ + case ~1: return x >> 31; + case ~2: return x >> 32; /* { dg-warning "shift count >= width" } */ + } + return c < 0 ? x >> -c : x << c; +} diff --git a/gcc/testsuite/gcc.dg/vshift-7.c b/gcc/testsuite/gcc.dg/vshift-7.c new file mode 100644 index 00000000000..27321209dea --- /dev/null +++ b/gcc/testsuite/gcc.dg/vshift-7.c @@ -0,0 +1,47 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -Wshift-count-negative -Wshift-count-overflow" } */ + +typedef unsigned int v1qi_t __attribute__((mode(QI), vector_size(1))); +typedef unsigned int v1hi_t __attribute__((mode(HI), vector_size(2))); +typedef unsigned int v1si_t __attribute__((mode(SI), vector_size(4))); + +static const signed shift_neg = -1; +static const unsigned shift_qi = 8; +static const unsigned shift_hi = 16; +static const unsigned shift_si = 32; + +v1qi_t test1qi(v1qi_t x, int c) { + switch(c) { + case 0: return x << shift_neg; /* { dg-warning "shift count is negative" } */ + case 1: return x << (shift_qi - 1); + case 2: return x << shift_qi; /* { dg-warning "shift count >= width" } */ + case ~0: return x >> shift_neg; /* { dg-warning "shift count is negative" } */ + case ~1: return x >> (shift_qi - 1); + case ~2: return x >> shift_qi; /* { dg-warning "shift count >= width" } */ + } + return c < 0 ? x >> -c : x << c; +} + +v1hi_t test1hi(v1hi_t x, int c) { + switch(c) { + case 0: return x << shift_neg; /* { dg-warning "shift count is negative" } */ + case 1: return x << (shift_hi - 1); + case 2: return x << shift_hi; /* { dg-warning "shift count >= width" } */ + case ~0: return x >> shift_neg; /* { dg-warning "shift count is negative" } */ + case ~1: return x >> (shift_hi - 1); + case ~2: return x >> shift_hi; /* { dg-warning "shift count >= width" } */ + } + return c < 0 ? x >> -c : x << c; +} + +v1si_t test1si(v1si_t x, int c) { + switch(c) { + case 0: return x << shift_neg; /* { dg-warning "shift count is negative" } */ + case 1: return x << (shift_si - 1); + case 2: return x << shift_si; /* { dg-warning "shift count >= width" } */ + case ~0: return x >> shift_neg; /* { dg-warning "shift count is negative" } */ + case ~1: return x >> (shift_si - 1); + case ~2: return x >> shift_si; /* { dg-warning "shift count >= width" } */ + } + return c < 0 ? x >> -c : x << c; +} -- 2.30.2