On Wed, 14 Sep 2022, Jakub Jelinek wrote:

> Hi!
> 
> My change to match.pd (that added the two simplifications this patch
> touches) results in more |/^/& assignments with pointer arguments,
> but since r12-1608 we reject pointer operands for BIT_NOT_EXPR.
> 
> Disallowing them for BIT_NOT_EXPR and allowing for BIT_{IOR,XOR,AND}_EXPR
> leads to a match.pd maintainance nightmare (see one of the patches in the
> PR), so either we want to allow pointer operand on BIT_NOT_EXPR (but then
> we run into issues e.g. with the ranger which expects it can emulate
> BIT_NOT_EXPR ~X as - 1 - X which doesn't work for pointers which don't
> support MINUS_EXPR), or the following patch disallows pointer arguments
> for all of BIT_{IOR,XOR,AND}_EXPR with the exception of BIT_AND_EXPR
> with INTEGER_CST last operand (for simpler pointer realignment).
> I had to tweak one reassoc optimization and the two match.pd
> simplifications.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

OK.

Did you check what breaks when we reverse the decision to allow
BIT_AND_EXPR to align pointers alltogether?  I think we don't
have any

 (T')(((T)ptr) & CST) -> ptr & CST

folding at least.  But I guess some passes that build pointer
re-alignments might need adjustment.

> P.S.: I know it would be better for the verifiers to have positive
> set of types it wants to allow for each operation, but I have no idea
> what exactly we use there right now.

I think for BIT_*_EXPR we want ANY_INTEGRAL_TYPE_P (well, likely
not complex int, but ...).  So if a patch to check that passes
bootstrap that would be nice to have.

Richard.

> 2022-09-14  Jakub Jelinek  <ja...@redhat.com>
> 
>       PR tree-optimization/106878
>       * tree-cfg.cc (verify_gimple_assign_binary): Disallow pointer,
>       reference or OFFSET_TYPE BIT_IOR_EXPR, BIT_XOR_EXPR or, unless
>       the second argument is INTEGER_CST, BIT_AND_EXPR.
>       * match.pd ((type) X op CST -> (type) (X op ((type-x) CST)),
>       (type) (((type2) X) op Y) -> (X op (type) Y)): Punt for
>       POINTER_TYPE_P or OFFSET_TYPE.
>       * tree-ssa-reassoc.cc (optimize_range_tests_cmp_bitwise): For
>       pointers cast them to pointer sized integers first.
> 
>       * gcc.c-torture/compile/pr106878.c: New test.
> 
> --- gcc/tree-cfg.cc.jj        2022-09-08 20:22:07.788184491 +0200
> +++ gcc/tree-cfg.cc   2022-09-13 09:28:53.563243962 +0200
> @@ -4167,6 +4167,8 @@ verify_gimple_assign_binary (gassign *st
>      case ROUND_MOD_EXPR:
>      case RDIV_EXPR:
>      case EXACT_DIV_EXPR:
> +    case BIT_IOR_EXPR:
> +    case BIT_XOR_EXPR:
>        /* Disallow pointer and offset types for many of the binary gimple. */
>        if (POINTER_TYPE_P (lhs_type)
>         || TREE_CODE (lhs_type) == OFFSET_TYPE)
> @@ -4182,9 +4184,23 @@ verify_gimple_assign_binary (gassign *st
>  
>      case MIN_EXPR:
>      case MAX_EXPR:
> -    case BIT_IOR_EXPR:
> -    case BIT_XOR_EXPR:
> +      /* Continue with generic binary expression handling.  */
> +      break;
> +
>      case BIT_AND_EXPR:
> +      if (POINTER_TYPE_P (lhs_type)
> +       && TREE_CODE (rhs2) == INTEGER_CST)
> +     break;
> +      /* Disallow pointer and offset types for many of the binary gimple. */
> +      if (POINTER_TYPE_P (lhs_type)
> +       || TREE_CODE (lhs_type) == OFFSET_TYPE)
> +     {
> +       error ("invalid types for %qs", code_name);
> +       debug_generic_expr (lhs_type);
> +       debug_generic_expr (rhs1_type);
> +       debug_generic_expr (rhs2_type);
> +       return true;
> +     }
>        /* Continue with generic binary expression handling.  */
>        break;
>  
> --- gcc/match.pd.jj   2022-09-08 20:22:00.836276502 +0200
> +++ gcc/match.pd      2022-09-13 10:21:04.567853941 +0200
> @@ -1763,6 +1763,8 @@ (define_operator_list SYNC_FETCH_AND_AND
>        && (int_fits_type_p (@1, TREE_TYPE (@0))
>            || tree_nop_conversion_p (TREE_TYPE (@0), type)))
>       || types_match (@0, @1))
> +       && !POINTER_TYPE_P (TREE_TYPE (@0))
> +       && TREE_CODE (TREE_TYPE (@0)) != OFFSET_TYPE
>         /* ???  This transform conflicts with fold-const.cc doing
>         Convert (T)(x & c) into (T)x & (T)c, if c is an integer
>         constants (if x has signed type, the sign bit cannot be set
> @@ -1799,7 +1801,9 @@ (define_operator_list SYNC_FETCH_AND_AND
>    (if (GIMPLE
>         && TREE_CODE (@1) != INTEGER_CST
>         && tree_nop_conversion_p (type, TREE_TYPE (@2))
> -       && types_match (type, @0))
> +       && types_match (type, @0)
> +       && !POINTER_TYPE_P (TREE_TYPE (@0))
> +       && TREE_CODE (TREE_TYPE (@0)) != OFFSET_TYPE)
>     (bitop @0 (convert @1)))))
>  
>  (for bitop (bit_and bit_ior)
> --- gcc/tree-ssa-reassoc.cc.jj        2022-06-28 13:03:31.292684917 +0200
> +++ gcc/tree-ssa-reassoc.cc   2022-09-13 10:18:27.466085947 +0200
> @@ -3608,10 +3608,14 @@ optimize_range_tests_cmp_bitwise (enum t
>       tree type2 = NULL_TREE;
>       bool strict_overflow_p = false;
>       candidates.truncate (0);
> +     if (POINTER_TYPE_P (type1))
> +       type1 = pointer_sized_int_node;
>       for (j = i; j; j = chains[j - 1])
>         {
>           tree type = TREE_TYPE (ranges[j - 1].exp);
>           strict_overflow_p |= ranges[j - 1].strict_overflow_p;
> +         if (POINTER_TYPE_P (type))
> +           type = pointer_sized_int_node;
>           if ((b % 4) == 3)
>             {
>               /* For the signed < 0 cases, the types should be
> @@ -3642,6 +3646,8 @@ optimize_range_tests_cmp_bitwise (enum t
>           tree type = TREE_TYPE (ranges[j - 1].exp);
>           if (j == k)
>             continue;
> +         if (POINTER_TYPE_P (type))
> +           type = pointer_sized_int_node;
>           if ((b % 4) == 3)
>             {
>               if (!useless_type_conversion_p (type1, type))
> @@ -3671,7 +3677,7 @@ optimize_range_tests_cmp_bitwise (enum t
>               op = r->exp;
>               continue;
>             }
> -         if (id == l)
> +         if (id == l || POINTER_TYPE_P (TREE_TYPE (op)))
>             {
>               code = (b % 4) == 3 ? BIT_NOT_EXPR : NOP_EXPR;
>               g = gimple_build_assign (make_ssa_name (type1), code, op);
> @@ -3695,6 +3701,14 @@ optimize_range_tests_cmp_bitwise (enum t
>           gimple_seq_add_stmt_without_update (&seq, g);
>           op = gimple_assign_lhs (g);
>         }
> +     type1 = TREE_TYPE (ranges[k - 1].exp);
> +     if (POINTER_TYPE_P (type1))
> +       {
> +         gimple *g
> +           = gimple_build_assign (make_ssa_name (type1), NOP_EXPR, op);
> +         gimple_seq_add_stmt_without_update (&seq, g);
> +         op = gimple_assign_lhs (g);
> +       }
>       candidates.pop ();
>       if (update_range_test (&ranges[k - 1], NULL, candidates.address (),
>                              candidates.length (), opcode, ops, op,
> --- gcc/testsuite/gcc.c-torture/compile/pr106878.c.jj 2022-09-13 
> 10:21:04.567853941 +0200
> +++ gcc/testsuite/gcc.c-torture/compile/pr106878.c    2022-09-13 
> 10:21:04.567853941 +0200
> @@ -0,0 +1,15 @@
> +/* PR tree-optimization/106878 */
> +
> +typedef __INTPTR_TYPE__ intptr_t;
> +typedef __UINTPTR_TYPE__ uintptr_t;
> +int a;
> +
> +int
> +foo (const int *c)
> +{
> +  uintptr_t d = ((intptr_t) c | (intptr_t) &a) & 65535 << 16;
> +  intptr_t e = (intptr_t) c;
> +  if (d != (e & 65535 << 16))
> +    return 1;
> +  return 0;
> +}
> 
>       Jakub
> 
> 

-- 
Richard Biener <rguent...@suse.de>
SUSE Software Solutions Germany GmbH, Frankenstrasse 146, 90461 Nuernberg,
Germany; GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman;
HRB 36809 (AG Nuernberg)

Reply via email to