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)` 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