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.

Reply via email to