From 42c6b3cadd77829763b2a1484c5cfa50a9524b1f Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Thu, 15 Jan 2015 15:02:11 +0000 Subject: [PATCH] re PR tree-optimization/61743 (Complete unroll is not happened for loops with short upper bound) 2015-01-15 Richard Biener 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 | 6 +++ gcc/testsuite/ChangeLog | 6 +++ gcc/testsuite/gcc.dg/tree-ssa/pr61743-1.c | 53 +++++++++++++++++++++++ gcc/testsuite/gcc.dg/tree-ssa/pr61743-2.c | 53 +++++++++++++++++++++++ gcc/tree-ssa-pre.c | 27 ++++++++++++ 5 files changed, 145 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr61743-1.c create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr61743-2.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 21d6a8809f1..da62dae337c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2015-01-15 Richard Biener + + 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 * config/arm/arm.md (generic_sched): Specify xgene1 in 'no' list. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 04a43c502f0..8a5cf7e1c6f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2015-01-15 Richard Biener + + 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 * 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 index 00000000000..de09daa28a8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr61743-1.c @@ -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" } } */ 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 index 00000000000..c8a43914d12 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr61743-2.c @@ -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" } } */ diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c index 3ef7510df66..32cd74dd3bb 100644 --- a/gcc/tree-ssa-pre.c +++ b/gcc/tree-ssa-pre.c @@ -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 "); -- 2.30.2