]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
match: Fix some `(op (cnd @0 @1 @2) @3)` patterns [PR123778]
authorAndrew Pinski <andrew.pinski@oss.qualcomm.com>
Fri, 23 Jan 2026 07:12:42 +0000 (23:12 -0800)
committerAndrew Pinski <andrew.pinski@oss.qualcomm.com>
Fri, 23 Jan 2026 19:17:01 +0000 (11:17 -0800)
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.

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)`, `(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 <andrew.pinski@oss.qualcomm.com>
gcc/genmatch.cc
gcc/match.pd
gcc/testsuite/gcc.dg/torture/pr123778-1.c [new file with mode: 0644]

index 1cb252229769021699ebdb6f358f60c8b9a1d56d..633ff9e1db2192b7bc0fda1879767b12cb43ab82 100644 (file)
@@ -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;
     }
 
index b66fd9022eb3708c428eb2b4b4f7da169154c251..e94e474bdc5763166189e209023e9cf5ad87dc83 100644 (file)
@@ -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.  */
@@ -6281,7 +6281,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)
@@ -6301,7 +6301,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)
@@ -6310,7 +6310,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)
@@ -8638,7 +8638,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)
@@ -8649,13 +8649,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 (file)
index 0000000..ebaa92b
--- /dev/null
@@ -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;
+}