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

            Bug ID: 122769
           Summary: RISC-V: Short branch can be elided for alu op
           Product: gcc
           Version: 15.0
            Status: UNCONFIRMED
          Keywords: missed-optimization
          Severity: normal
          Priority: P3
         Component: target
          Assignee: vineetg at gcc dot gnu.org
          Reporter: vineetg at gcc dot gnu.org
  Target Milestone: ---
            Target: risc-v

gcc is generating a short forward branch whereas llvm omits the branch
altogether.


typedef unsigned long uint64_t;

uint64_t updateLSB63(uint64_t val, uint64_t val2, int bits, int n) {
  if (val & (1ULL << 63))
     val2 ^= n;
  return val2;
}

-O2 -mtune=generic -march=rv64gc_zba_zbb_zbs_zicond -mabi=lp64d

updateLSB63:
        bge     a0,zero,.L2
        xor     a1,a1,a3
.L2:
        mv      a0,a1
        ret

LLVM OTOH generates 

updateLSB63:
        srai    a0, a0, 63
        and     a0, a0, a3
        xor     a0, a0, a1
        ret

Interestingly, if the const 63 is replaced with 62, gcc seems to elide the
branch for a conditional zero.

uint64_t updateLSB62(uint64_t val, uint64_t val2, int bits, int n) {
  if (val & (1ULL << 62))
     val2 ^= n;
  return val2;
}

updateLSB62:
        bseti   a5,zero,62
        and     a0,a0,a5
        czero.eqz       a0,a3,a0
        xor     a0,a1,a0
        ret

Granted this itself could be optimized BSETI + AND = BEXTI as a followup.

Reply via email to