1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-25 04:02:41 +01:00

[OpaquePtr] Remove checking pointee type for byval/preallocated type

These currently always require a type parameter. The bitcode reader
already upgrades old bitcode without the type parameter to use the
pointee type.

In cases where the caller does not have byval but the callee does, we
need to follow CallBase::paramHasAttr() and also look at the callee for
the byval type so that CallBase::isByValArgument() and
CallBase::getParamByValType() are in sync. Do the same for preallocated.

While we're here add a corresponding version for inalloca since we'll
need it soon.

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D104663
This commit is contained in:
Arthur Eubanks 2021-07-07 14:28:41 -07:00
parent 6032fd6068
commit b3ffc2a93b
2 changed files with 64 additions and 5 deletions

View File

@ -1728,14 +1728,29 @@ public:
/// Extract the byval type for a call or parameter. /// Extract the byval type for a call or parameter.
Type *getParamByValType(unsigned ArgNo) const { Type *getParamByValType(unsigned ArgNo) const {
Type *Ty = Attrs.getParamByValType(ArgNo); if (auto *Ty = Attrs.getParamByValType(ArgNo))
return Ty ? Ty : getArgOperand(ArgNo)->getType()->getPointerElementType(); return Ty;
if (const Function *F = getCalledFunction())
return F->getAttributes().getParamByValType(ArgNo);
return nullptr;
} }
/// Extract the preallocated type for a call or parameter. /// Extract the preallocated type for a call or parameter.
Type *getParamPreallocatedType(unsigned ArgNo) const { Type *getParamPreallocatedType(unsigned ArgNo) const {
Type *Ty = Attrs.getParamPreallocatedType(ArgNo); if (auto *Ty = Attrs.getParamPreallocatedType(ArgNo))
return Ty ? Ty : getArgOperand(ArgNo)->getType()->getPointerElementType(); return Ty;
if (const Function *F = getCalledFunction())
return F->getAttributes().getParamPreallocatedType(ArgNo);
return nullptr;
}
/// Extract the preallocated type for a call or parameter.
Type *getParamInAllocaType(unsigned ArgNo) const {
if (auto *Ty = Attrs.getParamInAllocaType(ArgNo))
return Ty;
if (const Function *F = getCalledFunction())
return F->getAttributes().getParamInAllocaType(ArgNo);
return nullptr;
} }
/// Extract the number of dereferenceable bytes for a call or /// Extract the number of dereferenceable bytes for a call or

View File

@ -7,8 +7,12 @@
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "llvm/IR/Attributes.h" #include "llvm/IR/Attributes.h"
#include "llvm/IR/LLVMContext.h" #include "llvm/AsmParser/Parser.h"
#include "llvm/IR/DerivedTypes.h" #include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/SourceMgr.h"
#include "gtest/gtest.h" #include "gtest/gtest.h"
using namespace llvm; using namespace llvm;
@ -252,4 +256,44 @@ TEST(Attributes, AttributeListPrinting) {
} }
} }
TEST(Attributes, MismatchedABIAttrs) {
const char *IRString = R"IR(
declare void @f1(i32* byval(i32))
define void @g() {
call void @f1(i32* null)
ret void
}
declare void @f2(i32* preallocated(i32))
define void @h() {
call void @f2(i32* null)
ret void
}
declare void @f3(i32* inalloca(i32))
define void @i() {
call void @f3(i32* null)
ret void
}
)IR";
SMDiagnostic Err;
LLVMContext Context;
std::unique_ptr<Module> M = parseAssemblyString(IRString, Err, Context);
ASSERT_TRUE(M);
{
auto *I = cast<CallBase>(&M->getFunction("g")->getEntryBlock().front());
ASSERT_TRUE(I->isByValArgument(0));
ASSERT_TRUE(I->getParamByValType(0));
}
{
auto *I = cast<CallBase>(&M->getFunction("h")->getEntryBlock().front());
ASSERT_TRUE(I->getParamPreallocatedType(0));
}
{
auto *I = cast<CallBase>(&M->getFunction("i")->getEntryBlock().front());
ASSERT_TRUE(I->isInAllocaArgument(0));
ASSERT_TRUE(I->getParamInAllocaType(0));
}
}
} // end anonymous namespace } // end anonymous namespace