Repository navigation
CodeGen: Use RuntimeLibcallsInfo for memset_pattern16 - #241384
Conversation
This stack of pull requests is managed by Graphite. Learn more about stacking. |
|
@llvm/pr-subscribers-llvm-transforms Author: Matt Arsenault (arsenm) ChangesCodeGen passes shouldn't be using TargetLibraryInfo for functions they Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Full diff: https://github.com/llvm/llvm-project/pull/241384.diff 5 Files Affected:
diff --git a/llvm/include/llvm/Analysis/LibcallLoweringInfo.h b/llvm/include/llvm/Analysis/LibcallLoweringInfo.h
index 083a86c4a9ef4..e513cd1e983a5 100644
--- a/llvm/include/llvm/Analysis/LibcallLoweringInfo.h
+++ b/llvm/include/llvm/Analysis/LibcallLoweringInfo.h
@@ -131,6 +131,10 @@ class ModuleLibcallLoweringInfo {
operator bool() const { return RTLCI != nullptr; }
+ const RTLIB::RuntimeLibcallsInfo &getRuntimeLibcallsInfo() const {
+ return *RTLCI;
+ }
+
LLVM_ABI bool invalidate(Module &, const PreservedAnalyses &,
ModuleAnalysisManager::Invalidator &);
diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.td b/llvm/include/llvm/IR/RuntimeLibcalls.td
index 6d339cbd33d4f..5e497c84d6a2e 100644
--- a/llvm/include/llvm/IR/RuntimeLibcalls.td
+++ b/llvm/include/llvm/IR/RuntimeLibcalls.td
@@ -1105,9 +1105,13 @@ def MEMCHR : RuntimeLibcall<Ptr, [Ptr, Int, SizeT]>;
def MEMPCPY : RuntimeLibcall<Ptr, [Ptr, Ptr, SizeT]>;
def MEMPCPY_CHK : RuntimeLibcall<Ptr, [Ptr, Ptr, SizeT, SizeT]>;
def MEMRCHR : RuntimeLibcall<Ptr, [Ptr, Int, SizeT]>;
-def MEMSET_PATTERN16 : RuntimeLibcall<Void, [Ptr, Ptr, SizeT]>;
-def MEMSET_PATTERN4 : RuntimeLibcall<Void, [Ptr, Ptr, SizeT]>;
-def MEMSET_PATTERN8 : RuntimeLibcall<Void, [Ptr, Ptr, SizeT]>;
+foreach Size = [4, 8, 16] in {
+ def MEMSET_PATTERN#Size : RuntimeLibcall<Void, [Ptr, Ptr, SizeT]> {
+ let FnAttrs = [NoCallback, NoFree, NoSync, NoUnwind, WillReturn];
+ let Memory = ArgMemOnly;
+ let ParamAttrs = [[CapturesNone, WriteOnly], [CapturesNone, ReadOnly]];
+ }
+}
def MKDIR : RuntimeLibcall<Int, [Ptr, IntX]>;
def MKTIME : RuntimeLibcall<IntPlus, [Ptr]>;
def MSVC_DELETE_ARRAY_PTR32 : RuntimeLibcall<Void, [Ptr]>;
diff --git a/llvm/include/llvm/IR/RuntimeLibcallsImpl.td b/llvm/include/llvm/IR/RuntimeLibcallsImpl.td
index 03346b17fece4..da452fcc813cf 100644
--- a/llvm/include/llvm/IR/RuntimeLibcallsImpl.td
+++ b/llvm/include/llvm/IR/RuntimeLibcallsImpl.td
@@ -159,6 +159,7 @@ class MemoryEffects<ModRefInfo mr = ModRef> {
def UnknownMemory : MemoryEffects;
def NoMemory : MemoryEffects<NoModRef>;
+def ArgMemOnly : MemoryEffects<NoModRef> { let ArgMem = ModRef; }
def ArgMemWriteOnly : MemoryEffects<NoModRef> { let ArgMem = Mod; }
def ErrnoMemWriteOnly : MemoryEffects<NoModRef> { let ErrnoMem = Mod; }
diff --git a/llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp b/llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp
index d1f34737fbafc..05fa1f27ebf06 100644
--- a/llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp
+++ b/llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp
@@ -43,7 +43,6 @@
#include "llvm/Target/TargetMachine.h"
#include "llvm/Transforms/Scalar/LowerConstantIntrinsics.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
-#include "llvm/Transforms/Utils/BuildLibCalls.h"
#include "llvm/Transforms/Utils/LowerMemIntrinsics.h"
#include "llvm/Transforms/Utils/LowerVectorIntrinsics.h"
@@ -339,8 +338,9 @@ bool PreISelIntrinsicLowering::tryExpandBoundedMemSet(
// Return a value appropriate for use with the memset_pattern16 libcall, if
// possible and if we know how. (Adapted from equivalent helper in
// LoopIdiomRecognize).
-static Constant *getMemSetPattern16Value(MemSetPatternInst *Inst,
- const TargetLibraryInfo &TLI) {
+static Constant *
+getMemSetPattern16Value(MemSetPatternInst *Inst,
+ const RTLIB::RuntimeLibcallsInfo &RTLCI) {
// TODO: This could check for UndefValue because it can be merged into any
// other valid pattern.
@@ -351,9 +351,8 @@ static Constant *getMemSetPattern16Value(MemSetPatternInst *Inst,
Value *V = Inst->getValue();
Type *VTy = V->getType();
const DataLayout &DL = Inst->getDataLayout();
- Module *M = Inst->getModule();
- if (!isLibFuncEmittable(M, &TLI, LibFunc_memset_pattern16))
+ if (!RTLCI.isAvailable(RTLIB::impl_memset_pattern16))
return nullptr;
// If the value isn't a constant, we can't promote it to being in a constant
@@ -489,8 +488,9 @@ bool PreISelIntrinsicLowering::expandMemIntrinsicUses(
case Intrinsic::experimental_memset_pattern: {
auto *Memset = cast<MemSetPatternInst>(Inst);
Function *ParentFunc = Memset->getFunction();
- const TargetLibraryInfo &TLI = LookupTLI(*ParentFunc);
- Constant *PatternValue = getMemSetPattern16Value(Memset, TLI);
+ const RTLIB::RuntimeLibcallsInfo &RTLCI =
+ ModuleLibcalls.getRuntimeLibcallsInfo();
+ Constant *PatternValue = getMemSetPattern16Value(Memset, RTLCI);
if (!PatternValue) {
// If it isn't possible to emit a memset_pattern16 libcall, expand to
// a loop instead.
@@ -506,13 +506,9 @@ bool PreISelIntrinsicLowering::expandMemIntrinsicUses(
Module *M = Memset->getModule();
const DataLayout &DL = Memset->getDataLayout();
- Type *DestPtrTy = Memset->getRawDest()->getType();
- Type *SizeTTy = TLI.getSizeTType(*M);
- StringRef FuncName = "memset_pattern16";
- FunctionCallee MSP = getOrInsertLibFunc(M, TLI, LibFunc_memset_pattern16,
- Builder.getVoidTy(), DestPtrTy,
- Builder.getPtrTy(), SizeTTy);
- inferNonMandatoryLibFuncAttrs(M, FuncName, TLI);
+ FunctionCallee MSP =
+ RTLCI.getOrInsertLibcallDecl(*M, RTLIB::impl_memset_pattern16);
+ Type *SizeTTy = MSP.getFunctionType()->getParamType(2);
// Otherwise we should form a memset_pattern16. PatternValue is known
// to be an constant array of 16-bytes. Put the value into a mergable
@@ -535,11 +531,13 @@ bool PreISelIntrinsicLowering::expandMemIntrinsicUses(
}
Value *PatternPtr = GV;
Value *NumBytes = Builder.CreateMul(
- TLI.getAsSizeT(DL.getTypeAllocSize(Memset->getValue()->getType()),
- *M),
+ ConstantInt::get(SizeTTy,
+ DL.getTypeAllocSize(Memset->getValue()->getType())),
Builder.CreateZExtOrTrunc(Memset->getLength(), SizeTTy));
CallInst *MemsetPattern16Call =
Builder.CreateCall(MSP, {Memset->getRawDest(), PatternPtr, NumBytes});
+ MemsetPattern16Call->setCallingConv(
+ RTLCI.getLibcallImplCallingConv(RTLIB::impl_memset_pattern16));
MemsetPattern16Call->setAAMetadata(Memset->getAAMetadata());
// Preserve any call site attributes on the destination pointer
// argument (e.g. alignment).
diff --git a/llvm/test/Transforms/Util/DeclareRuntimeLibcalls/darwin.ll b/llvm/test/Transforms/Util/DeclareRuntimeLibcalls/darwin.ll
index e8c2f0abcbf1b..700847c0b62c2 100644
--- a/llvm/test/Transforms/Util/DeclareRuntimeLibcalls/darwin.ll
+++ b/llvm/test/Transforms/Util/DeclareRuntimeLibcalls/darwin.ll
@@ -19,14 +19,17 @@
; MACOS: declare i32 @getc_unlocked(ptr)
; MACOS: declare i32 @getchar_unlocked()
-; HAS-MEMSET-PATTERN-32: declare void @memset_pattern16(ptr, ptr, i32)
-; HAS-MEMSET-PATTERN-32: declare void @memset_pattern4(ptr, ptr, i32)
-; HAS-MEMSET-PATTERN-32: declare void @memset_pattern8(ptr, ptr, i32)
-; HAS-MEMSET-PATTERN-64: declare void @memset_pattern16(ptr, ptr, i64)
-; HAS-MEMSET-PATTERN-64: declare void @memset_pattern4(ptr, ptr, i64)
-; HAS-MEMSET-PATTERN-64: declare void @memset_pattern8(ptr, ptr, i64)
+; HAS-MEMSET-PATTERN-32: declare void @memset_pattern16(ptr writeonly captures(none), ptr readonly captures(none), i32) [[MEMSET_PATTERN_ATTRS:#[0-9]+]]
+; HAS-MEMSET-PATTERN-32: declare void @memset_pattern4(ptr writeonly captures(none), ptr readonly captures(none), i32) [[MEMSET_PATTERN_ATTRS]]
+; HAS-MEMSET-PATTERN-32: declare void @memset_pattern8(ptr writeonly captures(none), ptr readonly captures(none), i32) [[MEMSET_PATTERN_ATTRS]]
+; HAS-MEMSET-PATTERN-64: declare void @memset_pattern16(ptr writeonly captures(none), ptr readonly captures(none), i64) [[MEMSET_PATTERN_ATTRS:#[0-9]+]]
+; HAS-MEMSET-PATTERN-64: declare void @memset_pattern4(ptr writeonly captures(none), ptr readonly captures(none), i64) [[MEMSET_PATTERN_ATTRS]]
+; HAS-MEMSET-PATTERN-64: declare void @memset_pattern8(ptr writeonly captures(none), ptr readonly captures(none), i64) [[MEMSET_PATTERN_ATTRS]]
; MACOS: declare i32 @putc_unlocked(i32, ptr)
; MACOS: declare i32 @putchar_unlocked(i32)
+; HAS-MEMSET-PATTERN-32: attributes [[MEMSET_PATTERN_ATTRS]] = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
+; HAS-MEMSET-PATTERN-64: attributes [[MEMSET_PATTERN_ATTRS]] = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
+
; NO-MEMSET-PATTERN-NOT: memset_pattern
|
|
@llvm/pr-subscribers-llvm-analysis Author: Matt Arsenault (arsenm) ChangesCodeGen passes shouldn't be using TargetLibraryInfo for functions they Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Full diff: https://github.com/llvm/llvm-project/pull/241384.diff 5 Files Affected:
diff --git a/llvm/include/llvm/Analysis/LibcallLoweringInfo.h b/llvm/include/llvm/Analysis/LibcallLoweringInfo.h
index 083a86c4a9ef4..e513cd1e983a5 100644
--- a/llvm/include/llvm/Analysis/LibcallLoweringInfo.h
+++ b/llvm/include/llvm/Analysis/LibcallLoweringInfo.h
@@ -131,6 +131,10 @@ class ModuleLibcallLoweringInfo {
operator bool() const { return RTLCI != nullptr; }
+ const RTLIB::RuntimeLibcallsInfo &getRuntimeLibcallsInfo() const {
+ return *RTLCI;
+ }
+
LLVM_ABI bool invalidate(Module &, const PreservedAnalyses &,
ModuleAnalysisManager::Invalidator &);
diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.td b/llvm/include/llvm/IR/RuntimeLibcalls.td
index 6d339cbd33d4f..5e497c84d6a2e 100644
--- a/llvm/include/llvm/IR/RuntimeLibcalls.td
+++ b/llvm/include/llvm/IR/RuntimeLibcalls.td
@@ -1105,9 +1105,13 @@ def MEMCHR : RuntimeLibcall<Ptr, [Ptr, Int, SizeT]>;
def MEMPCPY : RuntimeLibcall<Ptr, [Ptr, Ptr, SizeT]>;
def MEMPCPY_CHK : RuntimeLibcall<Ptr, [Ptr, Ptr, SizeT, SizeT]>;
def MEMRCHR : RuntimeLibcall<Ptr, [Ptr, Int, SizeT]>;
-def MEMSET_PATTERN16 : RuntimeLibcall<Void, [Ptr, Ptr, SizeT]>;
-def MEMSET_PATTERN4 : RuntimeLibcall<Void, [Ptr, Ptr, SizeT]>;
-def MEMSET_PATTERN8 : RuntimeLibcall<Void, [Ptr, Ptr, SizeT]>;
+foreach Size = [4, 8, 16] in {
+ def MEMSET_PATTERN#Size : RuntimeLibcall<Void, [Ptr, Ptr, SizeT]> {
+ let FnAttrs = [NoCallback, NoFree, NoSync, NoUnwind, WillReturn];
+ let Memory = ArgMemOnly;
+ let ParamAttrs = [[CapturesNone, WriteOnly], [CapturesNone, ReadOnly]];
+ }
+}
def MKDIR : RuntimeLibcall<Int, [Ptr, IntX]>;
def MKTIME : RuntimeLibcall<IntPlus, [Ptr]>;
def MSVC_DELETE_ARRAY_PTR32 : RuntimeLibcall<Void, [Ptr]>;
diff --git a/llvm/include/llvm/IR/RuntimeLibcallsImpl.td b/llvm/include/llvm/IR/RuntimeLibcallsImpl.td
index 03346b17fece4..da452fcc813cf 100644
--- a/llvm/include/llvm/IR/RuntimeLibcallsImpl.td
+++ b/llvm/include/llvm/IR/RuntimeLibcallsImpl.td
@@ -159,6 +159,7 @@ class MemoryEffects<ModRefInfo mr = ModRef> {
def UnknownMemory : MemoryEffects;
def NoMemory : MemoryEffects<NoModRef>;
+def ArgMemOnly : MemoryEffects<NoModRef> { let ArgMem = ModRef; }
def ArgMemWriteOnly : MemoryEffects<NoModRef> { let ArgMem = Mod; }
def ErrnoMemWriteOnly : MemoryEffects<NoModRef> { let ErrnoMem = Mod; }
diff --git a/llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp b/llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp
index d1f34737fbafc..05fa1f27ebf06 100644
--- a/llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp
+++ b/llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp
@@ -43,7 +43,6 @@
#include "llvm/Target/TargetMachine.h"
#include "llvm/Transforms/Scalar/LowerConstantIntrinsics.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
-#include "llvm/Transforms/Utils/BuildLibCalls.h"
#include "llvm/Transforms/Utils/LowerMemIntrinsics.h"
#include "llvm/Transforms/Utils/LowerVectorIntrinsics.h"
@@ -339,8 +338,9 @@ bool PreISelIntrinsicLowering::tryExpandBoundedMemSet(
// Return a value appropriate for use with the memset_pattern16 libcall, if
// possible and if we know how. (Adapted from equivalent helper in
// LoopIdiomRecognize).
-static Constant *getMemSetPattern16Value(MemSetPatternInst *Inst,
- const TargetLibraryInfo &TLI) {
+static Constant *
+getMemSetPattern16Value(MemSetPatternInst *Inst,
+ const RTLIB::RuntimeLibcallsInfo &RTLCI) {
// TODO: This could check for UndefValue because it can be merged into any
// other valid pattern.
@@ -351,9 +351,8 @@ static Constant *getMemSetPattern16Value(MemSetPatternInst *Inst,
Value *V = Inst->getValue();
Type *VTy = V->getType();
const DataLayout &DL = Inst->getDataLayout();
- Module *M = Inst->getModule();
- if (!isLibFuncEmittable(M, &TLI, LibFunc_memset_pattern16))
+ if (!RTLCI.isAvailable(RTLIB::impl_memset_pattern16))
return nullptr;
// If the value isn't a constant, we can't promote it to being in a constant
@@ -489,8 +488,9 @@ bool PreISelIntrinsicLowering::expandMemIntrinsicUses(
case Intrinsic::experimental_memset_pattern: {
auto *Memset = cast<MemSetPatternInst>(Inst);
Function *ParentFunc = Memset->getFunction();
- const TargetLibraryInfo &TLI = LookupTLI(*ParentFunc);
- Constant *PatternValue = getMemSetPattern16Value(Memset, TLI);
+ const RTLIB::RuntimeLibcallsInfo &RTLCI =
+ ModuleLibcalls.getRuntimeLibcallsInfo();
+ Constant *PatternValue = getMemSetPattern16Value(Memset, RTLCI);
if (!PatternValue) {
// If it isn't possible to emit a memset_pattern16 libcall, expand to
// a loop instead.
@@ -506,13 +506,9 @@ bool PreISelIntrinsicLowering::expandMemIntrinsicUses(
Module *M = Memset->getModule();
const DataLayout &DL = Memset->getDataLayout();
- Type *DestPtrTy = Memset->getRawDest()->getType();
- Type *SizeTTy = TLI.getSizeTType(*M);
- StringRef FuncName = "memset_pattern16";
- FunctionCallee MSP = getOrInsertLibFunc(M, TLI, LibFunc_memset_pattern16,
- Builder.getVoidTy(), DestPtrTy,
- Builder.getPtrTy(), SizeTTy);
- inferNonMandatoryLibFuncAttrs(M, FuncName, TLI);
+ FunctionCallee MSP =
+ RTLCI.getOrInsertLibcallDecl(*M, RTLIB::impl_memset_pattern16);
+ Type *SizeTTy = MSP.getFunctionType()->getParamType(2);
// Otherwise we should form a memset_pattern16. PatternValue is known
// to be an constant array of 16-bytes. Put the value into a mergable
@@ -535,11 +531,13 @@ bool PreISelIntrinsicLowering::expandMemIntrinsicUses(
}
Value *PatternPtr = GV;
Value *NumBytes = Builder.CreateMul(
- TLI.getAsSizeT(DL.getTypeAllocSize(Memset->getValue()->getType()),
- *M),
+ ConstantInt::get(SizeTTy,
+ DL.getTypeAllocSize(Memset->getValue()->getType())),
Builder.CreateZExtOrTrunc(Memset->getLength(), SizeTTy));
CallInst *MemsetPattern16Call =
Builder.CreateCall(MSP, {Memset->getRawDest(), PatternPtr, NumBytes});
+ MemsetPattern16Call->setCallingConv(
+ RTLCI.getLibcallImplCallingConv(RTLIB::impl_memset_pattern16));
MemsetPattern16Call->setAAMetadata(Memset->getAAMetadata());
// Preserve any call site attributes on the destination pointer
// argument (e.g. alignment).
diff --git a/llvm/test/Transforms/Util/DeclareRuntimeLibcalls/darwin.ll b/llvm/test/Transforms/Util/DeclareRuntimeLibcalls/darwin.ll
index e8c2f0abcbf1b..700847c0b62c2 100644
--- a/llvm/test/Transforms/Util/DeclareRuntimeLibcalls/darwin.ll
+++ b/llvm/test/Transforms/Util/DeclareRuntimeLibcalls/darwin.ll
@@ -19,14 +19,17 @@
; MACOS: declare i32 @getc_unlocked(ptr)
; MACOS: declare i32 @getchar_unlocked()
-; HAS-MEMSET-PATTERN-32: declare void @memset_pattern16(ptr, ptr, i32)
-; HAS-MEMSET-PATTERN-32: declare void @memset_pattern4(ptr, ptr, i32)
-; HAS-MEMSET-PATTERN-32: declare void @memset_pattern8(ptr, ptr, i32)
-; HAS-MEMSET-PATTERN-64: declare void @memset_pattern16(ptr, ptr, i64)
-; HAS-MEMSET-PATTERN-64: declare void @memset_pattern4(ptr, ptr, i64)
-; HAS-MEMSET-PATTERN-64: declare void @memset_pattern8(ptr, ptr, i64)
+; HAS-MEMSET-PATTERN-32: declare void @memset_pattern16(ptr writeonly captures(none), ptr readonly captures(none), i32) [[MEMSET_PATTERN_ATTRS:#[0-9]+]]
+; HAS-MEMSET-PATTERN-32: declare void @memset_pattern4(ptr writeonly captures(none), ptr readonly captures(none), i32) [[MEMSET_PATTERN_ATTRS]]
+; HAS-MEMSET-PATTERN-32: declare void @memset_pattern8(ptr writeonly captures(none), ptr readonly captures(none), i32) [[MEMSET_PATTERN_ATTRS]]
+; HAS-MEMSET-PATTERN-64: declare void @memset_pattern16(ptr writeonly captures(none), ptr readonly captures(none), i64) [[MEMSET_PATTERN_ATTRS:#[0-9]+]]
+; HAS-MEMSET-PATTERN-64: declare void @memset_pattern4(ptr writeonly captures(none), ptr readonly captures(none), i64) [[MEMSET_PATTERN_ATTRS]]
+; HAS-MEMSET-PATTERN-64: declare void @memset_pattern8(ptr writeonly captures(none), ptr readonly captures(none), i64) [[MEMSET_PATTERN_ATTRS]]
; MACOS: declare i32 @putc_unlocked(i32, ptr)
; MACOS: declare i32 @putchar_unlocked(i32)
+; HAS-MEMSET-PATTERN-32: attributes [[MEMSET_PATTERN_ATTRS]] = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
+; HAS-MEMSET-PATTERN-64: attributes [[MEMSET_PATTERN_ATTRS]] = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
+
; NO-MEMSET-PATTERN-NOT: memset_pattern
|
|
@llvm/pr-subscribers-llvm-ir Author: Matt Arsenault (arsenm) ChangesCodeGen passes shouldn't be using TargetLibraryInfo for functions they Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Full diff: https://github.com/llvm/llvm-project/pull/241384.diff 5 Files Affected:
diff --git a/llvm/include/llvm/Analysis/LibcallLoweringInfo.h b/llvm/include/llvm/Analysis/LibcallLoweringInfo.h
index 083a86c4a9ef4..e513cd1e983a5 100644
--- a/llvm/include/llvm/Analysis/LibcallLoweringInfo.h
+++ b/llvm/include/llvm/Analysis/LibcallLoweringInfo.h
@@ -131,6 +131,10 @@ class ModuleLibcallLoweringInfo {
operator bool() const { return RTLCI != nullptr; }
+ const RTLIB::RuntimeLibcallsInfo &getRuntimeLibcallsInfo() const {
+ return *RTLCI;
+ }
+
LLVM_ABI bool invalidate(Module &, const PreservedAnalyses &,
ModuleAnalysisManager::Invalidator &);
diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.td b/llvm/include/llvm/IR/RuntimeLibcalls.td
index 6d339cbd33d4f..5e497c84d6a2e 100644
--- a/llvm/include/llvm/IR/RuntimeLibcalls.td
+++ b/llvm/include/llvm/IR/RuntimeLibcalls.td
@@ -1105,9 +1105,13 @@ def MEMCHR : RuntimeLibcall<Ptr, [Ptr, Int, SizeT]>;
def MEMPCPY : RuntimeLibcall<Ptr, [Ptr, Ptr, SizeT]>;
def MEMPCPY_CHK : RuntimeLibcall<Ptr, [Ptr, Ptr, SizeT, SizeT]>;
def MEMRCHR : RuntimeLibcall<Ptr, [Ptr, Int, SizeT]>;
-def MEMSET_PATTERN16 : RuntimeLibcall<Void, [Ptr, Ptr, SizeT]>;
-def MEMSET_PATTERN4 : RuntimeLibcall<Void, [Ptr, Ptr, SizeT]>;
-def MEMSET_PATTERN8 : RuntimeLibcall<Void, [Ptr, Ptr, SizeT]>;
+foreach Size = [4, 8, 16] in {
+ def MEMSET_PATTERN#Size : RuntimeLibcall<Void, [Ptr, Ptr, SizeT]> {
+ let FnAttrs = [NoCallback, NoFree, NoSync, NoUnwind, WillReturn];
+ let Memory = ArgMemOnly;
+ let ParamAttrs = [[CapturesNone, WriteOnly], [CapturesNone, ReadOnly]];
+ }
+}
def MKDIR : RuntimeLibcall<Int, [Ptr, IntX]>;
def MKTIME : RuntimeLibcall<IntPlus, [Ptr]>;
def MSVC_DELETE_ARRAY_PTR32 : RuntimeLibcall<Void, [Ptr]>;
diff --git a/llvm/include/llvm/IR/RuntimeLibcallsImpl.td b/llvm/include/llvm/IR/RuntimeLibcallsImpl.td
index 03346b17fece4..da452fcc813cf 100644
--- a/llvm/include/llvm/IR/RuntimeLibcallsImpl.td
+++ b/llvm/include/llvm/IR/RuntimeLibcallsImpl.td
@@ -159,6 +159,7 @@ class MemoryEffects<ModRefInfo mr = ModRef> {
def UnknownMemory : MemoryEffects;
def NoMemory : MemoryEffects<NoModRef>;
+def ArgMemOnly : MemoryEffects<NoModRef> { let ArgMem = ModRef; }
def ArgMemWriteOnly : MemoryEffects<NoModRef> { let ArgMem = Mod; }
def ErrnoMemWriteOnly : MemoryEffects<NoModRef> { let ErrnoMem = Mod; }
diff --git a/llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp b/llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp
index d1f34737fbafc..05fa1f27ebf06 100644
--- a/llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp
+++ b/llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp
@@ -43,7 +43,6 @@
#include "llvm/Target/TargetMachine.h"
#include "llvm/Transforms/Scalar/LowerConstantIntrinsics.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
-#include "llvm/Transforms/Utils/BuildLibCalls.h"
#include "llvm/Transforms/Utils/LowerMemIntrinsics.h"
#include "llvm/Transforms/Utils/LowerVectorIntrinsics.h"
@@ -339,8 +338,9 @@ bool PreISelIntrinsicLowering::tryExpandBoundedMemSet(
// Return a value appropriate for use with the memset_pattern16 libcall, if
// possible and if we know how. (Adapted from equivalent helper in
// LoopIdiomRecognize).
-static Constant *getMemSetPattern16Value(MemSetPatternInst *Inst,
- const TargetLibraryInfo &TLI) {
+static Constant *
+getMemSetPattern16Value(MemSetPatternInst *Inst,
+ const RTLIB::RuntimeLibcallsInfo &RTLCI) {
// TODO: This could check for UndefValue because it can be merged into any
// other valid pattern.
@@ -351,9 +351,8 @@ static Constant *getMemSetPattern16Value(MemSetPatternInst *Inst,
Value *V = Inst->getValue();
Type *VTy = V->getType();
const DataLayout &DL = Inst->getDataLayout();
- Module *M = Inst->getModule();
- if (!isLibFuncEmittable(M, &TLI, LibFunc_memset_pattern16))
+ if (!RTLCI.isAvailable(RTLIB::impl_memset_pattern16))
return nullptr;
// If the value isn't a constant, we can't promote it to being in a constant
@@ -489,8 +488,9 @@ bool PreISelIntrinsicLowering::expandMemIntrinsicUses(
case Intrinsic::experimental_memset_pattern: {
auto *Memset = cast<MemSetPatternInst>(Inst);
Function *ParentFunc = Memset->getFunction();
- const TargetLibraryInfo &TLI = LookupTLI(*ParentFunc);
- Constant *PatternValue = getMemSetPattern16Value(Memset, TLI);
+ const RTLIB::RuntimeLibcallsInfo &RTLCI =
+ ModuleLibcalls.getRuntimeLibcallsInfo();
+ Constant *PatternValue = getMemSetPattern16Value(Memset, RTLCI);
if (!PatternValue) {
// If it isn't possible to emit a memset_pattern16 libcall, expand to
// a loop instead.
@@ -506,13 +506,9 @@ bool PreISelIntrinsicLowering::expandMemIntrinsicUses(
Module *M = Memset->getModule();
const DataLayout &DL = Memset->getDataLayout();
- Type *DestPtrTy = Memset->getRawDest()->getType();
- Type *SizeTTy = TLI.getSizeTType(*M);
- StringRef FuncName = "memset_pattern16";
- FunctionCallee MSP = getOrInsertLibFunc(M, TLI, LibFunc_memset_pattern16,
- Builder.getVoidTy(), DestPtrTy,
- Builder.getPtrTy(), SizeTTy);
- inferNonMandatoryLibFuncAttrs(M, FuncName, TLI);
+ FunctionCallee MSP =
+ RTLCI.getOrInsertLibcallDecl(*M, RTLIB::impl_memset_pattern16);
+ Type *SizeTTy = MSP.getFunctionType()->getParamType(2);
// Otherwise we should form a memset_pattern16. PatternValue is known
// to be an constant array of 16-bytes. Put the value into a mergable
@@ -535,11 +531,13 @@ bool PreISelIntrinsicLowering::expandMemIntrinsicUses(
}
Value *PatternPtr = GV;
Value *NumBytes = Builder.CreateMul(
- TLI.getAsSizeT(DL.getTypeAllocSize(Memset->getValue()->getType()),
- *M),
+ ConstantInt::get(SizeTTy,
+ DL.getTypeAllocSize(Memset->getValue()->getType())),
Builder.CreateZExtOrTrunc(Memset->getLength(), SizeTTy));
CallInst *MemsetPattern16Call =
Builder.CreateCall(MSP, {Memset->getRawDest(), PatternPtr, NumBytes});
+ MemsetPattern16Call->setCallingConv(
+ RTLCI.getLibcallImplCallingConv(RTLIB::impl_memset_pattern16));
MemsetPattern16Call->setAAMetadata(Memset->getAAMetadata());
// Preserve any call site attributes on the destination pointer
// argument (e.g. alignment).
diff --git a/llvm/test/Transforms/Util/DeclareRuntimeLibcalls/darwin.ll b/llvm/test/Transforms/Util/DeclareRuntimeLibcalls/darwin.ll
index e8c2f0abcbf1b..700847c0b62c2 100644
--- a/llvm/test/Transforms/Util/DeclareRuntimeLibcalls/darwin.ll
+++ b/llvm/test/Transforms/Util/DeclareRuntimeLibcalls/darwin.ll
@@ -19,14 +19,17 @@
; MACOS: declare i32 @getc_unlocked(ptr)
; MACOS: declare i32 @getchar_unlocked()
-; HAS-MEMSET-PATTERN-32: declare void @memset_pattern16(ptr, ptr, i32)
-; HAS-MEMSET-PATTERN-32: declare void @memset_pattern4(ptr, ptr, i32)
-; HAS-MEMSET-PATTERN-32: declare void @memset_pattern8(ptr, ptr, i32)
-; HAS-MEMSET-PATTERN-64: declare void @memset_pattern16(ptr, ptr, i64)
-; HAS-MEMSET-PATTERN-64: declare void @memset_pattern4(ptr, ptr, i64)
-; HAS-MEMSET-PATTERN-64: declare void @memset_pattern8(ptr, ptr, i64)
+; HAS-MEMSET-PATTERN-32: declare void @memset_pattern16(ptr writeonly captures(none), ptr readonly captures(none), i32) [[MEMSET_PATTERN_ATTRS:#[0-9]+]]
+; HAS-MEMSET-PATTERN-32: declare void @memset_pattern4(ptr writeonly captures(none), ptr readonly captures(none), i32) [[MEMSET_PATTERN_ATTRS]]
+; HAS-MEMSET-PATTERN-32: declare void @memset_pattern8(ptr writeonly captures(none), ptr readonly captures(none), i32) [[MEMSET_PATTERN_ATTRS]]
+; HAS-MEMSET-PATTERN-64: declare void @memset_pattern16(ptr writeonly captures(none), ptr readonly captures(none), i64) [[MEMSET_PATTERN_ATTRS:#[0-9]+]]
+; HAS-MEMSET-PATTERN-64: declare void @memset_pattern4(ptr writeonly captures(none), ptr readonly captures(none), i64) [[MEMSET_PATTERN_ATTRS]]
+; HAS-MEMSET-PATTERN-64: declare void @memset_pattern8(ptr writeonly captures(none), ptr readonly captures(none), i64) [[MEMSET_PATTERN_ATTRS]]
; MACOS: declare i32 @putc_unlocked(i32, ptr)
; MACOS: declare i32 @putchar_unlocked(i32)
+; HAS-MEMSET-PATTERN-32: attributes [[MEMSET_PATTERN_ATTRS]] = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
+; HAS-MEMSET-PATTERN-64: attributes [[MEMSET_PATTERN_ATTRS]] = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
+
; NO-MEMSET-PATTERN-NOT: memset_pattern
|
cf90caf to
bb76979
Compare
|
LGTM. To spell it out explicitly (maybe let's include this in the commit message?), this has a user-visible behavior change: On -ffreestanding or -fno-builtin or -fno-builtin=memset_pattern compilations or attribute no_builtin annotated functions, TLI would never emit the call, but RTLCI allows that on platforms that claim to have it. Arguably, (1) this is simply a bug in the user's code (wrong target) or in the target definition, and (2) that's the whole point and intent of this TLI->RTLCI change. The relevance of this is that Apple/Darwin target triples do have a long history of being used for various firmware and embedded compilations with slight mismatches between LLVM's definition of the target and reality, and users are often able to solve ("paper over") the mismatches via various combinations of -ffreestanding, -fno-buildin, and attribute no_builtin. See #176272 for the current in-progress way of formalizing that. CC @ian-twilightcoder, @ahmedbougacha. (Power users, like firmware builders, would probably find it useful to have a way to actually influence the RTLCI's set of allowed libcalls via Clang or -mllvm compilation flags for particular compilations. But that's a separate story.) |
This is what I'm working on |
ilovepi
left a comment
There was a problem hiding this comment.
LGTM. Similar to the other comment, I wonder if this needs to be documented someplace? Maybe a blurb in the ReleaseNotes or an FYI post on discourse?
I don't think this comes anywhere near the level of requiring that much attention. This makes the behavior consistent with regular memset |
CodeGen passes shouldn't be using TargetLibraryInfo for functions they will emit. Use RuntimeLibcallsInfo which knows how to insert the correctly typed and annotated declaration. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
bb76979 to
31a557a
Compare
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/223/builds/17042 Here is the relevant piece of the build log for the reference |

CodeGen passes shouldn't be using TargetLibraryInfo for functions they will emit.
Use RuntimeLibcallsInfo which knows how to insert the correctly typed and annotated
declaration. This is a slight behavior change since RuntimeLibcallsInfo respects the
triple's libcall availability, but doesn't respect TargetLibraryInfo "no-builtins" attributes.
This is consistent with how regular memset is treated.
Co-authored-by: Claude Opus 5.5 noreply@anthropic.com