On Wed, 28 Aug 2024, Richard Biener wrote: > When evaluating the difference of two aligned pointers in CCP we > fail to handle the EXACT_DIV_EXPR by the element size that occurs. > The testcase then also exercises modulo to test alignment but > modulo by a power-of-two isn't handled either. > > Re-bootstrap and regtest running on x86_64-unknown-linux-gnu after > an adjustment. I'd appreciate a second eye.
Now pushed as r15-3548-ge7d5b9aa021f6f after re-testing on x86_64-unknown-linux-gnu. Richard. > Thanks, > Richard. > > PR tree-optimization/116514 > * tree-ssa-ccp.cc (bit_value_binop): Handle EXACT_DIV_EXPR > like TRUNC_DIV_EXPR. Handle exact division of a signed value > by a power-of-two like a shift. Handle unsigned division by > a power-of-two like a shift. > Handle unsigned TRUNC_MOD_EXPR by power-of-two, handle signed > TRUNC_MOD_EXPR by power-of-two if the result is zero. > > * gcc.dg/tree-ssa/ssa-ccp-44.c: New testcase. > --- > gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-44.c | 13 +++++++++++ > gcc/tree-ssa-ccp.cc | 27 +++++++++++++++++++++- > 2 files changed, 39 insertions(+), 1 deletion(-) > create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-44.c > > diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-44.c > b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-44.c > new file mode 100644 > index 00000000000..f1f09bfb117 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-44.c > @@ -0,0 +1,13 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O -fdump-tree-ccp1" } */ > + > +int > +test(int* a, int* b) > +{ > + __INTPTR_TYPE__ delta = (int*)__builtin_assume_aligned(b, 32) > + - (int*)__builtin_assume_aligned(a, 32); > + __INTPTR_TYPE__ x = delta % 8; > + return (x == 0); > +} > + > +/* { dg-final { scan-tree-dump "return 1;" "ccp1" } } */ > diff --git a/gcc/tree-ssa-ccp.cc b/gcc/tree-ssa-ccp.cc > index 44711018e0e..8cd45545763 100644 > --- a/gcc/tree-ssa-ccp.cc > +++ b/gcc/tree-ssa-ccp.cc > @@ -1921,6 +1921,27 @@ bit_value_binop (enum tree_code code, signop sgn, int > width, > { > widest_int r1max = r1val | r1mask; > widest_int r2max = r2val | r2mask; > + if (r2mask == 0) > + { > + widest_int shift = wi::exact_log2 (r2val); > + if (shift != -1) > + { > + // Handle modulo by a power of 2 as a bitwise and. > + widest_int tem_val, tem_mask; > + bit_value_binop (BIT_AND_EXPR, sgn, width, &tem_val, &tem_mask, > + r1type_sgn, r1type_precision, r1val, r1mask, > + r2type_sgn, r2type_precision, > + r2val - 1, r2mask); > + if (sgn == UNSIGNED > + || !wi::neg_p (r1max) > + || (tem_mask == 0 && tem_val == 0)) > + { > + *val = tem_val; > + *mask = tem_mask; > + return; > + } > + } > + } > if (sgn == UNSIGNED > || (!wi::neg_p (r1max) && !wi::neg_p (r2max))) > { > @@ -1949,11 +1970,15 @@ bit_value_binop (enum tree_code code, signop sgn, int > width, > } > break; > > + case EXACT_DIV_EXPR: > case TRUNC_DIV_EXPR: > { > widest_int r1max = r1val | r1mask; > widest_int r2max = r2val | r2mask; > - if (r2mask == 0 && !wi::neg_p (r1max)) > + if (r2mask == 0 > + && (code == EXACT_DIV_EXPR > + || sgn == UNSIGNED > + || !wi::neg_p (r1max))) > { > widest_int shift = wi::exact_log2 (r2val); > if (shift != -1) > -- Richard Biener <rguent...@suse.de> SUSE Software Solutions Germany GmbH, Frankenstrasse 146, 90461 Nuernberg, Germany; GF: Ivo Totev, Andrew McDonald, Werner Knoblich; (HRB 36809, AG Nuernberg)