This fixes $subject and also "foo" != "bar" folding which was somehow missing. It fixes only parts of the PR since the PR is about PTA tracking string constants.
It might help PR88775 but unless I can confirm that this is just queued for GCC10. You might notice I'm treating string merging possibilities conservatively (defer to runtime). Bootstrapped and tested on x86_64-unknown-linux-gnu. Richard. >From 8f14bac370b8334a42f985027394e9f3fdf9e2f1 Mon Sep 17 00:00:00 2001 From: Richard Guenther <rguent...@suse.de> Date: Thu, 10 Jan 2019 10:24:20 +0100 Subject: [PATCH] fix-pr87314-1 2019-01-10 Richard Biener <rguent...@suse.de> PR middle-end/87314 * match.pd (cmp (convert1?@2 addr@0) (convert2? addr@1)): Handle STRING_CST vs DECL or STRING_CST. * gcc.dg/pr87314-1.c: New testcase. diff --git a/gcc/match.pd b/gcc/match.pd index 60b12f94f9e..95fa4e4a4dd 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -3896,6 +3896,9 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) || TREE_CODE (base1) == SSA_NAME || TREE_CODE (base1) == STRING_CST)) equal = (base0 == base1); + HOST_WIDE_INT ioff0 = -1, ioff1 = -1; + off0.is_constant (&ioff0); + off1.is_constant (&ioff1); } (if (equal == 1 && (cmp == EQ_EXPR || cmp == NE_EXPR @@ -3919,10 +3922,23 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (if (cmp == GT_EXPR && (known_gt (off0, off1) || known_le (off0, off1))) { constant_boolean_node (known_gt (off0, off1), type); })) (if (equal == 0 - && DECL_P (base0) && DECL_P (base1) - /* If we compare this as integers require equal offset. */ - && (!INTEGRAL_TYPE_P (TREE_TYPE (@2)) - || known_eq (off0, off1))) + && ((DECL_P (base0) && DECL_P (base1) + /* If we compare this as integers require equal offset. */ + && (!INTEGRAL_TYPE_P (TREE_TYPE (@2)) + || known_eq (off0, off1))) + || (DECL_P (base0) && TREE_CODE (base1) == STRING_CST) + || (TREE_CODE (base0) == STRING_CST && DECL_P (base1)) + || (TREE_CODE (base0) == STRING_CST + && TREE_CODE (base1) == STRING_CST + && ioff0 >= 0 && ioff1 >= 0 + && ioff0 < TREE_STRING_LENGTH (base0) + && ioff1 < TREE_STRING_LENGTH (base1) + /* This is a too conservative test that the STRING_CSTs + will not end up being string-merged. */ + && strncmp (TREE_STRING_POINTER (base0) + ioff0, + TREE_STRING_POINTER (base1) + ioff1, + MIN (TREE_STRING_LENGTH (base0) - ioff0, + TREE_STRING_LENGTH (base1) - ioff1)) != 0))) (switch (if (cmp == EQ_EXPR) { constant_boolean_node (false, type); }) diff --git a/gcc/testsuite/gcc.dg/pr87314-1.c b/gcc/testsuite/gcc.dg/pr87314-1.c new file mode 100644 index 00000000000..4dc85c8eee6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr87314-1.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fdump-tree-original" } */ + +int f(){ int a; return &a==(void *)"hello"; } +int g(){ return "bye"=="hello"; } +int h() { return "bye"=="hellobye"+5; } + +/* { dg-final { scan-tree-dump-times "hello" 1 "original" } } */ +/* The test in h() should be retained because the result depends on + string merging. */ +/* { dg-final { scan-assembler "hello" } } */