https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116398
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |rguenth at gcc dot gnu.org, | |rsandifo at gcc dot gnu.org, | |segher at gcc dot gnu.org --- Comment #6 from Jakub Jelinek <jakub at gcc dot gnu.org> --- As a hack, I've tried --- gcc/config/aarch64/aarch64.md.jj 2025-03-05 06:39:50.000000000 +0100 +++ gcc/config/aarch64/aarch64.md 2025-03-05 16:19:01.371301450 +0100 @@ -6337,6 +6337,26 @@ [(set_attr "type" "bfx")] ) +(define_insn_and_split "*extvdi_sext" + [(parallel + [(set (match_operand:DI 0 "register_operand" "=r") + (sign_extract:DI (subreg:DI (match_operand:SI 2 "register_operand" "r") 0) + (match_operand 3 + "aarch64_simd_shift_imm_offset_di" "n") + (match_operand 4 + "aarch64_simd_shift_imm_di" "n"))) + (set (match_operand:DI 1 "register_operand" "=r") + (sign_extend:DI (match_dup 2)))])] + "IN_RANGE (INTVAL (operands[3]) + INTVAL (operands[4]), 1, 63) + && !reg_overlap_mentioned_p (operands[1], operands[2]) + && !reload_completed" + "#" + "&& true" + [(set (match_dup 1) (sign_extend:DI (match_dup 2))) + (set (match_dup 0) (sign_extract:DI (subreg:DI (match_dup 2) 0) + (match_dup 3) + (match_dup 4)))]) + ;; When the bit position and width add up to 32 we can use a W-reg LSR ;; instruction taking advantage of the implicit zero-extension of the X-reg. (define_split (being a hack, no mode/code macros in it and the like), and that doesn't restore previous behavior, but instead results in sbfx x1, x0, 11, 21 sbfiz x0, x0, 53, 11 ret assembly. *extendsi_shft_di is matched by late_combine2. Perhaps that insn could have a splitter for the case where shift count is CONST_INT in range [32, 63] and in that case split it into normal left shift of the paradoxical subreg of the argument rather than sign_extend because nothing cares about those bits?