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

            Bug ID: 125405
           Summary: Missed optimization: mask/sub sign-extension idiom not
                    canonicalized to sign extension
           Product: gcc
           Version: 16.0
            Status: UNCONFIRMED
          Keywords: missed-optimization
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: [email protected]
  Target Milestone: ---
             Build: -O2

The following Hacker's Delight idioms compute sign extension from
the low byte / low halfword:

  (x & 0x7f) - (x & 0x80)
  (x & 0x7fff) - (x & 0x8000)

However, GCC does not currently canonicalize these idioms to a signed
narrow conversion / sign-extension operation.

Testcase:

typedef unsigned long xlen_t;

xlen_t sext8_hd(xlen_t x)
{
    return (x & 0x7fUL) - (x & 0x80UL);
}

xlen_t sext16_hd(xlen_t x)
{
    return (x & 0x7fffUL) - (x & 0x8000UL);
}

Command line:

  gcc -O2 -march=rv64gc -mabi=lp64d -S test.c

Current output for sext8_hd:

 sext8_hd:
          andi    a5,a0,127
          andi    a0,a0,128
          sub     a0,a5,a0
          ret

Current output for sext16_hd:

 sext16_hd:
          slli    a5,a0,49
          li      a4,32768
          srli    a5,a5,49
          and     a0,a0,a4
          sub     a0,a5,a0
          ret

Expected output:

sext8_hd:
        slliw   a0,a0,24
        sraiw   a0,a0,24
        ret
sext16_hd:
        slliw   a0,a0,16
        sraiw   a0,a0,16
        ret

Example link: https://godbolt.org/z/3h9z3vf95

Reply via email to