re PR tree-optimization/61743 (Complete unroll is not happened for loops with short...
authorRichard Biener <rguenther@suse.de>
Thu, 15 Jan 2015 15:02:11 +0000 (15:02 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Thu, 15 Jan 2015 15:02:11 +0000 (15:02 +0000)
2015-01-15  Richard Biener  <rguenther@suse.de>

PR tree-optimization/61743
* tree-ssa-pre.c (insert_into_preds_of_block): Preserve range
information on PHIs for some simple cases.

* gcc.dg/tree-ssa/pr61743-1.c: New testcase.
* gcc.dg/tree-ssa/pr61743-2.c: Likewise.

From-SVN: r219662

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/pr61743-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-ssa/pr61743-2.c [new file with mode: 0644]
gcc/tree-ssa-pre.c

index 21d6a8809f1b598a8b291c3dab6b1ac78eb4458b..da62dae337cf9ca044d12d1ebc2640cc395263fa 100644 (file)
@@ -1,3 +1,9 @@
+2015-01-15  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/61743
+       * tree-ssa-pre.c (insert_into_preds_of_block): Preserve range
+       information on PHIs for some simple cases.
+
 2015-01-15  Philipp Tomsich  <philipp.tomsich@theobroma-systems.com>
 
        * config/arm/arm.md (generic_sched): Specify xgene1 in 'no' list.
index 04a43c502f0615ed747b7395970161dacf036c94..8a5cf7e1c6f7d0f8caaefe1fc2d609f196e1c22c 100644 (file)
@@ -1,3 +1,9 @@
+2015-01-15  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/61743
+       * gcc.dg/tree-ssa/pr61743-1.c: New testcase.
+       * gcc.dg/tree-ssa/pr61743-2.c: Likewise.
+
 2015-01-15 Renlin Li <renlin.li@arm.com>
 
        * gcc.target/aarch64/volatileloadpair-1.c: Correct dg-options.
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr61743-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr61743-1.c
new file mode 100644 (file)
index 0000000..de09daa
--- /dev/null
@@ -0,0 +1,53 @@
+/* { dg-do compile } */\r
+/* { dg-options "-O3 -funroll-loops -fdump-tree-cunroll-details" } */\r
+\r
+#define N 8\r
+#define M 14\r
+typedef unsigned char e_u8;\r
+e_u8 x[256];\r
+#define MAX(a,b) ((a)>=(b)?(a):(b))\r
+#define btype int\r
+\r
+static inline void bar1(e_u8 a[4][N], e_u8 b[4][N], btype n)\r
+{\r
+  int i, j;\r
+\r
+  for(i = 0; i < 4; i++)\r
+    for(j = 0; j < n; j++)\r
+      a[i][j] ^= b[i][j];\r
+}\r
+\r
+static inline void bar2(e_u8 a[4][N], e_u8 b[256], btype n)\r
+{\r
+  int i, j;\r
+\r
+  for(i = 0; i < 4; i++)\r
+    for(j = 0; j < n; j++)\r
+      a[i][j] = b[a[i][j]] ;\r
+}\r
+\r
+int foo1 (e_u8 a[4][N], int b1, int b2, e_u8 b[M+1][4][N])\r
+{\r
+  btype n;\r
+  int r, m;\r
+\r
+  switch (b2) {\r
+    case 128: n = 4; break;\r
+    case 192: n = 6; break;\r
+    case 256: n = 8; break;\r
+    default : return (-2);\r
+  }\r
+  switch (MAX(b1,b2)) {\r
+    case 128: m = 10; break;\r
+    case 192: m = 12; break;\r
+    case 256: m = 14; break;\r
+    default : return (-3);\r
+  }\r
+  bar1(a,b[m],n);\r
+  bar2(a,x,n);\r
+  return 0;\r
+}\r
+\r
+/* { dg-final { scan-tree-dump-times "loop with 4 iterations completely unrolled" 2 "cunroll" } } */\r
+/* { dg-final { scan-tree-dump-times "loop with 8 iterations completely unrolled" 2 "cunroll" } } */\r
+/* { dg-final { cleanup-tree-dump "cunroll" } } */\r
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr61743-2.c b/gcc/testsuite/gcc.dg/tree-ssa/pr61743-2.c
new file mode 100644 (file)
index 0000000..c8a4391
--- /dev/null
@@ -0,0 +1,53 @@
+/* { dg-do compile } */\r
+/* { dg-options "-O3 -funroll-loops -fdump-tree-cunroll-details" } */\r
+\r
+#define N 8\r
+#define M 14\r
+typedef unsigned char e_u8;\r
+e_u8 x[256];\r
+#define MAX(a,b) ((a)>=(b)?(a):(b))\r
+#define btype e_u8\r
+\r
+static inline void bar1(e_u8 a[4][N], e_u8 b[4][N], btype n)\r
+{\r
+  int i, j;\r
+\r
+  for(i = 0; i < 4; i++)\r
+    for(j = 0; j < n; j++)\r
+      a[i][j] ^= b[i][j];\r
+}\r
+\r
+static inline void bar2(e_u8 a[4][N], e_u8 b[256], btype n)\r
+{\r
+  int i, j;\r
+\r
+  for(i = 0; i < 4; i++)\r
+    for(j = 0; j < n; j++)\r
+      a[i][j] = b[a[i][j]] ;\r
+}\r
+\r
+int foo1 (e_u8 a[4][N], int b1, int b2, e_u8 b[M+1][4][N])\r
+{\r
+  btype n;\r
+  int r, m;\r
+\r
+  switch (b2) {\r
+    case 128: n = 4; break;\r
+    case 192: n = 6; break;\r
+    case 256: n = 8; break;\r
+    default : return (-2);\r
+  }\r
+  switch (MAX(b1,b2)) {\r
+    case 128: m = 10; break;\r
+    case 192: m = 12; break;\r
+    case 256: m = 14; break;\r
+    default : return (-3);\r
+  }\r
+  bar1(a,b[m],n);\r
+  bar2(a,x,n);\r
+  return 0;\r
+}\r
+\r
+/* { dg-final { scan-tree-dump-times "loop with 4 iterations completely unrolled" 2 "cunroll" } } */\r
+/* { dg-final { scan-tree-dump-times "loop with 8 iterations completely unrolled" 2 "cunroll" } } */\r
+/* { dg-final { cleanup-tree-dump "cunroll" } } */\r
index 3ef7510df663c8fc890b9ef9c8b4b0a8bbd0aefa..32cd74dd3bbbd5031a80254750dc8f6d7226619c 100644 (file)
@@ -3184,6 +3184,33 @@ insert_into_preds_of_block (basic_block block, unsigned int exprnum,
   bitmap_insert_into_set (NEW_SETS (block),
                          newphi);
 
+  /* If we insert a PHI node for a conversion of another PHI node
+     in the same basic-block try to preserve range information.
+     This is important so that followup loop passes receive optimal
+     number of iteration analysis results.  See PR61743.  */
+  if (expr->kind == NARY
+      && CONVERT_EXPR_CODE_P (expr->u.nary->opcode)
+      && TREE_CODE (expr->u.nary->op[0]) == SSA_NAME
+      && gimple_bb (SSA_NAME_DEF_STMT (expr->u.nary->op[0])) == block
+      && INTEGRAL_TYPE_P (type)
+      && INTEGRAL_TYPE_P (TREE_TYPE (expr->u.nary->op[0]))
+      && (TYPE_PRECISION (type)
+         >= TYPE_PRECISION (TREE_TYPE (expr->u.nary->op[0])))
+      && SSA_NAME_RANGE_INFO (expr->u.nary->op[0]))
+    {
+      wide_int min, max;
+      if (get_range_info (expr->u.nary->op[0], &min, &max) == VR_RANGE
+         && !wi::neg_p (min, SIGNED)
+         && !wi::neg_p (max, SIGNED))
+       /* Just handle extension and sign-changes of all-positive ranges.  */
+       set_range_info (temp,
+                       SSA_NAME_RANGE_TYPE (expr->u.nary->op[0]),
+                       wide_int_storage::from (min, TYPE_PRECISION (type),
+                                               TYPE_SIGN (type)),
+                       wide_int_storage::from (max, TYPE_PRECISION (type),
+                                               TYPE_SIGN (type)));
+    }
+
   if (dump_file && (dump_flags & TDF_DETAILS))
     {
       fprintf (dump_file, "Created phi ");