aboutsummaryrefslogtreecommitdiffstats
path: root/toolchain-layer/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106853.patch
blob: 8c51c1d1f31b3431b044eaf9b0523aa66c854989 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
2011-12-20  Ira Rosen  <ira.rosen@linaro.org>

	Backport from mainline:

	2011-11-29  Ira Rosen  <ira.rosen@linaro.org>

	PR tree-optimization/51301
	gcc/
	* tree-vect-patterns.c (vect_recog_over_widening_pattern): Check that
	the last statement doesn't convert to a bigger type than the original
	type of the computation.

	gcc/testsuite/
	* gcc.dg/vect/pr51301.c: New test.

=== added file 'gcc/testsuite/gcc.dg/vect/pr51301.c'
--- old/gcc/testsuite/gcc.dg/vect/pr51301.c	1970-01-01 00:00:00 +0000
+++ new/gcc/testsuite/gcc.dg/vect/pr51301.c	2011-11-30 17:54:51 +0000
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+
+typedef signed char int8_t;
+typedef signed long long int64_t;
+int64_t
+f0a (int8_t * __restrict__ arg1)
+{
+  int idx;
+  int64_t result = 0;
+  for (idx = 0; idx < 416; idx += 1)
+    result += arg1[idx] << (arg1[idx] == arg1[idx]);
+  return result;
+}
+
+/* { dg-final { cleanup-tree-dump "vect" } } */

=== modified file 'gcc/tree-vect-patterns.c'
--- old/gcc/tree-vect-patterns.c	2011-11-27 12:17:31 +0000
+++ new/gcc/tree-vect-patterns.c	2011-12-20 07:47:44 +0000
@@ -1138,6 +1138,7 @@
   struct loop *loop = NULL;
   bb_vec_info bb_vinfo;
   stmt_vec_info stmt_vinfo;
+  tree type = NULL;
 
   stmt_vinfo = vinfo_for_stmt (stmt);
   loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_vinfo);
@@ -1207,6 +1208,7 @@
           print_gimple_stmt (vect_dump, pattern_stmt, 0, TDF_SLIM);
         }
 
+      type = gimple_expr_type (stmt);
       prev_stmt = stmt;
       stmt = use_stmt;
 
@@ -1222,9 +1224,11 @@
     {
       use_lhs = gimple_assign_lhs (use_stmt);
       use_type = TREE_TYPE (use_lhs);
-      /* Support only type promotion or signedess change.  */
+      /* Support only type promotion or signedess change.  Check that USE_TYPE
+        is not bigger than the original type.  */
       if (!INTEGRAL_TYPE_P (use_type)
-          || TYPE_PRECISION (new_type) > TYPE_PRECISION (use_type))
+          || TYPE_PRECISION (new_type) > TYPE_PRECISION (use_type)
+         || TYPE_PRECISION (type) < TYPE_PRECISION (use_type))
         return NULL;
 
       if (TYPE_UNSIGNED (new_type) != TYPE_UNSIGNED (use_type)