https://gcc.gnu.org/g:649b2a6d9f9f1a29f7f26199b7b3ebbaeef3c634

commit r17-2261-g649b2a6d9f9f1a29f7f26199b7b3ebbaeef3c634
Author: Jeff Law <[email protected]>
Date:   Wed Jul 8 12:30:56 2026 -0600

    [PR rtl-optimization/126136] Fix dest = cond ? x : -1 when STORE_FLAG_VALUE 
is -1
    
    So a while back I added support for selecting x/-1 into the ifcvt.cc by 
using
    scc and a couple ALU operations.  That code explicitly rejects 
STORE_FLAG_VALUE
    if it is not 1 or -1.
    
    The "1" case has been working well.  But -1 has been buggy since inception 
--
    the affected platforms are m68k and gcn, so not getting a ton of testing.
    
    In the "1" case we have to subtract one from the output of the SCC insn to 
give
    us a 0/-1 value for T/F.  In the -1 case the SCC naturally gives us the -1
    value, so we don't need that subtract one step.  But the tense is inverted, 
ie
    -1/0 for T/F and I failed to account for the inverted tense.
    
    This patch obviously fixes the code to handle that inverted tense.
    Bootstrapped and regression tested on x86, riscv and m68k.   Pushing to the
    trunk.
    
            PR rtl-optimization/126136
    gcc/
            * ifcvt.cc (noce_try_store_flag_logical): Fix for STORE_FLAG_VALUE
            of -1.
    
    gcc/testsuite
            * gcc.dg/torture/pr126136.c: New test.

Diff:
---
 gcc/ifcvt.cc                            |  4 ++--
 gcc/testsuite/gcc.dg/torture/pr126136.c | 24 ++++++++++++++++++++++++
 2 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/gcc/ifcvt.cc b/gcc/ifcvt.cc
index 37e757461934..1df5d54efa36 100644
--- a/gcc/ifcvt.cc
+++ b/gcc/ifcvt.cc
@@ -1797,12 +1797,12 @@ noce_try_store_flag_logical (struct noce_if_info 
*if_info)
   if (!noce_simple_bbs (if_info))
     return false;
 
-  bool swapped = false;
+  bool swapped = STORE_FLAG_VALUE == -1;
   if (a == CONSTM1_RTX (GET_MODE (dest))
       && if_info->rev_cond)
     {
       std::swap (a, b);
-      swapped = true;
+      swapped = !swapped;
     }
 
   if (b != CONSTM1_RTX (GET_MODE (dest)))
diff --git a/gcc/testsuite/gcc.dg/torture/pr126136.c 
b/gcc/testsuite/gcc.dg/torture/pr126136.c
new file mode 100644
index 000000000000..cc270f51ca2d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr126136.c
@@ -0,0 +1,24 @@
+/* { dg-do run } */
+
+int i;
+
+__attribute__ ((noipa,noclone,noinline))
+char foo(char val)
+{
+  i++;
+  if (i > 1)
+    return -1;
+  else
+    return val;
+}
+
+int
+main(void)
+{
+  i = 0;
+  if (foo (10) != 10)
+    __builtin_abort ();
+  i += 2;
+  if (foo (10) != -1)
+    __builtin_abort ();
+}

Reply via email to