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)

Reply via email to