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)