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

Reply via email to