mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-29 14:20:29 +00:00
Swift Calling Convention: add swiftself attribute.
Differential Revision: http://reviews.llvm.org/D17866 llvm-svn: 264754
This commit is contained in:
parent
555db84966
commit
620c905661
@ -1058,6 +1058,11 @@ Currently, only the following parameter attributes are defined:
|
||||
``dereferenceable(<n>)``). This attribute may only be applied to
|
||||
pointer typed parameters.
|
||||
|
||||
``swiftself``
|
||||
This indicates that the parameter is the self/context parameter. This is not
|
||||
a valid attribute for return values and can only be applied to one
|
||||
parameter.
|
||||
|
||||
.. _gc:
|
||||
|
||||
Garbage Collector Strategy Names
|
||||
|
@ -94,6 +94,7 @@ typedef enum {
|
||||
LLVMJumpTableAttribute = 1ULL << 45,
|
||||
LLVMConvergentAttribute = 1ULL << 46,
|
||||
LLVMSafeStackAttribute = 1ULL << 47,
|
||||
LLVMSwiftSelfAttribute = 1ULL << 48,
|
||||
*/
|
||||
} LLVMAttribute;
|
||||
|
||||
|
@ -40,12 +40,14 @@ public:
|
||||
bool IsByVal : 1;
|
||||
bool IsInAlloca : 1;
|
||||
bool IsReturned : 1;
|
||||
bool IsSwiftSelf : 1;
|
||||
uint16_t Alignment;
|
||||
|
||||
ArgListEntry()
|
||||
: Val(nullptr), Ty(nullptr), IsSExt(false), IsZExt(false),
|
||||
IsInReg(false), IsSRet(false), IsNest(false), IsByVal(false),
|
||||
IsInAlloca(false), IsReturned(false), Alignment(0) {}
|
||||
IsInAlloca(false), IsReturned(false), IsSwiftSelf(false),
|
||||
Alignment(0) {}
|
||||
|
||||
/// \brief Set CallLoweringInfo attribute flags based on a call instruction
|
||||
/// and called function attributes.
|
||||
|
@ -73,6 +73,9 @@ public:
|
||||
/// containing function.
|
||||
bool hasByValAttr() const;
|
||||
|
||||
/// \brief Return true if this argument has the swiftself attribute.
|
||||
bool hasSwiftSelfAttr() const;
|
||||
|
||||
/// \brief Return true if this argument has the byval attribute or inalloca
|
||||
/// attribute on it in its containing function. These attributes both
|
||||
/// represent arguments being passed by value.
|
||||
|
@ -154,6 +154,9 @@ def SanitizeThread : EnumAttr<"sanitize_thread">;
|
||||
/// MemorySanitizer is on.
|
||||
def SanitizeMemory : EnumAttr<"sanitize_memory">;
|
||||
|
||||
/// Argument is swift self/context.
|
||||
def SwiftSelf : EnumAttr<"swiftself">;
|
||||
|
||||
/// Function must be in a unwind table.
|
||||
def UWTable : EnumAttr<"uwtable">;
|
||||
|
||||
|
@ -48,6 +48,8 @@ namespace ISD {
|
||||
static const uint64_t InAllocaOffs = 12;
|
||||
static const uint64_t SplitEnd = 1ULL<<13; ///< Last part of a split
|
||||
static const uint64_t SplitEndOffs = 13;
|
||||
static const uint64_t SwiftSelf = 1ULL<<14; ///< Swift self parameter
|
||||
static const uint64_t SwiftSelfOffs = 14;
|
||||
static const uint64_t OrigAlign = 0x1FULL<<27;
|
||||
static const uint64_t OrigAlignOffs = 27;
|
||||
static const uint64_t ByValSize = 0x3fffffffULL<<32; ///< Struct size
|
||||
@ -82,6 +84,9 @@ namespace ISD {
|
||||
bool isInAlloca() const { return Flags & InAlloca; }
|
||||
void setInAlloca() { Flags |= One << InAllocaOffs; }
|
||||
|
||||
bool isSwiftSelf() const { return Flags & SwiftSelf; }
|
||||
void setSwiftSelf() { Flags |= One << SwiftSelfOffs; }
|
||||
|
||||
bool isNest() const { return Flags & Nest; }
|
||||
void setNest() { Flags |= One << NestOffs; }
|
||||
|
||||
|
@ -42,6 +42,11 @@ class CCIf<string predicate, CCAction A> : CCPredicateAction<A> {
|
||||
class CCIfByVal<CCAction A> : CCIf<"ArgFlags.isByVal()", A> {
|
||||
}
|
||||
|
||||
/// CCIfSwiftSelf - If the current argument has swiftself parameter attribute,
|
||||
/// apply Action A.
|
||||
class CCIfSwiftSelf<CCAction A> : CCIf<"ArgFlags.isSwiftSelf()", A> {
|
||||
}
|
||||
|
||||
/// CCIfConsecutiveRegs - If the current argument has InConsecutiveRegs
|
||||
/// parameter attribute, apply Action A.
|
||||
class CCIfConsecutiveRegs<CCAction A> : CCIf<"ArgFlags.isInConsecutiveRegs()", A> {
|
||||
|
@ -2326,11 +2326,12 @@ public:
|
||||
bool isByVal : 1;
|
||||
bool isInAlloca : 1;
|
||||
bool isReturned : 1;
|
||||
bool isSwiftSelf : 1;
|
||||
uint16_t Alignment;
|
||||
|
||||
ArgListEntry() : isSExt(false), isZExt(false), isInReg(false),
|
||||
isSRet(false), isNest(false), isByVal(false), isInAlloca(false),
|
||||
isReturned(false), Alignment(0) { }
|
||||
isReturned(false), isSwiftSelf(false), Alignment(0) { }
|
||||
|
||||
void setAttributes(ImmutableCallSite *CS, unsigned AttrIdx);
|
||||
};
|
||||
|
@ -647,6 +647,7 @@ lltok::Kind LLLexer::LexIdentifier() {
|
||||
KEYWORD(sanitize_address);
|
||||
KEYWORD(sanitize_thread);
|
||||
KEYWORD(sanitize_memory);
|
||||
KEYWORD(swiftself);
|
||||
KEYWORD(uwtable);
|
||||
KEYWORD(zeroext);
|
||||
|
||||
|
@ -1071,6 +1071,7 @@ bool LLParser::ParseFnAttributeValuePairs(AttrBuilder &B,
|
||||
case lltok::kw_nonnull:
|
||||
case lltok::kw_returned:
|
||||
case lltok::kw_sret:
|
||||
case lltok::kw_swiftself:
|
||||
HaveError |=
|
||||
Error(Lex.getLoc(),
|
||||
"invalid use of parameter-only attribute on a function");
|
||||
@ -1344,6 +1345,7 @@ bool LLParser::ParseOptionalParamAttrs(AttrBuilder &B) {
|
||||
case lltok::kw_returned: B.addAttribute(Attribute::Returned); break;
|
||||
case lltok::kw_signext: B.addAttribute(Attribute::SExt); break;
|
||||
case lltok::kw_sret: B.addAttribute(Attribute::StructRet); break;
|
||||
case lltok::kw_swiftself: B.addAttribute(Attribute::SwiftSelf); break;
|
||||
case lltok::kw_zeroext: B.addAttribute(Attribute::ZExt); break;
|
||||
|
||||
case lltok::kw_alignstack:
|
||||
@ -1431,6 +1433,7 @@ bool LLParser::ParseOptionalReturnAttrs(AttrBuilder &B) {
|
||||
case lltok::kw_nocapture:
|
||||
case lltok::kw_returned:
|
||||
case lltok::kw_sret:
|
||||
case lltok::kw_swiftself:
|
||||
HaveError |= Error(Lex.getLoc(), "invalid use of parameter-only attribute");
|
||||
break;
|
||||
|
||||
|
@ -151,6 +151,7 @@ namespace lltok {
|
||||
kw_sret,
|
||||
kw_sanitize_thread,
|
||||
kw_sanitize_memory,
|
||||
kw_swiftself,
|
||||
kw_uwtable,
|
||||
kw_zeroext,
|
||||
|
||||
|
@ -1325,6 +1325,8 @@ static Attribute::AttrKind getAttrFromCode(uint64_t Code) {
|
||||
return Attribute::SanitizeThread;
|
||||
case bitc::ATTR_KIND_SANITIZE_MEMORY:
|
||||
return Attribute::SanitizeMemory;
|
||||
case bitc::ATTR_KIND_SWIFT_SELF:
|
||||
return Attribute::SwiftSelf;
|
||||
case bitc::ATTR_KIND_UW_TABLE:
|
||||
return Attribute::UWTable;
|
||||
case bitc::ATTR_KIND_Z_EXT:
|
||||
|
@ -259,6 +259,8 @@ static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind) {
|
||||
return bitc::ATTR_KIND_SANITIZE_THREAD;
|
||||
case Attribute::SanitizeMemory:
|
||||
return bitc::ATTR_KIND_SANITIZE_MEMORY;
|
||||
case Attribute::SwiftSelf:
|
||||
return bitc::ATTR_KIND_SWIFT_SELF;
|
||||
case Attribute::UWTable:
|
||||
return bitc::ATTR_KIND_UW_TABLE;
|
||||
case Attribute::ZExt:
|
||||
|
@ -89,6 +89,7 @@ void FastISel::ArgListEntry::setAttributes(ImmutableCallSite *CS,
|
||||
IsByVal = CS->paramHasAttr(AttrIdx, Attribute::ByVal);
|
||||
IsInAlloca = CS->paramHasAttr(AttrIdx, Attribute::InAlloca);
|
||||
IsReturned = CS->paramHasAttr(AttrIdx, Attribute::Returned);
|
||||
IsSwiftSelf = CS->paramHasAttr(AttrIdx, Attribute::SwiftSelf);
|
||||
Alignment = CS->getParamAlignment(AttrIdx);
|
||||
}
|
||||
|
||||
@ -957,6 +958,8 @@ bool FastISel::lowerCallTo(CallLoweringInfo &CLI) {
|
||||
Flags.setInReg();
|
||||
if (Arg.IsSRet)
|
||||
Flags.setSRet();
|
||||
if (Arg.IsSwiftSelf)
|
||||
Flags.setSwiftSelf();
|
||||
if (Arg.IsByVal)
|
||||
Flags.setByVal();
|
||||
if (Arg.IsInAlloca) {
|
||||
|
@ -7281,6 +7281,7 @@ TargetLowering::LowerCallTo(TargetLowering::CallLoweringInfo &CLI) const {
|
||||
Entry.isNest = false;
|
||||
Entry.isByVal = false;
|
||||
Entry.isReturned = false;
|
||||
Entry.isSwiftSelf = false;
|
||||
Entry.Alignment = Align;
|
||||
CLI.getArgs().insert(CLI.getArgs().begin(), Entry);
|
||||
CLI.RetTy = Type::getVoidTy(CLI.RetTy->getContext());
|
||||
@ -7338,6 +7339,8 @@ TargetLowering::LowerCallTo(TargetLowering::CallLoweringInfo &CLI) const {
|
||||
Flags.setInReg();
|
||||
if (Args[i].isSRet)
|
||||
Flags.setSRet();
|
||||
if (Args[i].isSwiftSelf)
|
||||
Flags.setSwiftSelf();
|
||||
if (Args[i].isByVal)
|
||||
Flags.setByVal();
|
||||
if (Args[i].isInAlloca) {
|
||||
@ -7617,6 +7620,8 @@ void SelectionDAGISel::LowerArguments(const Function &F) {
|
||||
Flags.setInReg();
|
||||
if (F.getAttributes().hasAttribute(Idx, Attribute::StructRet))
|
||||
Flags.setSRet();
|
||||
if (F.getAttributes().hasAttribute(Idx, Attribute::SwiftSelf))
|
||||
Flags.setSwiftSelf();
|
||||
if (F.getAttributes().hasAttribute(Idx, Attribute::ByVal))
|
||||
Flags.setByVal();
|
||||
if (F.getAttributes().hasAttribute(Idx, Attribute::InAlloca)) {
|
||||
|
@ -77,6 +77,7 @@ void TargetLowering::ArgListEntry::setAttributes(ImmutableCallSite *CS,
|
||||
isByVal = CS->paramHasAttr(AttrIdx, Attribute::ByVal);
|
||||
isInAlloca = CS->paramHasAttr(AttrIdx, Attribute::InAlloca);
|
||||
isReturned = CS->paramHasAttr(AttrIdx, Attribute::Returned);
|
||||
isSwiftSelf = CS->paramHasAttr(AttrIdx, Attribute::SwiftSelf);
|
||||
Alignment = CS->getParamAlignment(AttrIdx);
|
||||
}
|
||||
|
||||
|
@ -195,6 +195,8 @@ std::string Attribute::getAsString(bool InAttrGrp) const {
|
||||
return "byval";
|
||||
if (hasAttribute(Attribute::Convergent))
|
||||
return "convergent";
|
||||
if (hasAttribute(Attribute::SwiftSelf))
|
||||
return "swiftself";
|
||||
if (hasAttribute(Attribute::InaccessibleMemOnly))
|
||||
return "inaccessiblememonly";
|
||||
if (hasAttribute(Attribute::InaccessibleMemOrArgMemOnly))
|
||||
@ -448,6 +450,7 @@ uint64_t AttributeImpl::getAttrMask(Attribute::AttrKind Val) {
|
||||
case Attribute::NoRecurse: return 1ULL << 48;
|
||||
case Attribute::InaccessibleMemOnly: return 1ULL << 49;
|
||||
case Attribute::InaccessibleMemOrArgMemOnly: return 1ULL << 50;
|
||||
case Attribute::SwiftSelf: return 1ULL << 51;
|
||||
case Attribute::Dereferenceable:
|
||||
llvm_unreachable("dereferenceable attribute not supported in raw format");
|
||||
break;
|
||||
|
@ -92,6 +92,11 @@ bool Argument::hasByValAttr() const {
|
||||
return hasAttribute(Attribute::ByVal);
|
||||
}
|
||||
|
||||
bool Argument::hasSwiftSelfAttr() const {
|
||||
return getParent()->getAttributes().
|
||||
hasAttribute(getArgNo()+1, Attribute::SwiftSelf);
|
||||
}
|
||||
|
||||
/// \brief Return true if this argument has the inalloca attribute on it in
|
||||
/// its containing function.
|
||||
bool Argument::hasInAllocaAttr() const {
|
||||
|
@ -1344,9 +1344,11 @@ void Verifier::verifyParameterAttrs(AttributeSet Attrs, unsigned Idx, Type *Ty,
|
||||
!Attrs.hasAttribute(Idx, Attribute::StructRet) &&
|
||||
!Attrs.hasAttribute(Idx, Attribute::NoCapture) &&
|
||||
!Attrs.hasAttribute(Idx, Attribute::Returned) &&
|
||||
!Attrs.hasAttribute(Idx, Attribute::InAlloca),
|
||||
"Attributes 'byval', 'inalloca', 'nest', 'sret', 'nocapture', and "
|
||||
"'returned' do not apply to return values!",
|
||||
!Attrs.hasAttribute(Idx, Attribute::InAlloca) &&
|
||||
!Attrs.hasAttribute(Idx, Attribute::SwiftSelf),
|
||||
"Attributes 'byval', 'inalloca', 'nest', 'sret', 'nocapture', "
|
||||
"'returned', and 'swiftself' do not apply to return "
|
||||
"values!",
|
||||
V);
|
||||
|
||||
// Check for mutually incompatible attributes. Only inreg is compatible with
|
||||
@ -1423,6 +1425,7 @@ void Verifier::verifyFunctionAttrs(FunctionType *FT, AttributeSet Attrs,
|
||||
bool SawNest = false;
|
||||
bool SawReturned = false;
|
||||
bool SawSRet = false;
|
||||
bool SawSwiftSelf = false;
|
||||
|
||||
for (unsigned i = 0, e = Attrs.getNumSlots(); i != e; ++i) {
|
||||
unsigned Idx = Attrs.getSlotIndex(i);
|
||||
@ -1462,6 +1465,11 @@ void Verifier::verifyFunctionAttrs(FunctionType *FT, AttributeSet Attrs,
|
||||
SawSRet = true;
|
||||
}
|
||||
|
||||
if (Attrs.hasAttribute(Idx, Attribute::SwiftSelf)) {
|
||||
Assert(!SawSwiftSelf, "Cannot have multiple 'swiftself' parameters!", V);
|
||||
SawSwiftSelf = true;
|
||||
}
|
||||
|
||||
if (Attrs.hasAttribute(Idx, Attribute::InAlloca)) {
|
||||
Assert(Idx == FT->getNumParams(), "inalloca isn't on the last parameter!",
|
||||
V);
|
||||
@ -2554,7 +2562,7 @@ static bool isTypeCongruent(Type *L, Type *R) {
|
||||
static AttrBuilder getParameterABIAttributes(int I, AttributeSet Attrs) {
|
||||
static const Attribute::AttrKind ABIAttrs[] = {
|
||||
Attribute::StructRet, Attribute::ByVal, Attribute::InAlloca,
|
||||
Attribute::InReg, Attribute::Returned};
|
||||
Attribute::InReg, Attribute::Returned, Attribute::SwiftSelf};
|
||||
AttrBuilder Copy;
|
||||
for (auto AK : ABIAttrs) {
|
||||
if (Attrs.hasAttribute(I + 1, AK))
|
||||
|
@ -126,6 +126,9 @@ def CC_AArch64_DarwinPCS : CallingConv<[
|
||||
// slot is 64-bit.
|
||||
CCIfByVal<CCPassByVal<8, 8>>,
|
||||
|
||||
// A SwiftSelf is passed in X9.
|
||||
CCIfSwiftSelf<CCIfType<[i64], CCAssignToRegWithShadow<[X9], [W9]>>>,
|
||||
|
||||
CCIfConsecutiveRegs<CCCustom<"CC_AArch64_Custom_Block">>,
|
||||
|
||||
// Handle i1, i8, i16, i32, i64, f32, f64 and v2f64 by passing in registers,
|
||||
|
@ -2809,6 +2809,7 @@ bool AArch64FastISel::fastLowerArguments() {
|
||||
if (F->getAttributes().hasAttribute(Idx, Attribute::ByVal) ||
|
||||
F->getAttributes().hasAttribute(Idx, Attribute::InReg) ||
|
||||
F->getAttributes().hasAttribute(Idx, Attribute::StructRet) ||
|
||||
F->getAttributes().hasAttribute(Idx, Attribute::SwiftSelf) ||
|
||||
F->getAttributes().hasAttribute(Idx, Attribute::Nest))
|
||||
return false;
|
||||
|
||||
@ -3060,7 +3061,8 @@ bool AArch64FastISel::fastLowerCall(CallLoweringInfo &CLI) {
|
||||
return false;
|
||||
|
||||
for (auto Flag : CLI.OutFlags)
|
||||
if (Flag.isInReg() || Flag.isSRet() || Flag.isNest() || Flag.isByVal())
|
||||
if (Flag.isInReg() || Flag.isSRet() || Flag.isNest() || Flag.isByVal() ||
|
||||
Flag.isSwiftSelf())
|
||||
return false;
|
||||
|
||||
// Set up the argument vectors.
|
||||
|
@ -23,6 +23,9 @@ def CC_ARM_APCS : CallingConv<[
|
||||
|
||||
CCIfType<[i1, i8, i16], CCPromoteToType<i32>>,
|
||||
|
||||
// A SwiftSelf is passed in R9.
|
||||
CCIfSwiftSelf<CCIfType<[i32], CCAssignToReg<[R9]>>>,
|
||||
|
||||
// Handle all vector types as either f64 or v2f64.
|
||||
CCIfType<[v1i64, v2i32, v4i16, v8i8, v2f32], CCBitConvertToType<f64>>,
|
||||
CCIfType<[v2i64, v4i32, v8i16, v16i8, v4f32], CCBitConvertToType<v2f64>>,
|
||||
@ -151,6 +154,9 @@ def CC_ARM_AAPCS : CallingConv<[
|
||||
CCIfType<[v1i64, v2i32, v4i16, v8i8, v2f32], CCBitConvertToType<f64>>,
|
||||
CCIfType<[v2i64, v4i32, v8i16, v16i8, v4f32], CCBitConvertToType<v2f64>>,
|
||||
|
||||
// A SwiftSelf is passed in R9.
|
||||
CCIfSwiftSelf<CCIfType<[i32], CCAssignToReg<[R9]>>>,
|
||||
|
||||
CCIfType<[f64, v2f64], CCCustom<"CC_ARM_AAPCS_Custom_f64">>,
|
||||
CCIfType<[f32], CCBitConvertToType<i32>>,
|
||||
CCDelegateTo<CC_ARM_AAPCS_Common>
|
||||
@ -179,6 +185,9 @@ def CC_ARM_AAPCS_VFP : CallingConv<[
|
||||
CCIfType<[v1i64, v2i32, v4i16, v8i8, v2f32], CCBitConvertToType<f64>>,
|
||||
CCIfType<[v2i64, v4i32, v8i16, v16i8, v4f32], CCBitConvertToType<v2f64>>,
|
||||
|
||||
// A SwiftSelf is passed in R9.
|
||||
CCIfSwiftSelf<CCIfType<[i32], CCAssignToReg<[R9]>>>,
|
||||
|
||||
// HFAs are passed in a contiguous block of registers, or on the stack
|
||||
CCIfConsecutiveRegs<CCCustom<"CC_ARM_AAPCS_Custom_Aggregate">>,
|
||||
|
||||
|
@ -2345,6 +2345,7 @@ bool ARMFastISel::SelectCall(const Instruction *I,
|
||||
// FIXME: Only handle *easy* calls for now.
|
||||
if (CS.paramHasAttr(AttrInd, Attribute::InReg) ||
|
||||
CS.paramHasAttr(AttrInd, Attribute::StructRet) ||
|
||||
CS.paramHasAttr(AttrInd, Attribute::SwiftSelf) ||
|
||||
CS.paramHasAttr(AttrInd, Attribute::Nest) ||
|
||||
CS.paramHasAttr(AttrInd, Attribute::ByVal))
|
||||
return false;
|
||||
@ -3019,6 +3020,7 @@ bool ARMFastISel::fastLowerArguments() {
|
||||
|
||||
if (F->getAttributes().hasAttribute(Idx, Attribute::InReg) ||
|
||||
F->getAttributes().hasAttribute(Idx, Attribute::StructRet) ||
|
||||
F->getAttributes().hasAttribute(Idx, Attribute::SwiftSelf) ||
|
||||
F->getAttributes().hasAttribute(Idx, Attribute::ByVal))
|
||||
return false;
|
||||
|
||||
|
@ -273,6 +273,9 @@ def CC_X86_64_C : CallingConv<[
|
||||
CCIfNest<CCIfSubtarget<"isTarget64BitILP32()", CCAssignToReg<[R10D]>>>,
|
||||
CCIfNest<CCAssignToReg<[R10]>>,
|
||||
|
||||
// A SwiftSelf is passed in R10.
|
||||
CCIfSwiftSelf<CCIfType<[i64], CCAssignToReg<[R10]>>>,
|
||||
|
||||
// The first 6 integer arguments are passed in integer registers.
|
||||
CCIfType<[i32], CCAssignToReg<[EDI, ESI, EDX, ECX, R8D, R9D]>>,
|
||||
CCIfType<[i64], CCAssignToReg<[RDI, RSI, RDX, RCX, R8 , R9 ]>>,
|
||||
|
@ -2744,6 +2744,7 @@ bool X86FastISel::fastLowerArguments() {
|
||||
if (F->getAttributes().hasAttribute(Idx, Attribute::ByVal) ||
|
||||
F->getAttributes().hasAttribute(Idx, Attribute::InReg) ||
|
||||
F->getAttributes().hasAttribute(Idx, Attribute::StructRet) ||
|
||||
F->getAttributes().hasAttribute(Idx, Attribute::SwiftSelf) ||
|
||||
F->getAttributes().hasAttribute(Idx, Attribute::Nest))
|
||||
return false;
|
||||
|
||||
|
@ -287,6 +287,12 @@ define void @f49() inaccessiblemem_or_argmemonly {
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK: define void @f50(i8* swiftself)
|
||||
define void @f50(i8* swiftself)
|
||||
{
|
||||
ret void;
|
||||
}
|
||||
|
||||
; CHECK: attributes #0 = { noreturn }
|
||||
; CHECK: attributes #1 = { nounwind }
|
||||
; CHECK: attributes #2 = { readnone }
|
||||
|
29
test/CodeGen/AArch64/swiftself.ll
Normal file
29
test/CodeGen/AArch64/swiftself.ll
Normal file
@ -0,0 +1,29 @@
|
||||
; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-apple-ios | FileCheck --check-prefix=CHECK-APPLE %s
|
||||
; RUN: llc -O0 -verify-machineinstrs < %s -mtriple=aarch64-apple-ios | FileCheck --check-prefix=CHECK-O0 %s
|
||||
|
||||
; Parameter with swiftself should be allocated to x9.
|
||||
define void @check_swiftself(i32* swiftself %addr0) {
|
||||
; CHECK-APPLE-LABEL: check_swiftself:
|
||||
; CHECK-O0-LABEL: check_swiftself:
|
||||
|
||||
%val0 = load volatile i32, i32* %addr0
|
||||
; CHECK-APPLE: ldr w{{.*}}, [x9]
|
||||
; CHECK-O0: ldr w{{.*}}, [x9]
|
||||
ret void
|
||||
}
|
||||
|
||||
@var8_3 = global i8 0
|
||||
declare void @take_swiftself(i8* swiftself %addr0)
|
||||
|
||||
define void @simple_args() {
|
||||
; CHECK-APPLE-LABEL: simple_args:
|
||||
; CHECK-O0-LABEL: simple_args:
|
||||
|
||||
call void @take_swiftself(i8* @var8_3)
|
||||
; CHECK-APPLE: add x9,
|
||||
; CHECK-APPLE: bl {{_?}}take_swiftself
|
||||
; CHECK-O0: add x9,
|
||||
; CHECK-O0: bl {{_?}}take_swiftself
|
||||
|
||||
ret void
|
||||
}
|
32
test/CodeGen/ARM/swiftself.ll
Normal file
32
test/CodeGen/ARM/swiftself.ll
Normal file
@ -0,0 +1,32 @@
|
||||
; RUN: llc -verify-machineinstrs < %s -mtriple=armv7k-apple-ios8.0 -mcpu=cortex-a7 | FileCheck --check-prefix=CHECK-APPLE %s
|
||||
; RUN: llc -O0 -verify-machineinstrs < %s -mtriple=armv7k-apple-ios8.0 -mcpu=cortex-a7 | FileCheck --check-prefix=CHECK-O0 %s
|
||||
|
||||
; RUN: llc -verify-machineinstrs < %s -mtriple=armv7-apple-ios | FileCheck --check-prefix=CHECK-APPLE %s
|
||||
; RUN: llc -O0 -verify-machineinstrs < %s -mtriple=armv7-apple-ios | FileCheck --check-prefix=CHECK-O0 %s
|
||||
|
||||
; Parameter with swiftself should be allocated to r9.
|
||||
define void @check_swiftself(i32* swiftself %addr0) {
|
||||
; CHECK-APPLE-LABEL: check_swiftself:
|
||||
; CHECK-O0-LABEL: check_swiftself:
|
||||
|
||||
%val0 = load volatile i32, i32* %addr0
|
||||
; CHECK-APPLE: ldr r{{.*}}, [r9]
|
||||
; CHECK-O0: ldr r{{.*}}, [r9]
|
||||
ret void
|
||||
}
|
||||
|
||||
@var8_3 = global i8 0
|
||||
declare void @take_swiftself(i8* swiftself %addr0)
|
||||
|
||||
define void @simple_args() {
|
||||
; CHECK-APPLE-LABEL: simple_args:
|
||||
; CHECK-O0-LABEL: simple_args:
|
||||
|
||||
call void @take_swiftself(i8* @var8_3)
|
||||
; CHECK-APPLE: add r9, pc
|
||||
; CHECK-APPLE: bl {{_?}}take_swiftself
|
||||
; CHECK-O0: add r9, pc
|
||||
; CHECK-O0: bl {{_?}}take_swiftself
|
||||
|
||||
ret void
|
||||
}
|
41
test/CodeGen/X86/swiftself.ll
Normal file
41
test/CodeGen/X86/swiftself.ll
Normal file
@ -0,0 +1,41 @@
|
||||
; RUN: llc -verify-machineinstrs < %s -mtriple=x86_64-unknown-unknown | FileCheck %s
|
||||
; RUN: llc -O0 -verify-machineinstrs < %s -mtriple=x86_64-unknown-unknown | FileCheck --check-prefix=CHECK-O0 %s
|
||||
; RUN: llc -verify-machineinstrs < %s -march=x86 -mcpu=yonah -mtriple=i386-apple-darwin | FileCheck --check-prefix=CHECK-i386 %s
|
||||
; RUN: llc -O0 -verify-machineinstrs < %s -march=x86 -mcpu=yonah -mtriple=i386-apple-darwin | FileCheck --check-prefix=CHECK-i386-O0 %s
|
||||
|
||||
; Parameter with swiftself should be allocated to r10.
|
||||
define void @check_swiftself(i32* swiftself %addr0) {
|
||||
; CHECK-LABEL: check_swiftself:
|
||||
; CHECK-O0-LABEL: check_swiftself:
|
||||
; CHECK-i386-LABEL: check_swiftself:
|
||||
; CHECK-i386-O0-LABEL: check_swiftself:
|
||||
|
||||
%val0 = load volatile i32, i32* %addr0
|
||||
; CHECK: movl (%r10),
|
||||
; CHECK-O0: movl (%r10),
|
||||
; CHECK-i386: movl {{[0-9a-f]+}}(%esp)
|
||||
; CHECK-i386-O0: movl {{[0-9a-f]+}}(%esp)
|
||||
ret void
|
||||
}
|
||||
|
||||
@var8_3 = global i8 0
|
||||
declare void @take_swiftself(i8* swiftself %addr0)
|
||||
|
||||
define void @simple_args() {
|
||||
; CHECK-LABEL: simple_args:
|
||||
; CHECK-O0-LABEL: simple_args:
|
||||
; CHECK-i386-LABEL: simple_args:
|
||||
; CHECK-i386-O0-LABEL: simple_args:
|
||||
|
||||
call void @take_swiftself(i8* @var8_3)
|
||||
; CHECK: movl {{.*}}, %r10d
|
||||
; CHECK: callq {{_?}}take_swiftself
|
||||
; CHECK-O0: movabsq {{.*}}, %r10
|
||||
; CHECK-O0: callq {{_?}}take_swiftself
|
||||
; CHECK-i386: movl {{.*}}, (%esp)
|
||||
; CHECK-i386: calll {{.*}}take_swiftself
|
||||
; CHECK-i386-O0: movl {{.*}}, (%esp)
|
||||
; CHECK-i386-O0: calll {{.*}}take_swiftself
|
||||
|
||||
ret void
|
||||
}
|
4
test/Verifier/swiftself.ll
Normal file
4
test/Verifier/swiftself.ll
Normal file
@ -0,0 +1,4 @@
|
||||
; RUN: not llvm-as %s -o /dev/null 2>&1 | FileCheck %s
|
||||
|
||||
declare void @a(i32* swiftself %a, i32* swiftself %b)
|
||||
; CHECK: Cannot have multiple 'swiftself' parameters!
|
Loading…
Reference in New Issue
Block a user