mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-21 18:22:53 +01:00
Intrinsic::getName: require a Module argument
Ensure that we provide a `Module` when checking if a rename of an intrinsic is necessary. This fixes the issue that was detected by https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=32288 (as mentioned by @fhahn), after committing D91250. Note that the `LLVMIntrinsicCopyOverloadedName` is being deprecated in favor of `LLVMIntrinsicCopyOverloadedName2`. Reviewed By: nikic Differential Revision: https://reviews.llvm.org/D99173
This commit is contained in:
parent
68369fae88
commit
c08eaddde6
@ -121,6 +121,10 @@ Changes to the OCaml bindings
|
||||
Changes to the C API
|
||||
--------------------
|
||||
|
||||
* The C API function ``LLVMIntrinsicCopyOverloadedName`` has been deprecated.
|
||||
Please migrate to ``LLVMIntrinsicCopyOverloadedName2`` which takes an extra
|
||||
module argument and which also handles unnamed types.
|
||||
('D99173' <https://reviews.llvm.org/D99173>'_)
|
||||
|
||||
Changes to the Go bindings
|
||||
--------------------------
|
||||
|
@ -2514,6 +2514,12 @@ LLVMTypeRef LLVMIntrinsicGetType(LLVMContextRef Ctx, unsigned ID,
|
||||
*/
|
||||
const char *LLVMIntrinsicGetName(unsigned ID, size_t *NameLength);
|
||||
|
||||
/** Deprecated: Use LLVMIntrinsicCopyOverloadedName2 instead. */
|
||||
const char *LLVMIntrinsicCopyOverloadedName(unsigned ID,
|
||||
LLVMTypeRef *ParamTypes,
|
||||
size_t ParamCount,
|
||||
size_t *NameLength);
|
||||
|
||||
/**
|
||||
* Copies the name of an overloaded intrinsic identified by a given list of
|
||||
* parameter types.
|
||||
@ -2521,12 +2527,14 @@ const char *LLVMIntrinsicGetName(unsigned ID, size_t *NameLength);
|
||||
* Unlike LLVMIntrinsicGetName, the caller is responsible for freeing the
|
||||
* returned string.
|
||||
*
|
||||
* This version also supports unnamed types.
|
||||
*
|
||||
* @see llvm::Intrinsic::getName()
|
||||
*/
|
||||
const char *LLVMIntrinsicCopyOverloadedName(unsigned ID,
|
||||
LLVMTypeRef *ParamTypes,
|
||||
size_t ParamCount,
|
||||
size_t *NameLength);
|
||||
const char *LLVMIntrinsicCopyOverloadedName2(LLVMModuleRef Mod, unsigned ID,
|
||||
LLVMTypeRef *ParamTypes,
|
||||
size_t ParamCount,
|
||||
size_t *NameLength);
|
||||
|
||||
/**
|
||||
* Obtain if the intrinsic identified by the given ID is overloaded.
|
||||
|
@ -55,21 +55,23 @@ namespace Intrinsic {
|
||||
/// version of getName if overloads are required.
|
||||
StringRef getName(ID id);
|
||||
|
||||
/// Return the LLVM name for an intrinsic, such as "llvm.ppc.altivec.lvx".
|
||||
/// Note, this version of getName supports overloads, but not unnamed types.
|
||||
/// It is less efficient than the StringRef version of this function. If no
|
||||
/// overloads are required, it is safe to use this version, but better to use
|
||||
/// the StringRef version.
|
||||
std::string getName(ID Id, ArrayRef<Type *> Tys);
|
||||
/// Return the LLVM name for an intrinsic, without encoded types for
|
||||
/// overloading, such as "llvm.ssa.copy".
|
||||
StringRef getBaseName(ID id);
|
||||
|
||||
/// Return the LLVM name for an intrinsic, such as "llvm.ssa.copy.p0s_s.1".
|
||||
/// Note, this version of getName supports overloads and unnamed types, but is
|
||||
/// less efficient than the StringRef version of this function. If no
|
||||
/// Return the LLVM name for an intrinsic, such as "llvm.ppc.altivec.lvx" or
|
||||
/// "llvm.ssa.copy.p0s_s.1". Note, this version of getName supports overloads.
|
||||
/// This is less efficient than the StringRef version of this function. If no
|
||||
/// overloads are required, it is safe to use this version, but better to use
|
||||
/// the StringRef version. A function type FT can be provided to avoid
|
||||
/// computing it. It is used (or computed) if one of the types is based on an
|
||||
/// unnamed type.
|
||||
std::string getName(ID Id, ArrayRef<Type *> Tys, Module *M, FunctionType *FT);
|
||||
/// the StringRef version. If one of the types is based on an unnamed type, a
|
||||
/// function type will be computed. Providing FT will avoid this computation.
|
||||
std::string getName(ID Id, ArrayRef<Type *> Tys, Module *M,
|
||||
FunctionType *FT = nullptr);
|
||||
|
||||
/// Return the LLVM name for an intrinsic. This is a special version only to
|
||||
/// be used by LLVMIntrinsicCopyOverloadedName. It only supports overloads
|
||||
/// based on named types.
|
||||
std::string getNameNoUnnamedTypes(ID Id, ArrayRef<Type *> Tys);
|
||||
|
||||
/// Return the function type for an intrinsic.
|
||||
FunctionType *getType(LLVMContext &Context, ID id,
|
||||
|
@ -935,7 +935,7 @@ void MachineOperand::print(raw_ostream &OS, ModuleSlotTracker &MST,
|
||||
case MachineOperand::MO_IntrinsicID: {
|
||||
Intrinsic::ID ID = getIntrinsicID();
|
||||
if (ID < Intrinsic::num_intrinsics)
|
||||
OS << "intrinsic(@" << Intrinsic::getName(ID, None) << ')';
|
||||
OS << "intrinsic(@" << Intrinsic::getBaseName(ID) << ')';
|
||||
else if (IntrinsicInfo)
|
||||
OS << "intrinsic(@" << IntrinsicInfo->getName(ID) << ')';
|
||||
else
|
||||
|
@ -142,7 +142,7 @@ static bool replaceWithCallToVeclib(const TargetLibraryInfo &TLI,
|
||||
// converted to scalar above.
|
||||
std::string ScalarName;
|
||||
if (Intrinsic::isOverloaded(IntrinsicID)) {
|
||||
ScalarName = Intrinsic::getName(IntrinsicID, ScalarTypes);
|
||||
ScalarName = Intrinsic::getName(IntrinsicID, ScalarTypes, CI.getModule());
|
||||
} else {
|
||||
ScalarName = Intrinsic::getName(IntrinsicID).str();
|
||||
}
|
||||
|
@ -145,7 +145,7 @@ std::string SDNode::getOperationName(const SelectionDAG *G) const {
|
||||
unsigned OpNo = getOpcode() == ISD::INTRINSIC_WO_CHAIN ? 0 : 1;
|
||||
unsigned IID = cast<ConstantSDNode>(getOperand(OpNo))->getZExtValue();
|
||||
if (IID < Intrinsic::num_intrinsics)
|
||||
return Intrinsic::getName((Intrinsic::ID)IID, None);
|
||||
return Intrinsic::getBaseName((Intrinsic::ID)IID).str();
|
||||
else if (!G)
|
||||
return "Unknown intrinsic";
|
||||
else if (const TargetIntrinsicInfo *TII = G->getTarget().getIntrinsicInfo())
|
||||
|
@ -3777,7 +3777,7 @@ void SelectionDAGISel::CannotYetSelect(SDNode *N) {
|
||||
unsigned iid =
|
||||
cast<ConstantSDNode>(N->getOperand(HasInputChain))->getZExtValue();
|
||||
if (iid < Intrinsic::num_intrinsics)
|
||||
Msg << "intrinsic %" << Intrinsic::getName((Intrinsic::ID)iid, None);
|
||||
Msg << "intrinsic %" << Intrinsic::getBaseName((Intrinsic::ID)iid);
|
||||
else if (const TargetIntrinsicInfo *TII = TM.getIntrinsicInfo())
|
||||
Msg << "target intrinsic %" << TII->getName(iid);
|
||||
else
|
||||
|
@ -778,7 +778,7 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) {
|
||||
Intrinsic::lifetime_start : Intrinsic::invariant_start;
|
||||
auto Args = F->getFunctionType()->params();
|
||||
Type* ObjectPtr[1] = {Args[1]};
|
||||
if (F->getName() != Intrinsic::getName(ID, ObjectPtr)) {
|
||||
if (F->getName() != Intrinsic::getName(ID, ObjectPtr, F->getParent())) {
|
||||
rename(F);
|
||||
NewFn = Intrinsic::getDeclaration(F->getParent(), ID, ObjectPtr);
|
||||
return true;
|
||||
@ -792,7 +792,7 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) {
|
||||
|
||||
auto Args = F->getFunctionType()->params();
|
||||
Type* ObjectPtr[1] = {Args[IsLifetimeEnd ? 1 : 2]};
|
||||
if (F->getName() != Intrinsic::getName(ID, ObjectPtr)) {
|
||||
if (F->getName() != Intrinsic::getName(ID, ObjectPtr, F->getParent())) {
|
||||
rename(F);
|
||||
NewFn = Intrinsic::getDeclaration(F->getParent(), ID, ObjectPtr);
|
||||
return true;
|
||||
@ -814,7 +814,8 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) {
|
||||
case 'm': {
|
||||
if (Name.startswith("masked.load.")) {
|
||||
Type *Tys[] = { F->getReturnType(), F->arg_begin()->getType() };
|
||||
if (F->getName() != Intrinsic::getName(Intrinsic::masked_load, Tys)) {
|
||||
if (F->getName() !=
|
||||
Intrinsic::getName(Intrinsic::masked_load, Tys, F->getParent())) {
|
||||
rename(F);
|
||||
NewFn = Intrinsic::getDeclaration(F->getParent(),
|
||||
Intrinsic::masked_load,
|
||||
@ -825,7 +826,8 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) {
|
||||
if (Name.startswith("masked.store.")) {
|
||||
auto Args = F->getFunctionType()->params();
|
||||
Type *Tys[] = { Args[0], Args[1] };
|
||||
if (F->getName() != Intrinsic::getName(Intrinsic::masked_store, Tys)) {
|
||||
if (F->getName() !=
|
||||
Intrinsic::getName(Intrinsic::masked_store, Tys, F->getParent())) {
|
||||
rename(F);
|
||||
NewFn = Intrinsic::getDeclaration(F->getParent(),
|
||||
Intrinsic::masked_store,
|
||||
@ -837,7 +839,8 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) {
|
||||
// to the new overload which includes an address space
|
||||
if (Name.startswith("masked.gather.")) {
|
||||
Type *Tys[] = {F->getReturnType(), F->arg_begin()->getType()};
|
||||
if (F->getName() != Intrinsic::getName(Intrinsic::masked_gather, Tys)) {
|
||||
if (F->getName() !=
|
||||
Intrinsic::getName(Intrinsic::masked_gather, Tys, F->getParent())) {
|
||||
rename(F);
|
||||
NewFn = Intrinsic::getDeclaration(F->getParent(),
|
||||
Intrinsic::masked_gather, Tys);
|
||||
@ -847,7 +850,8 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) {
|
||||
if (Name.startswith("masked.scatter.")) {
|
||||
auto Args = F->getFunctionType()->params();
|
||||
Type *Tys[] = {Args[0], Args[1]};
|
||||
if (F->getName() != Intrinsic::getName(Intrinsic::masked_scatter, Tys)) {
|
||||
if (F->getName() !=
|
||||
Intrinsic::getName(Intrinsic::masked_scatter, Tys, F->getParent())) {
|
||||
rename(F);
|
||||
NewFn = Intrinsic::getDeclaration(F->getParent(),
|
||||
Intrinsic::masked_scatter, Tys);
|
||||
@ -928,7 +932,8 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) {
|
||||
if (Name.startswith("objectsize.")) {
|
||||
Type *Tys[2] = { F->getReturnType(), F->arg_begin()->getType() };
|
||||
if (F->arg_size() == 2 || F->arg_size() == 3 ||
|
||||
F->getName() != Intrinsic::getName(Intrinsic::objectsize, Tys)) {
|
||||
F->getName() !=
|
||||
Intrinsic::getName(Intrinsic::objectsize, Tys, F->getParent())) {
|
||||
rename(F);
|
||||
NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::objectsize,
|
||||
Tys);
|
||||
@ -941,7 +946,8 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) {
|
||||
if (Name == "prefetch") {
|
||||
// Handle address space overloading.
|
||||
Type *Tys[] = {F->arg_begin()->getType()};
|
||||
if (F->getName() != Intrinsic::getName(Intrinsic::prefetch, Tys)) {
|
||||
if (F->getName() !=
|
||||
Intrinsic::getName(Intrinsic::prefetch, Tys, F->getParent())) {
|
||||
rename(F);
|
||||
NewFn =
|
||||
Intrinsic::getDeclaration(F->getParent(), Intrinsic::prefetch, Tys);
|
||||
|
@ -2411,7 +2411,18 @@ const char *LLVMIntrinsicCopyOverloadedName(unsigned ID,
|
||||
size_t *NameLength) {
|
||||
auto IID = llvm_map_to_intrinsic_id(ID);
|
||||
ArrayRef<Type*> Tys(unwrap(ParamTypes), ParamCount);
|
||||
auto Str = llvm::Intrinsic::getName(IID, Tys);
|
||||
auto Str = llvm::Intrinsic::getNameNoUnnamedTypes(IID, Tys);
|
||||
*NameLength = Str.length();
|
||||
return strdup(Str.c_str());
|
||||
}
|
||||
|
||||
const char *LLVMIntrinsicCopyOverloadedName2(LLVMModuleRef Mod, unsigned ID,
|
||||
LLVMTypeRef *ParamTypes,
|
||||
size_t ParamCount,
|
||||
size_t *NameLength) {
|
||||
auto IID = llvm_map_to_intrinsic_id(ID);
|
||||
ArrayRef<Type *> Tys(unwrap(ParamTypes), ParamCount);
|
||||
auto Str = llvm::Intrinsic::getName(IID, Tys, unwrap(Mod));
|
||||
*NameLength = Str.length();
|
||||
return strdup(Str.c_str());
|
||||
}
|
||||
|
@ -831,37 +831,53 @@ static std::string getMangledTypeStr(Type *Ty, bool &HasUnnamedType) {
|
||||
return Result;
|
||||
}
|
||||
|
||||
StringRef Intrinsic::getBaseName(ID id) {
|
||||
assert(id < num_intrinsics && "Invalid intrinsic ID!");
|
||||
return IntrinsicNameTable[id];
|
||||
}
|
||||
|
||||
StringRef Intrinsic::getName(ID id) {
|
||||
assert(id < num_intrinsics && "Invalid intrinsic ID!");
|
||||
assert(!Intrinsic::isOverloaded(id) &&
|
||||
"This version of getName does not support overloading");
|
||||
return IntrinsicNameTable[id];
|
||||
return getBaseName(id);
|
||||
}
|
||||
|
||||
std::string Intrinsic::getName(ID Id, ArrayRef<Type *> Tys, Module *M,
|
||||
FunctionType *FT) {
|
||||
assert(Id < num_intrinsics && "Invalid intrinsic ID!");
|
||||
static std::string getIntrinsicNameImpl(Intrinsic::ID Id, ArrayRef<Type *> Tys,
|
||||
Module *M, FunctionType *FT,
|
||||
bool EarlyModuleCheck) {
|
||||
|
||||
assert(Id < Intrinsic::num_intrinsics && "Invalid intrinsic ID!");
|
||||
assert((Tys.empty() || Intrinsic::isOverloaded(Id)) &&
|
||||
"This version of getName is for overloaded intrinsics only");
|
||||
(void)EarlyModuleCheck;
|
||||
assert((!EarlyModuleCheck || M ||
|
||||
!any_of(Tys, [](Type *T) { return isa<PointerType>(T); })) &&
|
||||
"Intrinsic overloading on pointer types need to provide a Module");
|
||||
bool HasUnnamedType = false;
|
||||
std::string Result(IntrinsicNameTable[Id]);
|
||||
for (Type *Ty : Tys) {
|
||||
std::string Result(Intrinsic::getBaseName(Id));
|
||||
for (Type *Ty : Tys)
|
||||
Result += "." + getMangledTypeStr(Ty, HasUnnamedType);
|
||||
}
|
||||
assert((M || !HasUnnamedType) && "unnamed types need a module");
|
||||
if (M && HasUnnamedType) {
|
||||
if (HasUnnamedType) {
|
||||
assert(M && "unnamed types need a module");
|
||||
if (!FT)
|
||||
FT = getType(M->getContext(), Id, Tys);
|
||||
FT = Intrinsic::getType(M->getContext(), Id, Tys);
|
||||
else
|
||||
assert((FT == getType(M->getContext(), Id, Tys)) &&
|
||||
assert((FT == Intrinsic::getType(M->getContext(), Id, Tys)) &&
|
||||
"Provided FunctionType must match arguments");
|
||||
return M->getUniqueIntrinsicName(Result, Id, FT);
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
std::string Intrinsic::getName(ID Id, ArrayRef<Type *> Tys) {
|
||||
return getName(Id, Tys, nullptr, nullptr);
|
||||
std::string Intrinsic::getName(ID Id, ArrayRef<Type *> Tys, Module *M,
|
||||
FunctionType *FT) {
|
||||
assert(M && "We need to have a Module");
|
||||
return getIntrinsicNameImpl(Id, Tys, M, FT, true);
|
||||
}
|
||||
|
||||
std::string Intrinsic::getNameNoUnnamedTypes(ID Id, ArrayRef<Type *> Tys) {
|
||||
return getIntrinsicNameImpl(Id, Tys, nullptr, nullptr, false);
|
||||
}
|
||||
|
||||
/// IIT_Info - These are enumerators that describe the entries returned by the
|
||||
|
@ -1841,7 +1841,7 @@ public:
|
||||
return;
|
||||
}
|
||||
IntrinsicInst *II = dyn_cast<IntrinsicInst>(CI);
|
||||
write(StringRef(Intrinsic::getName(II->getIntrinsicID(), {}))
|
||||
write(Intrinsic::getBaseName(II->getIntrinsicID())
|
||||
.drop_front(StringRef("llvm.matrix.").size()));
|
||||
write(".");
|
||||
std::string Tmp;
|
||||
|
@ -2,15 +2,14 @@
|
||||
; RUN: llvm-as < %s | llvm-dis | FileCheck %s
|
||||
; RUN: verify-uselistorder %s
|
||||
|
||||
%0 = type opaque;
|
||||
|
||||
declare i8 @llvm.ctlz.i8(i8)
|
||||
declare i16 @llvm.ctlz.i16(i16)
|
||||
declare i32 @llvm.ctlz.i32(i32)
|
||||
declare i42 @llvm.ctlz.i42(i42) ; Not a power-of-2
|
||||
|
||||
|
||||
declare i32 @llvm.objectsize.i32(i8*, i1) nounwind readonly
|
||||
|
||||
|
||||
define void @test.ctlz(i8 %a, i16 %b, i32 %c, i42 %d) {
|
||||
; CHECK: @test.ctlz
|
||||
|
||||
@ -51,6 +50,7 @@ entry:
|
||||
|
||||
@a = private global [60 x i8] zeroinitializer, align 1
|
||||
|
||||
declare i32 @llvm.objectsize.i32(i8*, i1) nounwind readonly
|
||||
define i32 @test.objectsize() {
|
||||
; CHECK-LABEL: @test.objectsize(
|
||||
; CHECK: @llvm.objectsize.i32.p0i8(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i1 false, i1 false, i1 false)
|
||||
@ -66,6 +66,24 @@ define i64 @test.objectsize.2() {
|
||||
ret i64 %s
|
||||
}
|
||||
|
||||
@u = private global [60 x %0*] zeroinitializer, align 1
|
||||
|
||||
declare i32 @llvm.objectsize.i32.unnamed(%0**, i1) nounwind readonly
|
||||
define i32 @test.objectsize.unnamed() {
|
||||
; CHECK-LABEL: @test.objectsize.unnamed(
|
||||
; CHECK: @llvm.objectsize.i32.p0p0s_s.0(%0** getelementptr inbounds ([60 x %0*], [60 x %0*]* @u, i32 0, i32 0), i1 false, i1 false, i1 false)
|
||||
%s = call i32 @llvm.objectsize.i32.unnamed(%0** getelementptr inbounds ([60 x %0*], [60 x %0*]* @u, i32 0, i32 0), i1 false)
|
||||
ret i32 %s
|
||||
}
|
||||
|
||||
declare i64 @llvm.objectsize.i64.p0p0s_s.0(%0**, i1) nounwind readonly
|
||||
define i64 @test.objectsize.unnamed.2() {
|
||||
; CHECK-LABEL: @test.objectsize.unnamed.2(
|
||||
; CHECK: @llvm.objectsize.i64.p0p0s_s.0(%0** getelementptr inbounds ([60 x %0*], [60 x %0*]* @u, i32 0, i32 0), i1 false, i1 false, i1 false)
|
||||
%s = call i64 @llvm.objectsize.i64.p0p0s_s.0(%0** getelementptr inbounds ([60 x %0*], [60 x %0*]* @u, i32 0, i32 0), i1 false)
|
||||
ret i64 %s
|
||||
}
|
||||
|
||||
declare <2 x double> @llvm.masked.load.v2f64(<2 x double>* %ptrs, i32, <2 x i1> %mask, <2 x double> %src0)
|
||||
|
||||
define <2 x double> @tests.masked.load(<2 x double>* %ptr, <2 x i1> %mask, <2 x double> %passthru) {
|
||||
@ -116,6 +134,20 @@ define void @tests.invariant.start.end() {
|
||||
ret void
|
||||
}
|
||||
|
||||
declare {}* @llvm.invariant.start.unnamed(i64, %0** nocapture) nounwind readonly
|
||||
declare void @llvm.invariant.end.unnamed({}*, i64, %0** nocapture) nounwind
|
||||
|
||||
define void @tests.invariant.start.end.unnamed() {
|
||||
; CHECK-LABEL: @tests.invariant.start.end.unnamed(
|
||||
%a = alloca %0*
|
||||
%i = call {}* @llvm.invariant.start.unnamed(i64 1, %0** %a)
|
||||
; CHECK: call {}* @llvm.invariant.start.p0p0s_s.0
|
||||
store %0* null, %0** %a
|
||||
call void @llvm.invariant.end.unnamed({}* %i, i64 1, %0** %a)
|
||||
; CHECK: call void @llvm.invariant.end.p0p0s_s.0
|
||||
ret void
|
||||
}
|
||||
|
||||
@__stack_chk_guard = external global i8*
|
||||
declare void @llvm.stackprotectorcheck(i8**)
|
||||
|
||||
@ -140,6 +172,20 @@ define void @tests.lifetime.start.end() {
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @llvm.lifetime.start.unnamed(i64, %0** nocapture) nounwind readonly
|
||||
declare void @llvm.lifetime.end.unnamed(i64, %0** nocapture) nounwind
|
||||
|
||||
define void @tests.lifetime.start.end.unnamed() {
|
||||
; CHECK-LABEL: @tests.lifetime.start.end.unnamed(
|
||||
%a = alloca %0*
|
||||
call void @llvm.lifetime.start.unnamed(i64 1, %0** %a)
|
||||
; CHECK: call void @llvm.lifetime.start.p0p0s_s.0(i64 1, %0** %a)
|
||||
store %0* null, %0** %a
|
||||
call void @llvm.lifetime.end.unnamed(i64 1, %0** %a)
|
||||
; CHECK: call void @llvm.lifetime.end.p0p0s_s.0(i64 1, %0** %a)
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @llvm.prefetch(i8*, i32, i32, i32)
|
||||
define void @test.prefetch(i8* %ptr) {
|
||||
; CHECK-LABEL: @test.prefetch(
|
||||
@ -156,10 +202,20 @@ define void @test.prefetch.2(i8* %ptr) {
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @llvm.prefetch.unnamed(%0**, i32, i32, i32)
|
||||
define void @test.prefetch.unnamed(%0** %ptr) {
|
||||
; CHECK-LABEL: @test.prefetch.unnamed(
|
||||
; CHECK: @llvm.prefetch.p0p0s_s.0(%0** %ptr, i32 0, i32 3, i32 2)
|
||||
call void @llvm.prefetch.unnamed(%0** %ptr, i32 0, i32 3, i32 2)
|
||||
ret void
|
||||
}
|
||||
|
||||
; This is part of @test.objectsize(), since llvm.objectsize declaration gets
|
||||
; emitted at the end.
|
||||
; CHECK: declare i32 @llvm.objectsize.i32.p0i8
|
||||
|
||||
; CHECK: declare i32 @llvm.objectsize.i32.p0p0s_s.0
|
||||
|
||||
; CHECK: declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture)
|
||||
; CHECK: declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture)
|
||||
; CHECK: declare void @llvm.lifetime.start.p0p0s_s.0(i64 immarg, %0** nocapture)
|
||||
; CHECK: declare void @llvm.lifetime.end.p0p0s_s.0(i64 immarg, %0** nocapture)
|
||||
|
Loading…
Reference in New Issue
Block a user