https://gcc.gnu.org/g:4203060a73e65e4fa3e091b060a973c3296b84e9
commit r15-9345-g4203060a73e65e4fa3e091b060a973c3296b84e9 Author: Jakub Jelinek <ja...@redhat.com> Date: Wed Apr 9 22:00:35 2025 +0200 h8300: Fix up bit test and jump splitter [PR119664] r12-2601 has added this define_insn_and_split and corresponding (define_insn "" [(set (reg:CCZ CC_REG) (eq (zero_extract:HSI (match_operand:HSI 0 "register_operand" "r") (const_int 1) (match_operand 1 "const_int_operand" "n")) (const_int 0)))] "INTVAL (operands[1]) < 16" "btst %Z1,%Y0" [(set_attr "length" "2")]) pattern into which the define_insn_and_split wants to splut in addition to a conditional jump. But as can be seen, the btst define_insn uses HSI mode iterator while define_insn_and_split QHSI, so for QImode it splits into something that can't be recognized. This was probably latent since r12-2601 and on the attached testcase is reproduceable starting with r15-1945 - a late combiner change. 2025-04-09 Jakub Jelinek <ja...@redhat.com> PR target/119664 * config/h8300/jumpcall.md (bit test and jump define_insn_and_split): Use HSI iterator rather than QHSI. * gcc.dg/pr119664.c: New test. Diff: --- gcc/config/h8300/jumpcall.md | 8 ++++---- gcc/testsuite/gcc.dg/pr119664.c | 15 +++++++++++++++ 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/gcc/config/h8300/jumpcall.md b/gcc/config/h8300/jumpcall.md index b59639992a36..4e634085130c 100644 --- a/gcc/config/h8300/jumpcall.md +++ b/gcc/config/h8300/jumpcall.md @@ -146,9 +146,9 @@ (define_insn_and_split "" [(set (pc) (if_then_else (match_operator 3 "eqne_operator" - [(zero_extract:QHSI (match_operand:QHSI 1 "register_operand" "r") - (const_int 1) - (match_operand 2 "const_int_operand" "n")) + [(zero_extract:HSI (match_operand:HSI 1 "register_operand" "r") + (const_int 1) + (match_operand 2 "const_int_operand" "n")) (const_int 0)]) (label_ref (match_operand 0 "" "")) (pc)))] @@ -156,7 +156,7 @@ "#" "&& reload_completed" [(set (reg:CCZ CC_REG) - (eq (zero_extract:QHSI (match_dup 1) (const_int 1) (match_dup 2)) + (eq (zero_extract:HSI (match_dup 1) (const_int 1) (match_dup 2)) (const_int 0))) (set (pc) (if_then_else (match_op_dup 3 [(reg:CCZ CC_REG) (const_int 0)]) diff --git a/gcc/testsuite/gcc.dg/pr119664.c b/gcc/testsuite/gcc.dg/pr119664.c new file mode 100644 index 000000000000..23ffc30eb779 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr119664.c @@ -0,0 +1,15 @@ +/* PR target/119664 */ +/* { dg-do compile } */ +/* { dg-options "-Os" } */ + +struct S { unsigned : 1, a : 1; } *s; +int foo (void); +void bar (void); + +int +baz (void) +{ + int a = s->a; + bar (); + return a && foo (); +}