Skip to content

Commit d257da7

Browse files
committed
[IR][AArch64] Add 'swiftcoro' parameter attribute.
It doesn't have any really interesting treatment, other than being passed in a fixed register. In most of our AArch64 calling conventions, that's X23. In effect, this is mostly similar to swiftself. rdar://135984630
1 parent 1bbe5a2 commit d257da7

File tree

21 files changed

+140
-7
lines changed

21 files changed

+140
-7
lines changed

llvm/include/llvm/Bitcode/LLVMBitCodes.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -758,6 +758,7 @@ enum AttributeKindCodes {
758758
ATTR_KIND_SANITIZE_NUMERICAL_STABILITY = 93,
759759
ATTR_KIND_INITIALIZES = 94,
760760
ATTR_KIND_HYBRID_PATCHABLE = 95,
761+
ATTR_KIND_SWIFT_CORO = 103,
761762
};
762763

763764
enum ComdatSelectionKindCodes {

llvm/include/llvm/CodeGen/TargetCallingConv.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ namespace ISD {
4040
unsigned IsSplitEnd : 1; ///< Last part of a split
4141
unsigned IsSwiftSelf : 1; ///< Swift self parameter
4242
unsigned IsSwiftAsync : 1; ///< Swift async context parameter
43+
unsigned IsSwiftCoro : 1; ///< Swift coro parameter
4344
unsigned IsSwiftError : 1; ///< Swift error parameter
4445
unsigned IsCFGuardTarget : 1; ///< Control Flow Guard target
4546
unsigned IsHva : 1; ///< HVA field for
@@ -63,6 +64,7 @@ namespace ISD {
6364
: IsZExt(0), IsSExt(0), IsInReg(0), IsSRet(0), IsByVal(0), IsByRef(0),
6465
IsNest(0), IsReturned(0), IsSplit(0), IsInAlloca(0),
6566
IsPreallocated(0), IsSplitEnd(0), IsSwiftSelf(0), IsSwiftAsync(0),
67+
IsSwiftCoro(0),
6668
IsSwiftError(0), IsCFGuardTarget(0), IsHva(0), IsHvaStart(0),
6769
IsSecArgPass(0), MemAlign(0), OrigAlign(0),
6870
IsInConsecutiveRegsLast(0), IsInConsecutiveRegs(0),
@@ -100,6 +102,9 @@ namespace ISD {
100102
bool isSwiftAsync() const { return IsSwiftAsync; }
101103
void setSwiftAsync() { IsSwiftAsync = 1; }
102104

105+
bool isSwiftCoro() const { return IsSwiftCoro; }
106+
void setSwiftCoro() { IsSwiftCoro = 1; }
107+
103108
bool isSwiftError() const { return IsSwiftError; }
104109
void setSwiftError() { IsSwiftError = 1; }
105110

llvm/include/llvm/CodeGen/TargetLowering.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,7 @@ class TargetLoweringBase {
313313
bool IsSwiftSelf : 1;
314314
bool IsSwiftAsync : 1;
315315
bool IsSwiftError : 1;
316+
bool IsSwiftCoro : 1;
316317
bool IsCFGuardTarget : 1;
317318
MaybeAlign Alignment = std::nullopt;
318319
Type *IndirectType = nullptr;
@@ -321,7 +322,8 @@ class TargetLoweringBase {
321322
: IsSExt(false), IsZExt(false), IsInReg(false), IsSRet(false),
322323
IsNest(false), IsByVal(false), IsByRef(false), IsInAlloca(false),
323324
IsPreallocated(false), IsReturned(false), IsSwiftSelf(false),
324-
IsSwiftAsync(false), IsSwiftError(false), IsCFGuardTarget(false) {}
325+
IsSwiftAsync(false), IsSwiftError(false), IsSwiftCoro(false),
326+
IsCFGuardTarget(false) {}
325327

326328
void setAttributes(const CallBase *Call, unsigned ArgIdx);
327329
};

llvm/include/llvm/IR/Attributes.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,9 @@ def SwiftSelf : EnumAttr<"swiftself", [ParamAttr]>;
315315
/// Argument is swift async context.
316316
def SwiftAsync : EnumAttr<"swiftasync", [ParamAttr]>;
317317

318+
/// Argument is swift coro allocator.
319+
def SwiftCoro : EnumAttr<"swiftcoro", [ParamAttr]>;
320+
318321
/// Function must be in a unwind table.
319322
def UWTable : IntAttr<"uwtable", [FnAttr]>;
320323

llvm/include/llvm/Target/TargetCallingConv.td

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,11 @@ class CCIfSwiftAsync<CCAction A> : CCIf<"ArgFlags.isSwiftAsync()", A> {
6161
class CCIfSwiftError<CCAction A> : CCIf<"ArgFlags.isSwiftError()", A> {
6262
}
6363

64+
/// CCIfSwiftCoro - If the current argument has swiftcoro parameter attribute,
65+
/// apply Action A.
66+
class CCIfSwiftCoro<CCAction A> : CCIf<"ArgFlags.isSwiftCoro()", A> {
67+
}
68+
6469
/// CCIfCFGuardTarget - If the current argument has cfguardtarget parameter
6570
/// attribute, apply Action A.
6671
class CCIfCFGuardTarget<CCAction A> : CCIf<"ArgFlags.isCFGuardTarget()", A> {

llvm/lib/Bitcode/Reader/BitcodeReader.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2149,6 +2149,8 @@ static Attribute::AttrKind getAttrFromCode(uint64_t Code) {
21492149
return Attribute::SwiftSelf;
21502150
case bitc::ATTR_KIND_SWIFT_ASYNC:
21512151
return Attribute::SwiftAsync;
2152+
case bitc::ATTR_KIND_SWIFT_CORO:
2153+
return Attribute::SwiftCoro;
21522154
case bitc::ATTR_KIND_UW_TABLE:
21532155
return Attribute::UWTable;
21542156
case bitc::ATTR_KIND_VSCALE_RANGE:

llvm/lib/Bitcode/Writer/BitcodeWriter.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -852,6 +852,8 @@ static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind) {
852852
return bitc::ATTR_KIND_SWIFT_SELF;
853853
case Attribute::SwiftAsync:
854854
return bitc::ATTR_KIND_SWIFT_ASYNC;
855+
case Attribute::SwiftCoro:
856+
return bitc::ATTR_KIND_SWIFT_CORO;
855857
case Attribute::UWTable:
856858
return bitc::ATTR_KIND_UW_TABLE;
857859
case Attribute::VScaleRange:

llvm/lib/CodeGen/GlobalISel/CallLowering.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ addFlagsUsingAttrFn(ISD::ArgFlagsTy &Flags,
6363
Flags.setSwiftAsync();
6464
if (AttrFn(Attribute::SwiftError))
6565
Flags.setSwiftError();
66+
if (AttrFn(Attribute::SwiftCoro))
67+
Flags.setSwiftCoro();
6668
}
6769

6870
ISD::ArgFlagsTy CallLowering::getAttributesForArgIdx(const CallBase &Call,

llvm/lib/CodeGen/SelectionDAG/FastISel.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1053,6 +1053,8 @@ bool FastISel::lowerCallTo(CallLoweringInfo &CLI) {
10531053
Flags.setSwiftAsync();
10541054
if (Arg.IsSwiftError)
10551055
Flags.setSwiftError();
1056+
if (Arg.IsSwiftCoro)
1057+
Flags.setSwiftCoro();
10561058
if (Arg.IsCFGuardTarget)
10571059
Flags.setCFGuardTarget();
10581060
if (Arg.IsByVal)

llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10860,6 +10860,7 @@ TargetLowering::LowerCallTo(TargetLowering::CallLoweringInfo &CLI) const {
1086010860
Entry.IsSwiftSelf = false;
1086110861
Entry.IsSwiftAsync = false;
1086210862
Entry.IsSwiftError = false;
10863+
Entry.IsSwiftCoro = false;
1086310864
Entry.IsCFGuardTarget = false;
1086410865
Entry.Alignment = Alignment;
1086510866
CLI.getArgs().insert(CLI.getArgs().begin(), Entry);
@@ -10977,6 +10978,8 @@ TargetLowering::LowerCallTo(TargetLowering::CallLoweringInfo &CLI) const {
1097710978
Flags.setSwiftAsync();
1097810979
if (Args[i].IsSwiftError)
1097910980
Flags.setSwiftError();
10981+
if (Args[i].IsSwiftCoro)
10982+
Flags.setSwiftCoro();
1098010983
if (Args[i].IsCFGuardTarget)
1098110984
Flags.setCFGuardTarget();
1098210985
if (Args[i].IsByVal)
@@ -11522,6 +11525,8 @@ void SelectionDAGISel::LowerArguments(const Function &F) {
1152211525
Flags.setSwiftAsync();
1152311526
if (Arg.hasAttribute(Attribute::SwiftError))
1152411527
Flags.setSwiftError();
11528+
if (Arg.hasAttribute(Attribute::SwiftCoro))
11529+
Flags.setSwiftCoro();
1152511530
if (Arg.hasAttribute(Attribute::ByVal))
1152611531
Flags.setByVal();
1152711532
if (Arg.hasAttribute(Attribute::ByRef))

llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ void TargetLoweringBase::ArgListEntry::setAttributes(const CallBase *Call,
123123
IsSwiftSelf = Call->paramHasAttr(ArgIdx, Attribute::SwiftSelf);
124124
IsSwiftAsync = Call->paramHasAttr(ArgIdx, Attribute::SwiftAsync);
125125
IsSwiftError = Call->paramHasAttr(ArgIdx, Attribute::SwiftError);
126+
IsSwiftCoro = Call->paramHasAttr(ArgIdx, Attribute::SwiftCoro);
126127
Alignment = Call->getParamStackAlign(ArgIdx);
127128
IndirectType = nullptr;
128129
assert(IsByVal + IsPreallocated + IsInAlloca + IsSRet <= 1 &&

llvm/lib/IR/Verifier.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2185,6 +2185,7 @@ void Verifier::verifyFunctionAttrs(FunctionType *FT, AttributeList Attrs,
21852185
bool SawSwiftSelf = false;
21862186
bool SawSwiftAsync = false;
21872187
bool SawSwiftError = false;
2188+
bool SawSwiftCoro = false;
21882189

21892190
// Verify return value attributes.
21902191
AttributeSet RetAttrs = Attrs.getRetAttrs();
@@ -2261,6 +2262,11 @@ void Verifier::verifyFunctionAttrs(FunctionType *FT, AttributeList Attrs,
22612262
SawSwiftError = true;
22622263
}
22632264

2265+
if (ArgAttrs.hasAttribute(Attribute::SwiftCoro)) {
2266+
Check(!SawSwiftCoro, "Cannot have multiple 'swiftcoro' parameters!", V);
2267+
SawSwiftCoro = true;
2268+
}
2269+
22642270
if (ArgAttrs.hasAttribute(Attribute::InAlloca)) {
22652271
Check(i == FT->getNumParams() - 1,
22662272
"inalloca isn't on the last parameter!", V);
@@ -3878,6 +3884,7 @@ static AttrBuilder getParameterABIAttributes(LLVMContext& C, unsigned I, Attribu
38783884
static const Attribute::AttrKind ABIAttrs[] = {
38793885
Attribute::StructRet, Attribute::ByVal, Attribute::InAlloca,
38803886
Attribute::InReg, Attribute::StackAlignment, Attribute::SwiftSelf,
3887+
Attribute::SwiftCoro,
38813888
Attribute::SwiftAsync, Attribute::SwiftError, Attribute::Preallocated,
38823889
Attribute::ByRef};
38833890
AttrBuilder Copy(C);

llvm/lib/Target/AArch64/AArch64CallingConvention.td

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,9 @@ defvar AArch64_Common = [
7272
// preserved for normal function calls.
7373
CCIfSwiftAsync<CCIfType<[i64], CCAssignToReg<[X22]>>>,
7474

75+
// Pass SwiftCoro in X23.
76+
CCIfSwiftCoro<CCIfType<[i64], CCAssignToReg<[X23]>>>,
77+
7578
CCIfConsecutiveRegs<CCCustom<"CC_AArch64_Custom_Block">>,
7679

7780
CCIfType<[nxv16i8, nxv8i16, nxv4i32, nxv2i64, nxv2f16, nxv4f16, nxv8f16,
@@ -241,6 +244,9 @@ def CC_AArch64_Arm64EC_Thunk : CallingConv<[
241244
// normal functions don't need to save it somewhere.
242245
CCIfSwiftAsync<CCIfType<[i64], CCAssignToReg<[X21]>>>,
243246

247+
// Pass SwiftCoro in X22.
248+
CCIfSwiftCoro<CCIfType<[i64], CCAssignToReg<[X22]>>>,
249+
244250
// The 'CFGuardTarget' parameter, if any, is passed in RAX (R8).
245251
CCIfCFGuardTarget<CCAssignToReg<[X8]>>,
246252

@@ -374,6 +380,9 @@ def CC_AArch64_DarwinPCS : CallingConv<[
374380
// preserved for normal function calls.
375381
CCIfSwiftAsync<CCIfType<[i64], CCAssignToReg<[X22]>>>,
376382

383+
// Pass SwiftCoro in X23.
384+
CCIfSwiftCoro<CCIfType<[i64], CCAssignToReg<[X23]>>>,
385+
377386
CCIfConsecutiveRegs<CCCustom<"CC_AArch64_Custom_Block">>,
378387

379388
// Handle i1, i8, i16, i32, i64, f32, f64 and v2f64 by passing in registers,

llvm/lib/Target/AArch64/AArch64FastISel.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2930,6 +2930,7 @@ bool AArch64FastISel::fastLowerArguments() {
29302930
Arg.hasAttribute(Attribute::SwiftSelf) ||
29312931
Arg.hasAttribute(Attribute::SwiftAsync) ||
29322932
Arg.hasAttribute(Attribute::SwiftError) ||
2933+
Arg.hasAttribute(Attribute::SwiftCoro) ||
29332934
Arg.hasAttribute(Attribute::Nest))
29342935
return false;
29352936

@@ -3197,6 +3198,7 @@ bool AArch64FastISel::fastLowerCall(CallLoweringInfo &CLI) {
31973198

31983199
for (auto Flag : CLI.OutFlags)
31993200
if (Flag.isInReg() || Flag.isSRet() || Flag.isNest() || Flag.isByVal() ||
3201+
Flag.isSwiftCoro() ||
32003202
Flag.isSwiftSelf() || Flag.isSwiftAsync() || Flag.isSwiftError())
32013203
return false;
32023204

llvm/lib/Target/AArch64/AArch64ISelLowering.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7701,7 +7701,7 @@ SDValue AArch64TargetLowering::LowerFormalArguments(
77017701
if (CallConv == CallingConv::PreserveNone) {
77027702
for (const ISD::InputArg &I : Ins) {
77037703
if (I.Flags.isSwiftSelf() || I.Flags.isSwiftError() ||
7704-
I.Flags.isSwiftAsync()) {
7704+
I.Flags.isSwiftAsync() || I.Flags.isSwiftCoro()) {
77057705
MachineFunction &MF = DAG.getMachineFunction();
77067706
DAG.getContext()->diagnose(DiagnosticInfoUnsupported(
77077707
MF.getFunction(),
@@ -8996,7 +8996,7 @@ AArch64TargetLowering::LowerCall(CallLoweringInfo &CLI,
89968996
if (CallConv == CallingConv::PreserveNone) {
89978997
for (const ISD::OutputArg &O : Outs) {
89988998
if (O.Flags.isSwiftSelf() || O.Flags.isSwiftError() ||
8999-
O.Flags.isSwiftAsync()) {
8999+
O.Flags.isSwiftAsync() || O.Flags.isSwiftCoro()) {
90009000
MachineFunction &MF = DAG.getMachineFunction();
90019001
DAG.getContext()->diagnose(DiagnosticInfoUnsupported(
90029002
MF.getFunction(),

llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1107,6 +1107,8 @@ WebAssemblyTargetLowering::LowerCall(CallLoweringInfo &CLI,
11071107
SDValue &OutVal = OutVals[I];
11081108
HasSwiftSelfArg |= Out.Flags.isSwiftSelf();
11091109
HasSwiftErrorArg |= Out.Flags.isSwiftError();
1110+
if (Out.Flags.isSwiftCoro())
1111+
fail(DL, DAG, "WebAssembly hasn't implemented swiftcoro arguments");
11101112
if (Out.Flags.isNest())
11111113
fail(DL, DAG, "WebAssembly hasn't implemented nest arguments");
11121114
if (Out.Flags.isInAlloca())

llvm/lib/Transforms/Utils/CodeExtractor.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -995,6 +995,7 @@ Function *CodeExtractor::constructFunction(const ValueSet &inputs,
995995
case Attribute::SwiftError:
996996
case Attribute::SwiftSelf:
997997
case Attribute::SwiftAsync:
998+
case Attribute::SwiftCoro:
998999
case Attribute::ZExt:
9991000
case Attribute::ImmArg:
10001001
case Attribute::ByRef:

llvm/test/Bitcode/attributes.ll

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,12 @@ define void @f50(ptr swiftself %0)
292292
ret void;
293293
}
294294

295+
; CHECK: define void @swiftcoro(ptr swiftcoro %0)
296+
define void @swiftcoro(ptr swiftcoro %0)
297+
{
298+
ret void;
299+
}
300+
295301
; CHECK: define i32 @f51(ptr swifterror %0)
296302
define i32 @f51(ptr swifterror %0)
297303
{

llvm/test/Bitcode/compatibility.ll

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -516,10 +516,10 @@ declare cc96 void @f.cc96()
516516
; CHECK: declare amdgpu_es void @f.cc96()
517517
declare amdgpu_es void @f.amdgpu_es()
518518
; CHECK: declare amdgpu_es void @f.amdgpu_es()
519-
+declare cc124 void @f.cc124()
520-
+; CHECK: declare swiftcorocc void @f.cc124()
521-
+declare swiftcorocc void @f.swiftcorocc()
522-
+; CHECK: declare swiftcorocc void @f.swiftcorocc()
519+
declare cc124 void @f.cc124()
520+
; CHECK: declare swiftcorocc void @f.cc124()
521+
declare swiftcorocc void @f.swiftcorocc()
522+
; CHECK: declare swiftcorocc void @f.swiftcorocc()
523523
declare cc1023 void @f.cc1023()
524524
; CHECK: declare cc1023 void @f.cc1023()
525525

@@ -582,6 +582,8 @@ declare void @f.param.swiftasync(ptr swiftasync)
582582
; CHECK: declare void @f.param.swiftasync(ptr swiftasync)
583583
declare void @f.param.swifterror(ptr swifterror)
584584
; CHECK: declare void @f.param.swifterror(ptr swifterror)
585+
declare void @f.param.swiftcoro(ptr swiftcoro)
586+
; CHECK: declare void @f.param.swiftcoro(ptr swiftcoro)
585587
declare void @f.param.allocalign(i32 allocalign)
586588
; CHECK: declare void @f.param.allocalign(i32 allocalign)
587589
declare void @f.param.allocptr(ptr allocptr)
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
; RUN: llc -verify-machineinstrs -mtriple=aarch64-apple-ios -o - %s | FileCheck --check-prefix=CHECK --check-prefix=OPT --check-prefix=OPTAARCH64 %s
2+
; RUN: llc -O0 -fast-isel -verify-machineinstrs -mtriple=aarch64-apple-ios -o - %s | FileCheck %s
3+
; RUN: llc -verify-machineinstrs -mtriple=aarch64-unknown-linux-gnu -o - %s | FileCheck --check-prefix=CHECK --check-prefix=OPT --check-prefix=OPTAARCH64 %s
4+
; RUN: llc -verify-machineinstrs -mtriple=arm64_32-apple-ios -o - %s | FileCheck --check-prefix=CHECK --check-prefix=OPT --check-prefix=OPTARM64_32 %s
5+
6+
; Parameter with swiftcoro should be allocated to x23.
7+
; CHECK-LABEL: swiftcoro_param:
8+
; CHECK: mov x0, x23
9+
; CHECK-NEXT: ret
10+
define ptr @swiftcoro_param(ptr swiftcoro %addr0) {
11+
ret ptr %addr0
12+
}
13+
14+
; Check that x23 is used to pass a swiftcoro argument.
15+
; CHECK-LABEL: call_swiftcoro:
16+
; CHECK: mov x23, x0
17+
; CHECK: bl {{_?}}swiftcoro_param
18+
; CHECK: ret
19+
define ptr @call_swiftcoro(ptr %arg) {
20+
%res = call ptr @swiftcoro_param(ptr swiftcoro %arg)
21+
ret ptr %res
22+
}
23+
24+
; x23 should be saved by the callee even if used for swiftcoro
25+
; CHECK-LABEL: swiftcoro_clobber:
26+
; CHECK: {{stp|str}} {{.*}}x23{{.*}}sp
27+
; ...
28+
; CHECK: {{ldp|ldr}} {{.*}}x23{{.*}}sp
29+
; CHECK: ret
30+
define ptr @swiftcoro_clobber(ptr swiftcoro %addr0) {
31+
call void asm sideeffect "", "~{x23}"()
32+
ret ptr %addr0
33+
}
34+
35+
; Demonstrate that we do not need any movs when calling multiple functions
36+
; with swiftcoro argument.
37+
; CHECK-LABEL: swiftcoro_passthrough:
38+
; OPT-NOT: mov{{.*}}x23
39+
; OPT: bl {{_?}}swiftcoro_param
40+
; OPT-NOT: mov{{.*}}x23
41+
; OPT-NEXT: bl {{_?}}swiftcoro_param
42+
; OPT: ret
43+
define void @swiftcoro_passthrough(ptr swiftcoro %addr0) {
44+
call ptr @swiftcoro_param(ptr swiftcoro %addr0)
45+
call ptr @swiftcoro_param(ptr swiftcoro %addr0)
46+
ret void
47+
}
48+
49+
; We can use a tail call if the callee swiftcoro is the same as the caller one.
50+
; This should also work with fast-isel.
51+
; CHECK-LABEL: swiftcoro_tail:
52+
; OPTAARCH64: b {{_?}}swiftcoro_param
53+
; OPTAARCH64-NOT: ret
54+
; OPTARM64_32: b {{_?}}swiftcoro_param
55+
define ptr @swiftcoro_tail(ptr swiftcoro %addr0) {
56+
call void asm sideeffect "", "~{x23}"()
57+
%res = musttail call ptr @swiftcoro_param(ptr swiftcoro %addr0)
58+
ret ptr %res
59+
}
60+
61+
; We can not use a tail call if the callee swiftcoro is not the same as the
62+
; caller one.
63+
; CHECK-LABEL: swiftcoro_notail:
64+
; CHECK: mov x23, x0
65+
; CHECK: bl {{_?}}swiftcoro_param
66+
; CHECK: ret
67+
define ptr @swiftcoro_notail(ptr swiftcoro %addr0, ptr %addr1) nounwind {
68+
%res = tail call ptr @swiftcoro_param(ptr swiftcoro %addr1)
69+
ret ptr %res
70+
}

llvm/test/Verifier/swiftcoro.ll

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
; RUN: not llvm-as %s -o /dev/null 2>&1 | FileCheck %s
2+
3+
declare void @a(ptr swiftcoro %a, ptr swiftcoro %b)
4+
; CHECK: Cannot have multiple 'swiftcoro' parameters!

0 commit comments

Comments
 (0)