On Wed, Apr 20, 2016 at 9:55 AM, Richard Biener <richard.guent...@gmail.com> wrote: > On Tue, Apr 19, 2016 at 7:00 PM, Bin Cheng <bin.ch...@arm.com> wrote: >> Hi, >> Type conversion from integer to smaller unsigned type could be transformed >> into BIT_AND_EXPR in compilation. For example, >> int i; >> for (i = 0; i < n; i++) >> { >> unsigned char uc = (unsigned char) i; // transformed into X = i && >> 255, in which both X and i are of int type. >> b[uc] = 0; >> } >> X here could a valid SCEV if we can prove that loop doesn't iterate more >> than 255 times. In other words, if 'i' is SCEV and its value is in the >> range of representable set of type "unsigned char". This information could >> be available with -faggressive-loop-optimizations. >> This patch adds support for BIT_AND_EXPR in scalar evolution to handle such >> cases, as well as two new tests. >> >> Bootstrap and test on x86_64 & AArch64. Is it OK? > > Don't use cst_and_fits_in_hwi/int_cst_value - those are odd beasts. > Use tree_fits_uhwi_p / tree_to_uhwi. > Or just use wi::popcount and verify it against wi::clz. Thanks for reviewing, here is the updated patch. Regtest ongoing, shouldn't be any surprise though. Is it OK?
Thanks, bin > > Richard. > >> Thanks, >> bin >> >> 2016-03-24 Bin Cheng <bin.ch...@arm.com> >> >> * tree-scalar-evolution.c (interpret_rhs_expr): Handle BIT_AND_EXPR. >> >> gcc/testsuite/ChangeLog >> 2016-03-24 Bin Cheng <bin.ch...@arm.com> >> >> * gcc.dg/tree-ssa/scev-11.c: New test. >> * gcc.dg/tree-ssa/scev-12.c: New test. >>
diff --git a/gcc/tree-scalar-evolution.c b/gcc/tree-scalar-evolution.c index 88a0eaa..d6f2a2f 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; 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 0000000..a7181b2 --- /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 0000000..6915ba8 --- /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" } } */ + + +