This match pattern allows combination (zero_extract:DI 8, 24, QI) with an sign-extend to 32bit INS instruction on TARGET_64BIT.
The problem is that, for SI mode, if the sign-bit is modified by bitops, we will need a sign-extend operation. Since 32bit INS instruction can be sure that result is sign-extended, and the QImode src register is safe for INS, too. (insn 19 18 20 2 (set (zero_extract:DI (reg/v:DI 200 [ val ]) (const_int 8 [0x8]) (const_int 24 [0x18])) (subreg:DI (reg:QI 205) 0)) "../xx.c":7:29 -1 (nil)) (insn 20 19 23 2 (set (reg/v:DI 200 [ val ]) (sign_extend:DI (subreg:SI (reg/v:DI 200 [ val ]) 0))) "../xx.c":7:29 -1 (nil)) Combine try to merge them to: (insn 20 19 23 2 (set (reg/v:DI 200 [ val ]) (sign_extend:DI (ior:SI (and:SI (subreg:SI (reg/v:DI 200 [ val ]) 0) (const_int 16777215 [0xffffff])) (ashift:SI (subreg:SI (reg:QI 205 [ MEM[(const unsigned char *)buf_8(D) + 3B] ]) 0) (const_int 24 [0x18]))))) "../xx.c":7:29 18 {*insv_extended} (expr_list:REG_DEAD (reg:QI 205 [ MEM[(const unsigned char *)buf_8(D) + 3B] ]) (nil))) Let's accept this pattern. Note: with this patch, we cannot get INS yet: rtx_cost treats that the later one is more expensive than the previous 2. gcc * config/mips/mips.md (insqisi_extended): New pattern. --- gcc/config/mips/mips.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md index 0666310734e..6bc56b0d3da 100644 --- a/gcc/config/mips/mips.md +++ b/gcc/config/mips/mips.md @@ -4415,6 +4415,16 @@ (define_insn "*extzv_truncsi_exts" [(set_attr "type" "arith") (set_attr "mode" "SI")]) +(define_insn "*insqisi_extended" + [(set (match_operand:DI 0 "register_operand" "=d") + (sign_extend:DI + (ior:SI (and:SI (subreg:SI (match_dup 0) 0) + (const_int 16777215)) + (ashift:SI (subreg:SI (match_operand:QI 1 "register_operand" "d") 0) + (const_int 24)))))] + "TARGET_64BIT && !TARGET_MIPS16 && ISA_HAS_EXT_INS" + "ins\t%0,%1,24,8" + [(set_attr "mode" "SI")]) (define_expand "insvmisalign<mode>" [(set (zero_extract:GPR (match_operand:BLK 0 "memory_operand") -- 2.39.2