diff options
author | Craig Topper <craig.topper@sifive.com> | 2022-12-20 11:37:51 -0800 |
---|---|---|
committer | Craig Topper <craig.topper@sifive.com> | 2022-12-20 11:47:04 -0800 |
commit | 9b2fecec406d6a6bcda9fbb9251db2ae202c7400 (patch) | |
tree | 40433f55df6c4f2b9bf1a2e2ab389caf97606cb1 /llvm/lib/Transforms/Utils/BuildLibCalls.cpp | |
parent | 3beb05417086443ad3314e7008090256b96741a2 (diff) | |
download | llvm-9b2fecec406d6a6bcda9fbb9251db2ae202c7400.zip llvm-9b2fecec406d6a6bcda9fbb9251db2ae202c7400.tar.gz llvm-9b2fecec406d6a6bcda9fbb9251db2ae202c7400.tar.bz2 |
[BuildLibCalls][RISCV] Sign extend return value of bcmp on riscv64.
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 signext 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
Reviewed By: efriedma
Differential Revision: https://reviews.llvm.org/D139901
Diffstat (limited to 'llvm/lib/Transforms/Utils/BuildLibCalls.cpp')
-rw-r--r-- | llvm/lib/Transforms/Utils/BuildLibCalls.cpp | 9 |
1 files changed, 9 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/Utils/BuildLibCalls.cpp b/llvm/lib/Transforms/Utils/BuildLibCalls.cpp index beb3351..1e21a2f 100644 --- a/llvm/lib/Transforms/Utils/BuildLibCalls.cpp +++ b/llvm/lib/Transforms/Utils/BuildLibCalls.cpp @@ -1240,6 +1240,13 @@ static void setArgExtAttr(Function &F, unsigned ArgNo, F.addParamAttr(ArgNo, ExtAttr); } +static void setRetExtAttr(Function &F, + const TargetLibraryInfo &TLI, bool Signed = true) { + Attribute::AttrKind ExtAttr = TLI.getExtAttrForI32Return(Signed); + if (ExtAttr != Attribute::None && !F.hasRetAttribute(ExtAttr)) + F.addRetAttr(ExtAttr); +} + // Modeled after X86TargetLowering::markLibCallAttributes. static void markRegisterParameterAttributes(Function *F) { if (!F->arg_size() || F->isVarArg()) @@ -1315,6 +1322,8 @@ FunctionCallee llvm::getOrInsertLibFunc(Module *M, const TargetLibraryInfo &TLI, // on any target: A size_t argument (which may be an i32 on some targets) // should not trigger the assert below. case LibFunc_bcmp: + setRetExtAttr(*F, TLI); + break; case LibFunc_calloc: case LibFunc_fwrite: case LibFunc_malloc: |