re PR tree-optimization/61743 (Complete unroll is not happened for loops with short upper bound)

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
This commit is contained in:
Richard Biener 2015-01-15 15:02:11 +00:00 committed by Richard Biener
parent cd3246ea58
commit 42c6b3cadd
5 changed files with 145 additions and 0 deletions

View 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.

View 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.

View File

@ -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" } } */

View File

@ -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" } } */

View 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 ");