https://gcc.gnu.org/g:44c5f9a37aa3dffac654c743147021df917daab0
commit r17-761-g44c5f9a37aa3dffac654c743147021df917daab0 Author: Andrew Pinski <[email protected]> Date: Mon May 25 12:44:48 2026 -0700 match: Fix up `(smaller)a ==/!= (smaller) b` pattern for pointers [PR125453] While reviewing r17-632-g1c9808a71207eb, I missed that it was valid (in gimple) to cast from a pointer to a smaller integral type. That meant with that pattern we would get `ptr ^ ptr` which is invalid gimple. This adds a check for integral type before applying this pattern. Pushed as obvious after a bootstrap/test on x86_64-linux-gnu. PR tree-optimization/125453 gcc/ChangeLog: * match.pd (`(smaller)a ==/!= (smaller) b`): Reject non integral types. gcc/testsuite/ChangeLog: * gcc.dg/torture/pr125453-1.c: New test. Signed-off-by: Andrew Pinski <[email protected]> Diff: --- gcc/match.pd | 5 +++-- gcc/testsuite/gcc.dg/torture/pr125453-1.c | 36 +++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/gcc/match.pd b/gcc/match.pd index 0be4eff818b2..8a2de136e7f1 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -7817,8 +7817,9 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) /* For eq/ne with narrowing conversion: (T)(X) == (T)(Y) -> (T)(X ^ Y) == 0 */ - (if (TYPE_PRECISION (TREE_TYPE (@0)) - < TYPE_PRECISION (TREE_TYPE (@00)) + (if (INTEGRAL_TYPE_P (TREE_TYPE (@00)) + && (TYPE_PRECISION (TREE_TYPE (@0)) + < TYPE_PRECISION (TREE_TYPE (@00))) && (cmp == EQ_EXPR || cmp == NE_EXPR) && types_match (TREE_TYPE (@00), TREE_TYPE (@10))) diff --git a/gcc/testsuite/gcc.dg/torture/pr125453-1.c b/gcc/testsuite/gcc.dg/torture/pr125453-1.c new file mode 100644 index 000000000000..d4ee478253de --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr125453-1.c @@ -0,0 +1,36 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-fgimple" } */ +/* PR tree-optimization/125453 */ + +int b[10]; + +_Bool __GIMPLE f(int *c) +{ + unsigned t; + unsigned t1; + int t2; + _Bool t3; + t = (unsigned)c; + t1 = (unsigned)_Literal (char *)&b; + t = t - t1; + t2 = (int)t; + t3 = t2 != 0; + return t3; +} + + + +int g1(void); +int f1(const char *); + +void h(void) { + char b[1], *c; + int d, e; + for (d = 0, c = b; d < 3; d++, c++) { + g1(); + if (d && e) + break; + } + *c = '\0'; + f1(b); +}
