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 tossed another port's MD file at it.

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

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