[This was actually pushed with the other v850 patch by accident... ]

So the LLM checker chewed on v850.md for a bit and spit out about 3 dozen issues.  I took one that seemed likely to be a code generation bug, the LLM claimed we were missing a condition code clobber on two of the single bit manipulation instructions.  It was trivial to review the V8 docs and conclude yes, this is likely a real problem.

I made a cross compiler available to the LLM and asked it to spit out a testcase which it did which it verified by looking at the .combine dumps (to see the pattern being used), the sched2 dump to see it get reordered in such a way as to expose the bug, then the final assembly code which looked wrong by inspection.  Then I told the LLM about the simulator and it was able to see the undesirable behavior at runtime which it could toggle on/off via -fno-schedule-insns2.  Not bad.

This patch fixes the bug by adding the missing clobbers.  It's possible we could be more surgical here since those instructions just change the Z bit, but full clobber is obviously safe.  It's not likely worth the effort to be more surgical.

Assisted-By: Claude for review of v850.md and testcase generation.

Regression tested on v850e-elf and pushed to the trunk.

Jeff
commit b31c358dd66fda84de3eb55e5d5924dfda8dc68a
Author: Jeff Law <[email protected]>
Date:   Sun Oct 25 22:05:23 2026 -0600

    [V850] Fix length computation for branches in V850 port
    
    Here's another bug caught by the LLM.
    
    In the E3V5 and newer V850 variants, the range of conditional branches 
extended
    from 8 to 17 bits. The conditional branch sequences were updated to account 
for
    that, except they mucked things up on the older targets.
    
    Essentially the output C fragment selects the sequence based on the length 
of
    the insn
    
    2 bytes -- short conditional
    4 bytes -- E3V5 long conditional
    6 bytes -- short inverted conditional around "jr"
    
    But the length computation just assumed that the long conditional forms were
    always available.
    
    It looks like we're testing base, along with the E3V5 variants, so I can 
only
    assume that the assembler isn't strict enough and that it's likely using the
    E3V5 instruction, even on base variants.  Similarly for the simulator.  If
    either of those were not true, I would expect massive failures from the
    testsuite.
    
    Anyway, the fix is simple, verify we have the E3V5 variant or newer in the
    length computation before returning "4".
    
    Regression tested on v850e-elf with no regressions or improvements to 
existing
    tests.  I'm still working through RISC-V bugs in that LLM based tester, but 
I
    wanted to see what it would do if I through another port's MD file at it.
    
    Assisted by: Claude for review of v850.md and testcase generation.
    
    gcc/
            * config/v850/v850.md (conditional branch patterns): Fix length
            computation for designs without long conditional branches.
    
    gcc/testsuite
            * gcc.target/v850/min_bit.c: New test.

diff --git a/gcc/config/v850/v850.md b/gcc/config/v850/v850.md
index 304477629db..a64d5452e57 100644
--- a/gcc/config/v850/v850.md
+++ b/gcc/config/v850/v850.md
@@ -831,7 +831,8 @@
 (define_insn "*v850_set1_2"
   [(set (match_operand:HI 0 "indirect_operand" "=m")
        (subreg:HI (ior:SI (subreg:SI (match_dup 0) 0)
-                          (match_operand 1 "power_of_two_operand" "")) 0))]
+                          (match_operand 1 "power_of_two_operand" "")) 0))
+   (clobber (reg:CC CC_REGNUM))]
   ""
 {
   int log2 = exact_log2 (INTVAL (operands[1]));
@@ -930,7 +931,8 @@
 (define_insn "*v850_not1_2"
   [(set (match_operand:HI 0 "indirect_operand" "=m")
        (subreg:HI (xor:SI (subreg:SI (match_dup 0) 0)
-                          (match_operand 1 "power_of_two_operand" "")) 0))]
+                          (match_operand 1 "power_of_two_operand" "")) 0))
+   (clobber (reg:CC CC_REGNUM))]
   ""
 {
   int log2 = exact_log2 (INTVAL (operands[1]));
@@ -1533,8 +1535,9 @@
     (if_then_else (lt (abs (minus (match_dup 0) (pc)))
                      (const_int 256))
                  (const_int 2)
-                 (if_then_else (lt (abs (minus (match_dup 0) (pc)))
-                     (const_int 65536))
+                 (if_then_else (and (match_test "TARGET_V850E3V5_UP")
+                                    (lt (abs (minus (match_dup 0) (pc)))
+                                        (const_int 65536)))
                      (const_int 4)
                      (const_int 6))))])
 
@@ -1573,8 +1576,9 @@
     (if_then_else (lt (abs (minus (match_dup 0) (pc)))
                      (const_int 256))
                  (const_int 2)
-                 (if_then_else (lt (abs (minus (match_dup 0) (pc)))
-                     (const_int 65536))
+                 (if_then_else (and (match_test "TARGET_V850E3V5_UP")
+                                    (lt (abs (minus (match_dup 0) (pc)))
+                                        (const_int 65536)))
                      (const_int 4)
                      (const_int 6))))])
 
diff --git a/gcc/testsuite/gcc.target/v850/min_bit.c 
b/gcc/testsuite/gcc.target/v850/min_bit.c
new file mode 100644
index 00000000000..c21c9797a2c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/v850/min_bit.c
@@ -0,0 +1,30 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+int g1 = 1, g2 = 2;
+
+#define TEST(NAME, OP)                                 \
+  __attribute__ ((noinline, noclone)) int              \
+  NAME (short *p, int a, int b)                                \
+  {                                                    \
+    *p OP 0x10;                                                \
+    if (a == b)                                                \
+      return g1;                                       \
+    return g2;                                         \
+  }
+
+TEST (f_set1, |=)
+TEST (f_not1, ^=)
+
+int
+main (void)
+{
+  short x = 0;
+
+  if (f_set1 (&x, 1, 2) != 2)
+    __builtin_abort ();
+  x = 0;
+  if (f_not1 (&x, 1, 2) != 2)
+    __builtin_abort ();
+  __builtin_exit (0);
+}

Reply via email to