> Am 23.01.2026 um 16:53 schrieb Andrew Pinski <[email protected]>:
> 
> All of these patterns have in common is they try to move
> the op inside the cnd if it simplifies. The problem is the
> type of the op does not need to be the type of first operand
> and instead is the type of the type variable. The fix is to
> supply the type to the op like in `(op:type @1 @3)`.
> But since they were originally in the `(op! @1 @3)`, it should be:
> `(op!:type @1 @3)`. Though this would be rejected as we don't pick
> up the next token after parsing the `!` (note `^` has the same issue
> which is also fixed here too).
> 
> Bootstrapped and tested on x86_64-linux-gnu.

Ok

Richard 

>    PR tree-optimization/123778
> 
> gcc/ChangeLog:
> 
>    * genmatch.cc (parser::parse_expr): Peek on the next
>    token after eating the `!` or `^`.
>    * match.pd (`(op (cnd @0 @1 @2) @3)` and `(op @3 (cnd @0 @1 @2))`:
>    Add the type to resulting op.
> 
> gcc/testsuite/ChangeLog:
> 
>    * gcc.dg/torture/pr123778-1.c: New test.
> 
> Signed-off-by: Andrew Pinski <[email protected]>
> ---
> gcc/genmatch.cc                           |  2 ++
> gcc/match.pd                              | 14 +++++++-------
> gcc/testsuite/gcc.dg/torture/pr123778-1.c | 20 ++++++++++++++++++++
> 3 files changed, 29 insertions(+), 7 deletions(-)
> create mode 100644 gcc/testsuite/gcc.dg/torture/pr123778-1.c
> 
> diff --git a/gcc/genmatch.cc b/gcc/genmatch.cc
> index 1cb25222976..633ff9e1db2 100644
> --- a/gcc/genmatch.cc
> +++ b/gcc/genmatch.cc
> @@ -5435,6 +5435,7 @@ parser::parse_expr ()
>       && !(token->flags & PREV_WHITE))
>     {
>       eat_token (CPP_NOT);
> +      token = peek ();
>       e->force_leaf = true;
>     }
> 
> @@ -5447,6 +5448,7 @@ parser::parse_expr ()
>    fatal_at (token, "modifier %<^%> can only act on operation %<COND_EXPR%>");
> 
>       eat_token (CPP_XOR);
> +      token = peek ();
>       e->match_phi = true;
>     }
> 
> diff --git a/gcc/match.pd b/gcc/match.pd
> index e0a2399ca65..d1a7956e531 100644
> --- a/gcc/match.pd
> +++ b/gcc/match.pd
> @@ -6242,7 +6242,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
> (for op (negate bit_not abs absu)
>  (simplify
>   (op (vec_cond:s @0 @1 @2))
> -  (vec_cond @0 (op! @1) (op! @2))))
> +  (vec_cond @0 (op!:type @1) (op!:type @2))))
> 
> /* Sink unary conversions to branches, but only if we do fold both
>    and the target's truth type is the same as we already have.  */
> @@ -6277,7 +6277,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
>          missing the legacy vcond{,u,eq} cases.  Do this only when
>          lowering will be able to fixup..  */
>           && !expand_vec_cond_expr_p (TREE_TYPE (@1), TREE_TYPE (@0)))))
> -   (vec_cond @0 (op! @1 @3) (op! @2 @4))))
> +   (vec_cond @0 (op!:type @1 @3) (op!:type @2 @4))))
> 
> /* (@0 ? @2 : @3) lop (@1 ? @2 : @3)  -->  (@0 lop @1) ? @2 : @3.  */
> (for lop (bit_and bit_ior bit_xor)
> @@ -6297,7 +6297,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
>       || expand_vec_cond_expr_p (type, TREE_TYPE (@0))
>       || (optimize_vectors_before_lowering_p ()
>           && !expand_vec_cond_expr_p (TREE_TYPE (@1), TREE_TYPE (@0)))))
> -   (vec_cond @0 (op! @1 @3) (op! @2 @3))))
> +   (vec_cond @0 (op!:type @1 @3) (op!:type @2 @3))))
>  (simplify
>   (op @3 (vec_cond:s @0 @1 @2))
>   (if (VECTOR_TYPE_P (type)
> @@ -6306,7 +6306,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
>       || expand_vec_cond_expr_p (type, TREE_TYPE (@0))
>       || (optimize_vectors_before_lowering_p ()
>           && !expand_vec_cond_expr_p (TREE_TYPE (@1), TREE_TYPE (@0)))))
> -   (vec_cond @0 (op! @3 @1) (op! @3 @2)))))
> +   (vec_cond @0 (op!:type @3 @1) (op!:type @3 @2)))))
> 
> #if GIMPLE
> (match (nop_atomic_bit_test_and_p @0 @1 @4)
> @@ -8634,7 +8634,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
>      pessimizes code and causes gimplification issues when applied late.  */
>   (if (!FLOAT_TYPE_P (TREE_TYPE (@3))
>        || !operation_could_trap_p (cmp, true, false, @3))
> -   (cond @0 (cmp! @1 @3) (cmp! @2 @3)))))
> +   (cond @0 (cmp!:type @1 @3) (cmp!:type @2 @3)))))
> 
> /* Similar to above:
>    (c ? a : b) op d  ->  c ? (a op d) : (b op d)
> @@ -8645,13 +8645,13 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
>     lrotate rrotate mult_highpart)
>  (simplify
>   (op (cond @0 @1 @2) @3)
> -  (cond @0 (op! @1 @3) (op! @2 @3)))
> +  (cond @0 (op!:type @1 @3) (op!:type @2 @3)))
> 
>  /* Support the variant
>     d op (c ? a : b)  ->  c ? (d op a) : (d op b)  */
>  (simplify
>   (op @3 (cond @0 @1 @2))
> -  (cond @0 (op! @3 @1) (op! @3 @2))))
> +  (cond @0 (op!:type @3 @1) (op!:type @3 @2))))
> #endif
> 
> /* Transform comparisons of the form (X & Y) CMP 0 to X CMP2 Z
> diff --git a/gcc/testsuite/gcc.dg/torture/pr123778-1.c 
> b/gcc/testsuite/gcc.dg/torture/pr123778-1.c
> new file mode 100644
> index 00000000000..ebaa92b76b3
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/torture/pr123778-1.c
> @@ -0,0 +1,20 @@
> +/* { dg-do compile } */
> +/* { dg-options "-fgimple" } */
> +
> +/* PR tree-optimization/123778 */
> +
> +typedef char (*t)[3];
> +long __GIMPLE(ssa) f(char a, int d)
> +{
> +  _Bool _107;
> +  __PTRDIFF_TYPE__ _14;
> +  char *_36;
> +
> +__BB(2):
> +  _107 = a_2(D) != _Literal (char) 0;
> +  _36 = _107
> +      ? _Literal (t)&__MEM <char[3]> ((void *)_Literal (t)&d + _Literal 
> (void *) 2)
> +      : _Literal (t)&__MEM <char[3]> ((void *)_Literal (t)&d + _Literal 
> (void *) 3);
> +  _14 = _36 - _Literal (char*)&d;
> +  return _14;
> +}
> --
> 2.43.0
> 

Reply via email to