tree-scalar-evolution.c (interpret_rhs_expr): Handle BIT_AND_EXPR.

* tree-scalar-evolution.c (interpret_rhs_expr): Handle BIT_AND_EXPR.

	* gcc.dg/tree-ssa/scev-11.c: New test.
	* gcc.dg/tree-ssa/scev-12.c: New test.

From-SVN: r235269
This commit is contained in:
Bin Cheng 2016-04-20 11:42:36 +00:00 committed by Bin Cheng
parent 6905a0499b
commit e6d62b46c8
5 changed files with 97 additions and 0 deletions

View File

@ -1,3 +1,7 @@
2016-04-20 Bin Cheng <bin.cheng@arm.com>
* tree-scalar-evolution.c (interpret_rhs_expr): Handle BIT_AND_EXPR.
2016-04-20 Marek Polacek <polacek@redhat.com>
PR tree-optimization/70725

View File

@ -1,3 +1,8 @@
2016-04-20 Bin Cheng <bin.cheng@arm.com>
* gcc.dg/tree-ssa/scev-11.c: New test.
* gcc.dg/tree-ssa/scev-12.c: New test.
2016-04-20 Marek Polacek <polacek@redhat.com>
PR tree-optimization/70725

View File

@ -0,0 +1,28 @@
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-ivopts-details" } */
int a[128];
extern int b[];
int bar (int *);
int
foo (int n)
{
int i;
for (i = 0; i < n; i++)
{
unsigned char uc = (unsigned char)i;
a[i] = i;
b[uc] = 0;
}
bar (a);
return 0;
}
/* Address of array reference to b is scev. */
/* { dg-final { scan-tree-dump-times "use \[0-9\]\n address" 2 "ivopts" } } */

View File

@ -0,0 +1,30 @@
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-ivopts-details" } */
int a[128];
extern int b[];
int bar (int *);
int
foo (int x, int n)
{
int i;
for (i = 0; i < n; i++)
{
unsigned char uc = (unsigned char)i;
if (x)
a[i] = i;
b[uc] = 0;
}
bar (a);
return 0;
}
/* Address of array reference to b is not scev. */
/* { dg-final { scan-tree-dump-times "use \[0-9\]\n address" 1 "ivopts" } } */

View File

@ -1937,6 +1937,36 @@ interpret_rhs_expr (struct loop *loop, gimple *at_stmt,
res = chrec_convert (type, chrec1, at_stmt);
break;
case BIT_AND_EXPR:
/* Given int variable A, handle A&0xffff as (int)(unsigned short)A.
If A is SCEV and its value is in the range of representable set
of type unsigned short, the result expression is a (no-overflow)
SCEV. */
res = chrec_dont_know;
if (tree_fits_uhwi_p (rhs2))
{
int precision;
unsigned HOST_WIDE_INT val = tree_to_uhwi (rhs2);
val ++;
/* Skip if value of rhs2 wraps in unsigned HOST_WIDE_INT or
it's not the maximum value of a smaller type than rhs1. */
if (val != 0
&& (precision = exact_log2 (val)) > 0
&& (unsigned) precision < TYPE_PRECISION (TREE_TYPE (rhs1)))
{
tree utype = build_nonstandard_integer_type (precision, 1);
if (TYPE_PRECISION (utype) < TYPE_PRECISION (TREE_TYPE (rhs1)))
{
chrec1 = analyze_scalar_evolution (loop, rhs1);
chrec1 = chrec_convert (utype, chrec1, at_stmt);
res = chrec_convert (TREE_TYPE (rhs1), chrec1, at_stmt);
}
}
}
break;
default:
res = chrec_dont_know;
break;