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