aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorAndrew Pinski <quic_apinski@quicinc.com>2024-07-29 11:33:58 -0700
committerAndrew Pinski <quic_apinski@quicinc.com>2024-07-31 12:26:14 -0700
commitc65653f5685a106661596a413744953ea9cdbc60 (patch)
tree641805eec8064fe471ef17f59bb16d17142d814c /gcc
parentebf4f095568e8e4af042f3e5a8cb6558888d9172 (diff)
downloadgcc-c65653f5685a106661596a413744953ea9cdbc60.zip
gcc-c65653f5685a106661596a413744953ea9cdbc60.tar.gz
gcc-c65653f5685a106661596a413744953ea9cdbc60.tar.bz2
match: Fix types matching for `(?:) !=/== (?:)` [PR116134]
The problem here is that in generic types of comparisons don't need to be boolean types (or vector boolean types). And fixes that by making sure the types of the conditions match before doing the optimization. Bootstrapped and tested on x86_64-linux-gnu with no regressions. PR middle-end/116134 gcc/ChangeLog: * match.pd (`(a ? x : y) eq/ne (b ? x : y)`): Check that a and b types match. (`(a ? x : y) eq/ne (b ? y : x)`): Likewise. gcc/testsuite/ChangeLog: * gcc.dg/torture/pr116134-1.c: New test. Signed-off-by: Andrew Pinski <quic_apinski@quicinc.com>
Diffstat (limited to 'gcc')
-rw-r--r--gcc/match.pd10
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr116134-1.c9
2 files changed, 15 insertions, 4 deletions
diff --git a/gcc/match.pd b/gcc/match.pd
index 1c86012..881a827 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -5640,12 +5640,14 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(for eqne (eq ne)
(simplify
(eqne:c (cnd @0 @1 @2) (cnd @3 @1 @2))
- (cnd (bit_xor @0 @3) { constant_boolean_node (eqne == NE_EXPR, type); }
- { constant_boolean_node (eqne != NE_EXPR, type); }))
+ (if (types_match (TREE_TYPE (@0), TREE_TYPE (@3)))
+ (cnd (bit_xor @0 @3) { constant_boolean_node (eqne == NE_EXPR, type); }
+ { constant_boolean_node (eqne != NE_EXPR, type); })))
(simplify
(eqne:c (cnd @0 @1 @2) (cnd @3 @2 @1))
- (cnd (bit_xor @0 @3) { constant_boolean_node (eqne != NE_EXPR, type); }
- { constant_boolean_node (eqne == NE_EXPR, type); }))))
+ (if (types_match (TREE_TYPE (@0), TREE_TYPE (@3)))
+ (cnd (bit_xor @0 @3) { constant_boolean_node (eqne != NE_EXPR, type); }
+ { constant_boolean_node (eqne == NE_EXPR, type); })))))
/* Canonicalize mask ? { 0, ... } : { -1, ...} to ~mask if the mask
types are compatible. */
diff --git a/gcc/testsuite/gcc.dg/torture/pr116134-1.c b/gcc/testsuite/gcc.dg/torture/pr116134-1.c
new file mode 100644
index 0000000..ab595f9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr116134-1.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+
+/* This used to ICE as comparisons on generic can be different types. */
+/* PR middle-end/116134 */
+
+int a;
+int b;
+int d;
+void c() { 1UL <= (d < b) != (1UL & (0 < a | 0L)); }