diff options
author | Christophe Lyon <christophe.lyon@linaro.org> | 2016-05-30 09:46:42 +0200 |
---|---|---|
committer | Christophe Lyon <christophe.lyon@linaro.org> | 2016-05-30 09:46:42 +0200 |
commit | 309490ea34b4e40522a6c1645ee191c1ad5f68c9 (patch) | |
tree | 27c893bae6585089b2566c029f4b3f4d2dd57c27 | |
parent | afe3fc322a7edd6a564d5a79b0ab640be227f548 (diff) |
gcc/
Backport from trunk r235269.
2016-04-20 Bin Cheng <bin.cheng@arm.com>
* tree-scalar-evolution.c (interpret_rhs_expr): Handle BIT_AND_EXPR.
gcc/testsuite/
Backport from trunk r235269.
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.
Change-Id: I7498c033cf77b8ab43ea155d599e603ffec63232
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/scev-11.c | 28 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/scev-12.c | 30 | ||||
-rw-r--r-- | gcc/tree-scalar-evolution.c | 30 |
3 files changed, 88 insertions, 0 deletions
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/scev-11.c b/gcc/testsuite/gcc.dg/tree-ssa/scev-11.c new file mode 100644 index 00000000000..a7181b2208b --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/scev-11.c @@ -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" } } */ + + diff --git a/gcc/testsuite/gcc.dg/tree-ssa/scev-12.c b/gcc/testsuite/gcc.dg/tree-ssa/scev-12.c new file mode 100644 index 00000000000..6915ba8b31d --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/scev-12.c @@ -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" } } */ + + + diff --git a/gcc/tree-scalar-evolution.c b/gcc/tree-scalar-evolution.c index 88a0eaaa82d..d6f2a2fba14 100644 --- a/gcc/tree-scalar-evolution.c +++ b/gcc/tree-scalar-evolution.c @@ -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; |