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.