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);
+}