https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119013
Bug ID: 119013 Summary: LoongArch and RISC-V: Redundant sign-extension after moving 32-bit values from FPR into 64-bit GPR Product: gcc Version: 15.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: rtl-optimization Assignee: unassigned at gcc dot gnu.org Reporter: xry111 at gcc dot gnu.org Target Milestone: --- int test (float x) { int ret; __builtin_memcpy (&ret, &x, 4); return ret; } results: movfr2gr.s $r4,$f0 slli.w $r4,$r4,0 jr $r1 for LoongArch, or fmv.x.s a0,fa0 sext.w a0,a0 ret for RISC-V. But both movfr2gr.s and fmv.x.s already performs the sign-extension. For LoongArch we already have (define_insn "extendsidi2" [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r") (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,ZC,m,k,f")))] "TARGET_64BIT" "@ slli.w\t%0,%1,0 ldptr.w\t%0,%1 ld.w\t%0,%1 ldx.w\t%0,%1 movfr2gr.s\t%0,%1" [(set_attr "move_type" "sll0,load,load,load,mftg") (set_attr "mode" "DI")]) but the register allocation just insists to do (insn 14 6 11 2 (set (reg:SF 4 $r4 [orig:85 x ] [85]) (reg:SF 32 $f0 [ x ])) "t.c":3:1 161 {*movsf_hardfloat} (nil)) (insn 11 14 12 2 (set (reg/i:DI 4 $r4) (sign_extend:DI (reg:SI 4 $r4 [orig:85 x ] [85]))) "t.c":7:1 135 {extendsidi2} (nil)) The similar thing happens if I add fmv.x.s to RISC-V extendsidi2_internal.