This is an archive of the discontinued LLVM Phabricator instance.

[BuildLibCalls][RISCV] Sign extend return value of bcmp on riscv64.
ClosedPublic

Authored by craig.topper on Dec 12 2022, 5:44 PM.

Details

Summary

riscv64 wants callees to sign extend signed and unsigned int returns.

The caller can use this to avoid a sign extend if the result is
used by a comparison since riscv64 only has 64-bit compares.

InstCombine/SimplifyLibCalls aggressively turn memcmps that are only
used by an icmp eq 0 into bcmp, but we lose the sext attribute that
would have been present on the memcmp. This causes an unneeded sext.w
in the generated assembly.

This looks even sillier if bcmp is implemented alias to memcmp. In
that case, not only did we not get any savings by using bcmp, we added
an instruction.

This probably applies to other functions, this just happens to be
the one I noticed so far.

See also the discussion here https://discourse.llvm.org/t/can-we-preserve-signext-return-attribute-when-converting-memcmp-to-bcmp/67126

Diff Detail

Event Timeline

craig.topper created this revision.Dec 12 2022, 5:44 PM
craig.topper requested review of this revision.Dec 12 2022, 5:44 PM
Herald added a project: Restricted Project. · View Herald TranscriptDec 12 2022, 5:44 PM
craig.topper retitled this revision from [BuildLibCalls] Sign extend return value of bcmp on riscv64. to [BuildLibCalls][RISCV] Sign extend return value of bcmp on riscv64..Dec 12 2022, 5:47 PM
craig.topper edited the summary of this revision. (Show Details)
craig.topper edited the summary of this revision. (Show Details)

Isn't MIPS the same? RISC-V just inherited this from MIPS by being a derivative of it (both ISA-wise and in the GNU toolchain implementation).

Hm, maybe not, GCC and Clang both seem to want to normalise the upper bits for dealing with an unsigned 32-bit return value being promoted to 64-bit, whether signed or unsigned... and the psABI document is really unclear on what on earth the convention is for return values in most respects. It's clear on parameters at least...

Hm, maybe not, GCC and Clang both seem to want to normalise the upper bits for dealing with an unsigned 32-bit return value being promoted to 64-bit, whether signed or unsigned... and the psABI document is really unclear on what on earth the convention is for return values in most respects. It's clear on parameters at least...

It looks like TargetInfo.cpp in clang applies the attributes to integer arguments regardless of triple. See MipsABIInfo::extendType.

// MIPS64 ABI requires unsigned 32 bit integers to be sign extended.           
if (Ty->isUnsignedIntegerOrEnumerationType() && TySize == 32)                  
  return ABIArgInfo::getSignExtend(Ty);                                        
                                                                               
return ABIArgInfo::getExtend(Ty);

For returns only applies to if the triple arch is mips64 or mips64el. See the bottom of MipsABIInfo::classifyReturnType.

if ((RetTy->isUnsignedIntegerOrEnumerationType() ||                            
    RetTy->isSignedIntegerOrEnumerationType()) && Size == 32 && !IsO32)        
  return ABIArgInfo::getSignExtend(RetTy);

Note the !IsO32 that was not present in MipsABIInfo::extendType

Ping. Does this look ok for RISC-V?

This revision is now accepted and ready to land.Dec 20 2022, 11:24 AM
This revision was landed with ongoing or failed builds.Dec 20 2022, 11:47 AM
This revision was automatically updated to reflect the committed changes.