https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64345
--- Comment #3 from Oleg Endo <olegendo at gcc dot gnu.org> --- (In reply to Oleg Endo from comment #2) The following pattern seems to fix the test case. =================================================================== --- gcc/config/sh/sh.md (revision 225987) +++ gcc/config/sh/sh.md (working copy) @@ -14220,6 +14220,31 @@ [(set (reg:SI T_REG) (zero_extract:SI (match_dup 0) (const_int 1) (match_dup 1)))]) +(define_insn_and_split "*zero_extract_3" + [(set (match_operand:SI 0 "arith_reg_dest") + (and:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand") + (match_operand 2 "const_int_operand")) + (match_operand 3 "const_int_operand"))) + (clobber (reg:SI T_REG))] + "TARGET_SH1 && can_create_pseudo_p () + && exact_log2 (INTVAL (operands[3])) >= 0" + "#" + "&& 1" + [(const_int 0)] +{ + int rshift = INTVAL (operands[2]); + int lshift = exact_log2 (INTVAL (operands[3])); + + rtx tmp = gen_reg_rtx (SImode); + emit_insn (gen_rtx_PARALLEL (VOIDmode, + gen_rtvec (2, + gen_rtx_SET (tmp, + gen_rtx_ZERO_EXTRACT (SImode, operands[1], const1_rtx, + GEN_INT (rshift + lshift))), + gen_rtx_CLOBBER (VOIDmode, get_t_reg_rtx ())))); + emit_insn (gen_ashlsi3 (operands[0], tmp, GEN_INT (lshift))); +}) + ;; ------------------------------------------------------------------------- ;; SH2A instructions for bitwise operations. ;; FIXME: Convert multiple instruction insns to insn_and_split. However, in some cases it might indeed be better to emit a shift-and sequence, especially if the shift value is 1,2,8,16. For instance return (((vi >> 6) & 0x01) << 3); results in mov r4,r0 tst #64,r0 mov #-1,r0 negc r0,r0 shll2 r0 rts add r0,r0 which is better as: mov r4,r0 shll2 r0 shlr r0 rts and #8,r0 Even more so when the bit test constant doesn't fit into 8 bits: return (((vi >> 10) & 0x01) << 1); mov.w .L2,r1 mov #-1,r0 tst r1,r4 negc r0,r0 rts add r0,r0 .align 1 .L2: .short 1024 better: mov r4,r0 shlr8 r0 shlr r0 rts and #2,r0 Generally, it seems better to use an shift-and sequence, unless the tst-negc sequence can simplify the trailing shift for SH variants without dynamic shifts.