https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111466

            Bug ID: 111466
           Summary: RISC-V: redundant sign extensions despite ABI
                    guarantees
           Product: gcc
           Version: 13.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
          Assignee: vineetg at gcc dot gnu.org
          Reporter: vineetg at gcc dot gnu.org
                CC: aagarwa at gcc dot gnu.org, jeffreyalaw at gmail dot com,
                    jivanhakobyan9 at gmail dot com, kito at gcc dot gnu.org,
                    palmer at gcc dot gnu.org
  Target Milestone: ---

Consider the test below:

int foo(int unused, int n, unsigned y, unsigned delta){
  int s = 0;
  unsigned int x = 0;    // if int, sext elided
  for (;x<n;x +=delta)
    s += x+y;
  return s;
}

-O2 -march=rv64gc_zba_zbb_zbs

foo2:
    sext.w    a6,a1            # 1
    beq    a1,zero,.L4
    li    a5,0
    li    a0,0
.L3:
    addw    a4,a2,a5
    addw    a5,a3,a5
    addw    a0,a4,a0
    bltu    a5,a6,.L3
    ret
.L4:
    li    a0,0
    ret

I believe the SEXT.W is not semantically needed as a1 is supposed to be sign
extended already at call site as per psABI [1]. I quote

    "When passed in registers or on the stack, integer scalars narrower than
XLEN bits are widened according to the sign of their type up to 32 bits, then
sign-extended to XLEN bits"

However currently RISC-V backend thinks otherwise: changing @x to int, causes
the the sign extend to go away. I think both the cases should behave the same
(and not generate SEXT.w) given the ABI clause above. Note that this manifests
in initial RTL expand itself generating/or-not-generating the sign_extend so if
it is unnecessary we can avoid late fixups in REE.

Andrew Waterman confirmed that the ABI guarantees this and that the SEXT.W is
redundant [1]

[1] https://gcc.gnu.org/pipermail/gcc-patches/2023-September/630811.html

Reply via email to