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  <jakub@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.
This commit is contained in:
Jakub Jelinek 2025-04-09 22:00:35 +02:00 committed by Jakub Jelinek
parent 101ac9e5ac
commit 4203060a73
2 changed files with 19 additions and 4 deletions

View file

@ -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)])

View file

@ -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 ();
}