diff mbox

Fix PR61743

Message ID alpine.LSU.2.11.1501151255290.12482@zhemvz.fhfr.qr
State New
Headers show

Commit Message

Richard Biener Jan. 15, 2015, 12:01 p.m. UTC
I am testing the following hack^Wpatch which makes us preserve
range information in some very special case in PRE.  This is
important to get number of iteration analysis results in a way
to enable unrolling of loops in some EEMBC testcase (I don't
have access to that benchmark unless it is part of coremark).

I'm not 100% happy about that special-casing (and in future
we might consider moving core range operation from VRP to
somewhere publically accessible to compute the cast of the
range properly also for truncations and negative ranges).

Bootstrap and regtest in progress on x86_64-unknown-linux-gnu.

Tell me if you think this is too much of a hack and exporting
extract_range_from_unary_expr_1 from tree-vrp.c and using that
would be less of that (I'd rather move things elsewhere to
make sure the exported routines are isolated well enough from
VRP internals).

Thanks,
Richard.

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.
diff mbox

Patch

Index: gcc/tree-ssa-pre.c
===================================================================
--- gcc/tree-ssa-pre.c	(revision 219646)
+++ gcc/tree-ssa-pre.c	(working copy)
@@ -3173,6 +3172,33 @@  insert_into_preds_of_block (basic_block
   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 ");
Index: gcc/testsuite/gcc.dg/tree-ssa/pr61743-2.c
===================================================================
--- gcc/testsuite/gcc.dg/tree-ssa/pr61743-2.c	(revision 0)
+++ gcc/testsuite/gcc.dg/tree-ssa/pr61743-2.c	(working copy)
@@ -0,0 +1,53 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O3 -funroll-loops -fdump-tree-cunroll-details" } */
+
+#define N 8
+#define M 14
+typedef unsigned char e_u8;
+e_u8 x[256];
+#define MAX(a,b) ((a)>=(b)?(a):(b))
+#define btype e_u8
+
+static inline void bar1(e_u8 a[4][N], e_u8 b[4][N], btype n)
+{
+  int i, j;
+
+  for(i = 0; i < 4; i++)
+    for(j = 0; j < n; j++)
+      a[i][j] ^= b[i][j];
+}
+
+static inline void bar2(e_u8 a[4][N], e_u8 b[256], btype n)
+{
+  int i, j;
+
+  for(i = 0; i < 4; i++)
+    for(j = 0; j < n; j++)
+      a[i][j] = b[a[i][j]] ;
+}
+
+int foo1 (e_u8 a[4][N], int b1, int b2, e_u8 b[M+1][4][N])
+{
+  btype n;
+  int r, m;
+
+  switch (b2) {
+    case 128: n = 4; break;
+    case 192: n = 6; break;
+    case 256: n = 8; break;
+    default : return (-2);
+  }
+  switch (MAX(b1,b2)) {
+    case 128: m = 10; break;
+    case 192: m = 12; break;
+    case 256: m = 14; break;
+    default : return (-3);
+  }
+  bar1(a,b[m],n);
+  bar2(a,x,n);
+  return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "loop with 4 iterations completely unrolled" 2 "cunroll" } } */
+/* { dg-final { scan-tree-dump-times "loop with 8 iterations completely unrolled" 2 "cunroll" } } */
+/* { dg-final { cleanup-tree-dump "cunroll" } } */
Index: gcc/testsuite/gcc.dg/tree-ssa/pr61743-1.c
===================================================================
--- gcc/testsuite/gcc.dg/tree-ssa/pr61743-1.c	(revision 0)
+++ gcc/testsuite/gcc.dg/tree-ssa/pr61743-1.c	(working copy)
@@ -0,0 +1,53 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O3 -funroll-loops -fdump-tree-cunroll-details" } */
+
+#define N 8
+#define M 14
+typedef unsigned char e_u8;
+e_u8 x[256];
+#define MAX(a,b) ((a)>=(b)?(a):(b))
+#define btype int
+
+static inline void bar1(e_u8 a[4][N], e_u8 b[4][N], btype n)
+{
+  int i, j;
+
+  for(i = 0; i < 4; i++)
+    for(j = 0; j < n; j++)
+      a[i][j] ^= b[i][j];
+}
+
+static inline void bar2(e_u8 a[4][N], e_u8 b[256], btype n)
+{
+  int i, j;
+
+  for(i = 0; i < 4; i++)
+    for(j = 0; j < n; j++)
+      a[i][j] = b[a[i][j]] ;
+}
+
+int foo1 (e_u8 a[4][N], int b1, int b2, e_u8 b[M+1][4][N])
+{
+  btype n;
+  int r, m;
+
+  switch (b2) {
+    case 128: n = 4; break;
+    case 192: n = 6; break;
+    case 256: n = 8; break;
+    default : return (-2);
+  }
+  switch (MAX(b1,b2)) {
+    case 128: m = 10; break;
+    case 192: m = 12; break;
+    case 256: m = 14; break;
+    default : return (-3);
+  }
+  bar1(a,b[m],n);
+  bar2(a,x,n);
+  return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "loop with 4 iterations completely unrolled" 2 "cunroll" } } */
+/* { dg-final { scan-tree-dump-times "loop with 8 iterations completely unrolled" 2 "cunroll" } } */
+/* { dg-final { cleanup-tree-dump "cunroll" } } */