Tested with

make -k check RUNTESTFLAGS="--target_board=sh-sim\{-m2/-ml,-m2/-mb,-m2a/-
mb,-m4/-ml,-m4/-mb,-m4a/-ml,-m4a/-mb}"

Committed to master.

Best regards,
Oleg Endo

gcc/ChangeLog:

        PR target/124778
        * config/sh/sh.md (extend<mode>si2_short_mem_disp_z): Move after
        '*extend<mode>si2_compact_mem_disp' patterns.
From b70bb7f63b69008692f66dafa81b632e3149e39c Mon Sep 17 00:00:00 2001
From: Oleg Endo <[email protected]>
Date: Fri, 3 Jul 2026 21:17:52 +0900
Subject: [PATCH] SH: Fix PR 124778

The lower-subreg pass would bail out in decompose_multiword_subregs because of
the ordering of the insn patterns.

gcc/ChangeLog:

	PR target/124778
	* config/sh/sh.md (extend<mode>si2_short_mem_disp_z): Move after
	'*extend<mode>si2_compact_mem_disp' patterns.
---
 gcc/config/sh/sh.md | 35 ++++++++++++++++++++---------------
 1 file changed, 20 insertions(+), 15 deletions(-)

diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md
index 4cc384c..2d08287 100644
--- a/gcc/config/sh/sh.md
+++ b/gcc/config/sh/sh.md
@@ -4846,21 +4846,6 @@
     }
 })
 
-(define_insn_and_split "extend<mode>si2_short_mem_disp_z"
-  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
-	(sign_extend:SI
-	    (match_operand:QIHI 1 "short_displacement_mem_operand" "m")))
-   (clobber (reg:SI R0_REG))]
-  "TARGET_SH1 && ! TARGET_SH2A && sh_lra_p ()"
-  "#"
-  "&& 1"
-  [(set (match_dup 2) (sign_extend:SI (match_dup  1)))
-   (set (match_dup 0) (match_dup 2))]
-{
-  operands[2] = gen_rtx_REG (SImode, R0_REG);
-}
-  [(set_attr "type" "load")])
-
 (define_insn_and_split "*extend<mode>si2_compact_reg"
   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
 	(sign_extend:SI (match_operand:QIHI 1 "arith_reg_operand" "r")))]
@@ -4911,6 +4896,26 @@
   [(set_attr "type" "load")
    (set_attr "length" "2,2,4")])
 
+;; The extend<mode>si2_short_mem_disp_z pattern must come after the
+;; *extend<mode>si2_compact_mem_disp patterns.
+;; The patterns without the R0 clobber should be matched by recog first.
+;; This R0-clobber pattern is normally only explicitly emitted during
+;; expansion before RA.
+(define_insn_and_split "extend<mode>si2_short_mem_disp_z"
+  [(set (match_operand:SI 0 "arith_reg_dest" "=r")
+	(sign_extend:SI
+	    (match_operand:QIHI 1 "short_displacement_mem_operand" "m")))
+   (clobber (reg:SI R0_REG))]
+  "TARGET_SH1 && ! TARGET_SH2A && sh_lra_p ()"
+  "#"
+  "&& 1"
+  [(set (match_dup 2) (sign_extend:SI (match_dup  1)))
+   (set (match_dup 0) (match_dup 2))]
+{
+  operands[2] = gen_rtx_REG (SImode, R0_REG);
+}
+  [(set_attr "type" "load")])
+
 ;; The pre-dec and post-inc mems must be captured by the '<' and '>'
 ;; constraints, otherwise wrong code might get generated.
 (define_insn "*extend<mode>si2_predec"
--
libgit2 1.9.0

Reply via email to