https://gcc.gnu.org/g:8371e7f240c1130a3827be1afb94f73c26df81a6

commit r15-7740-g8371e7f240c1130a3827be1afb94f73c26df81a6
Author: Jakub Jelinek <ja...@redhat.com>
Date:   Thu Feb 27 22:11:51 2025 +0100

    gimple-fold: Fix a pasto in fold_truth_andor_for_ifcombine [PR119030]
    
    The following testcase is miscompiled since r15-7597.
    The left comparison is unsigned (x & 0x8000U) != 0) while the
    right one is signed (x >> 16) >= 0 and is actually a signbit test,
    so rsignbit is 64.
    After debugging this and reading the r15-7597 change, I believe there
    is just a pasto, the if (lsignbit) and if (rsignbit) blocks are pretty
    much identical with just the first l on all variables starting with l
    replaced with r (the only difference is that if (lsignbit) has a comment
    explaining the sign <<= 1; stuff, while it isn't repeated in the second one.
    Except the second one was using ll_unsignedp instead of rl_unsignedp
    in one spot.  I think it should use the latter, the signedness of the left
    comparison doesn't affect the other one, they are basically independent
    with the exception that we check that after transformations they are both
    EQ or both NE and later on we try to merge them together.
    
    2025-02-27  Jakub Jelinek  <ja...@redhat.com>
    
            PR tree-optimization/119030
            * gimple-fold.cc (fold_truth_andor_for_ifcombine): Fix a pasto,
            ll_unsignedp -> rl_unsignedp.
    
            * gcc.c-torture/execute/pr119030.c: New test.

Diff:
---
 gcc/gimple-fold.cc                             |  2 +-
 gcc/testsuite/gcc.c-torture/execute/pr119030.c | 26 ++++++++++++++++++++++++++
 2 files changed, 27 insertions(+), 1 deletion(-)

diff --git a/gcc/gimple-fold.cc b/gcc/gimple-fold.cc
index 0380c7af4c21..b64561396874 100644
--- a/gcc/gimple-fold.cc
+++ b/gcc/gimple-fold.cc
@@ -8313,7 +8313,7 @@ fold_truth_andor_for_ifcombine (enum tree_code code, tree 
truth_type,
   if (rsignbit)
     {
       wide_int sign = wi::mask (rl_bitsize - 1, true, rl_bitsize);
-      if (rsignbit > rl_bitsize && ll_unsignedp)
+      if (rsignbit > rl_bitsize && rl_unsignedp)
        sign <<= 1;
       if (!rl_and_mask.get_precision ())
        rl_and_mask = sign;
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr119030.c 
b/gcc/testsuite/gcc.c-torture/execute/pr119030.c
new file mode 100644
index 000000000000..8964bac617bc
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr119030.c
@@ -0,0 +1,26 @@
+/* PR tree-optimization/119030 */
+
+static inline unsigned
+foo (long long x)
+{
+  return x & 0x8000;
+}
+
+static inline long long
+bar (long long x)
+{
+  if (foo (x))
+    return -1000L;
+  else
+    return x >> 16;
+}
+
+long long x = -0x20000LL;
+
+int
+main ()
+{
+  if (bar (x) >= 0)
+    __builtin_abort ();
+  return 0;
+}

Reply via email to