Skip to content

Commit 1b28e42

Browse files
author
Artem Gindinson
committed
Merge from 'main' to 'sycl-web' (#4)
CONFLICT (content): Merge conflict in llvm/lib/Support/Triple.cpp
2 parents 083445b + ed95655 commit 1b28e42

File tree

80 files changed

+1079
-281
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

80 files changed

+1079
-281
lines changed

clang/docs/HardwareAssistedAddressSanitizerDesign.rst

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,17 @@ The redzones, the quarantine, and, to a less extent, the shadow, are the
1919
sources of AddressSanitizer's memory overhead.
2020
See the `AddressSanitizer paper`_ for details.
2121

22-
AArch64 has the `Address Tagging`_ (or top-byte-ignore, TBI), a hardware feature that allows
23-
software to use 8 most significant bits of a 64-bit pointer as
22+
AArch64 has `Address Tagging`_ (or top-byte-ignore, TBI), a hardware feature that allows
23+
software to use the 8 most significant bits of a 64-bit pointer as
2424
a tag. HWASAN uses `Address Tagging`_
2525
to implement a memory safety tool, similar to :doc:`AddressSanitizer`,
2626
but with smaller memory overhead and slightly different (mostly better)
2727
accuracy guarantees.
2828

29+
Intel's `Linear Address Masking`_ (LAM) also provides address tagging for
30+
x86_64, though it is not widely available in hardware yet. For x86_64, HWASAN
31+
has a limited implementation using page aliasing instead.
32+
2933
Algorithm
3034
=========
3135
* Every heap/stack/global memory object is forcibly aligned by `TG` bytes
@@ -266,7 +270,15 @@ before every load and store by compiler instrumentation, but this variant
266270
will have limited deployability since not all of the code is
267271
typically instrumented.
268272

269-
The HWASAN's approach is not applicable to 32-bit architectures.
273+
On x86_64, HWASAN utilizes page aliasing to place tags in userspace address
274+
bits. Currently only heap tagging is supported. The page aliases rely on
275+
shared memory, which will cause heap memory to be shared between processes if
276+
the application calls ``fork()``. Therefore x86_64 is really only safe for
277+
applications that do not fork.
278+
279+
HWASAN does not currently support 32-bit architectures since they do not
280+
support `Address Tagging`_ and the address space is too constrained to easily
281+
implement page aliasing.
270282

271283

272284
Related Work
@@ -284,4 +296,4 @@ Related Work
284296
.. _SPARC ADI: https://lazytyped.blogspot.com/2017/09/getting-started-with-adi.html
285297
.. _AddressSanitizer paper: https://www.usenix.org/system/files/conference/atc12/atc12-final39.pdf
286298
.. _Address Tagging: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.den0024a/ch12s05s01.html
287-
299+
.. _Linear Address Masking: https://software.intel.com/content/www/us/en/develop/download/intel-architecture-instruction-set-extensions-programming-reference.html

clang/lib/AST/StmtPrinter.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1170,6 +1170,10 @@ void StmtPrinter::VisitIntegerLiteral(IntegerLiteral *Node) {
11701170
case BuiltinType::ULong: OS << "UL"; break;
11711171
case BuiltinType::LongLong: OS << "LL"; break;
11721172
case BuiltinType::ULongLong: OS << "ULL"; break;
1173+
case BuiltinType::Int128:
1174+
break; // no suffix.
1175+
case BuiltinType::UInt128:
1176+
break; // no suffix.
11731177
}
11741178
}
11751179

clang/lib/CodeGen/CGCoroutine.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -556,6 +556,8 @@ void CodeGenFunction::EmitCoroutineBody(const CoroutineBodyStmt &S) {
556556
{Builder.getInt32(NewAlign), NullPtr, NullPtr, NullPtr});
557557
createCoroData(*this, CurCoro, CoroId);
558558
CurCoro.Data->SuspendBB = RetBB;
559+
assert(ShouldEmitLifetimeMarkers &&
560+
"Must emit lifetime intrinsics for coroutines");
559561

560562
// Backend is allowed to elide memory allocations, to help it, emit
561563
// auto mem = coro.alloc() ? 0 : ... allocation code ...;

clang/lib/CodeGen/CGOpenMPRuntime.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1034,7 +1034,7 @@ LValue CGOpenMPRegionInfo::getThreadIDVariableLValue(CodeGenFunction &CGF) {
10341034
getThreadIDVariable()->getType()->castAs<PointerType>());
10351035
}
10361036

1037-
void CGOpenMPRegionInfo::EmitBody(CodeGenFunction &CGF, const Stmt * /*S*/) {
1037+
void CGOpenMPRegionInfo::EmitBody(CodeGenFunction &CGF, const Stmt *S) {
10381038
if (!CGF.HaveInsertPoint())
10391039
return;
10401040
// 1.2.2 OpenMP Language Terminology
@@ -1043,6 +1043,8 @@ void CGOpenMPRegionInfo::EmitBody(CodeGenFunction &CGF, const Stmt * /*S*/) {
10431043
// The point of exit cannot be a branch out of the structured block.
10441044
// longjmp() and throw() must not violate the entry/exit criteria.
10451045
CGF.EHStack.pushTerminate();
1046+
if (S)
1047+
CGF.incrementProfileCounter(S);
10461048
CodeGen(CGF);
10471049
CGF.EHStack.popTerminate();
10481050
}

clang/lib/CodeGen/CodeGenFunction.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1446,10 +1446,16 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn,
14461446

14471447
Stmt *Body = FD->getBody();
14481448

1449-
// Initialize helper which will detect jumps which can cause invalid lifetime
1450-
// markers.
1451-
if (Body && ShouldEmitLifetimeMarkers)
1452-
Bypasses.Init(Body);
1449+
if (Body) {
1450+
// Coroutines always emit lifetime markers.
1451+
if (isa<CoroutineBodyStmt>(Body))
1452+
ShouldEmitLifetimeMarkers = true;
1453+
1454+
// Initialize helper which will detect jumps which can cause invalid
1455+
// lifetime markers.
1456+
if (ShouldEmitLifetimeMarkers)
1457+
Bypasses.Init(Body);
1458+
}
14531459

14541460
// Emit the standard function prologue.
14551461
StartFunction(GD, ResTy, Fn, FnInfo, Args, Loc, BodyRange.getBegin());

clang/lib/CodeGen/CodeGenFunction.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1886,8 +1886,9 @@ class CodeGenFunction : public CodeGenTypeCache {
18861886
/// function attribute.
18871887
unsigned LargestVectorWidth = 0;
18881888

1889-
/// True if we need emit the life-time markers.
1890-
const bool ShouldEmitLifetimeMarkers;
1889+
/// True if we need emit the life-time markers. This is initially set in
1890+
/// the constructor, but could be overwritten to true if this is a coroutine.
1891+
bool ShouldEmitLifetimeMarkers;
18911892

18921893
/// Add OpenCL kernel arg metadata and the kernel attribute metadata to
18931894
/// the function metadata.

clang/lib/Driver/ToolChains/Fuchsia.cpp

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,8 @@ void fuchsia::Linker::ConstructJob(Compilation &C, const JobAction &JA,
9595
std::string Dyld = D.DyldPrefix;
9696
if (SanArgs.needsAsanRt() && SanArgs.needsSharedRt())
9797
Dyld += "asan/";
98+
if (SanArgs.needsHwasanRt() && SanArgs.needsSharedRt())
99+
Dyld += "hwasan/";
98100
if (SanArgs.needsTsanRt() && SanArgs.needsSharedRt())
99101
Dyld += "tsan/";
100102
Dyld += "ld.so.1";
@@ -210,23 +212,41 @@ Fuchsia::Fuchsia(const Driver &D, const llvm::Triple &Triple,
210212
.flag("+fsanitize=address")
211213
.flag("-fexceptions")
212214
.flag("+fno-exceptions"));
215+
// HWASan has higher priority because we always want the instrumentated
216+
// version.
217+
Multilibs.push_back(
218+
Multilib("hwasan", {}, {}, 4).flag("+fsanitize=hwaddress"));
219+
// Use the hwasan+noexcept variant with HWASan and -fno-exceptions.
220+
Multilibs.push_back(Multilib("hwasan+noexcept", {}, {}, 5)
221+
.flag("+fsanitize=hwaddress")
222+
.flag("-fexceptions")
223+
.flag("+fno-exceptions"));
213224
// Use the relative vtables ABI.
214225
// TODO: Remove these multilibs once relative vtables are enabled by default
215226
// for Fuchsia.
216-
Multilibs.push_back(Multilib("relative-vtables", {}, {}, 4)
227+
Multilibs.push_back(Multilib("relative-vtables", {}, {}, 6)
217228
.flag("+fexperimental-relative-c++-abi-vtables"));
218-
Multilibs.push_back(Multilib("relative-vtables+noexcept", {}, {}, 5)
229+
Multilibs.push_back(Multilib("relative-vtables+noexcept", {}, {}, 7)
219230
.flag("+fexperimental-relative-c++-abi-vtables")
220231
.flag("-fexceptions")
221232
.flag("+fno-exceptions"));
222-
Multilibs.push_back(Multilib("relative-vtables+asan", {}, {}, 6)
233+
Multilibs.push_back(Multilib("relative-vtables+asan", {}, {}, 8)
223234
.flag("+fexperimental-relative-c++-abi-vtables")
224235
.flag("+fsanitize=address"));
225-
Multilibs.push_back(Multilib("relative-vtables+asan+noexcept", {}, {}, 7)
236+
Multilibs.push_back(Multilib("relative-vtables+asan+noexcept", {}, {}, 9)
226237
.flag("+fexperimental-relative-c++-abi-vtables")
227238
.flag("+fsanitize=address")
228239
.flag("-fexceptions")
229240
.flag("+fno-exceptions"));
241+
Multilibs.push_back(Multilib("relative-vtables+hwasan", {}, {}, 10)
242+
.flag("+fexperimental-relative-c++-abi-vtables")
243+
.flag("+fsanitize=hwaddress"));
244+
Multilibs.push_back(Multilib("relative-vtables+hwasan+noexcept", {}, {}, 11)
245+
.flag("+fexperimental-relative-c++-abi-vtables")
246+
.flag("+fsanitize=hwaddress")
247+
.flag("-fexceptions")
248+
.flag("+fno-exceptions"));
249+
230250
Multilibs.FilterOut([&](const Multilib &M) {
231251
std::vector<std::string> RD = FilePaths(M);
232252
return std::all_of(RD.begin(), RD.end(), [&](std::string P) {
@@ -239,6 +259,8 @@ Fuchsia::Fuchsia(const Driver &D, const llvm::Triple &Triple,
239259
Args.hasFlag(options::OPT_fexceptions, options::OPT_fno_exceptions, true),
240260
"fexceptions", Flags);
241261
addMultilibFlag(getSanitizerArgs().needsAsanRt(), "fsanitize=address", Flags);
262+
addMultilibFlag(getSanitizerArgs().needsHwasanRt(), "fsanitize=hwaddress",
263+
Flags);
242264

243265
addMultilibFlag(
244266
Args.hasFlag(options::OPT_fexperimental_relative_cxx_abi_vtables,
@@ -368,6 +390,7 @@ void Fuchsia::AddCXXStdlibLibArgs(const ArgList &Args,
368390
SanitizerMask Fuchsia::getSupportedSanitizers() const {
369391
SanitizerMask Res = ToolChain::getSupportedSanitizers();
370392
Res |= SanitizerKind::Address;
393+
Res |= SanitizerKind::HWAddress;
371394
Res |= SanitizerKind::PointerCompare;
372395
Res |= SanitizerKind::PointerSubtract;
373396
Res |= SanitizerKind::Fuzzer;

clang/lib/Driver/ToolChains/Linux.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,11 @@ std::string Linux::getDynamicLinker(const ArgList &Args) const {
406406
case llvm::Triple::x86:
407407
ArchName = "i386";
408408
break;
409+
case llvm::Triple::x86_64:
410+
ArchName = Triple.getEnvironment() == llvm::Triple::MuslX32
411+
? "x32"
412+
: Triple.getArchName().str();
413+
break;
409414
default:
410415
ArchName = Triple.getArchName().str();
411416
}

clang/lib/Sema/SemaTemplateDeduction.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -455,11 +455,13 @@ static Sema::TemplateDeductionResult DeduceNullPtrTemplateArgument(
455455
const NonTypeTemplateParmDecl *NTTP, QualType NullPtrType,
456456
TemplateDeductionInfo &Info,
457457
SmallVectorImpl<DeducedTemplateArgument> &Deduced) {
458-
Expr *Value =
459-
S.ImpCastExprToType(new (S.Context) CXXNullPtrLiteralExpr(
460-
S.Context.NullPtrTy, NTTP->getLocation()),
461-
NullPtrType, CK_NullToPointer)
462-
.get();
458+
Expr *Value = S.ImpCastExprToType(
459+
new (S.Context) CXXNullPtrLiteralExpr(S.Context.NullPtrTy,
460+
NTTP->getLocation()),
461+
NullPtrType,
462+
NullPtrType->isMemberPointerType() ? CK_NullToMemberPointer
463+
: CK_NullToPointer)
464+
.get();
463465
return DeduceNonTypeTemplateArgument(S, TemplateParams, NTTP,
464466
DeducedTemplateArgument(Value),
465467
Value->getType(), Info, Deduced);

clang/test/AST/ast-print-int128.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// RUN: %clang_cc1 -ast-print -std=c++20 %s -o - | FileCheck %s
2+
3+
template <bool>
4+
struct enable_if {
5+
};
6+
7+
template <__uint128_t x, typename = typename enable_if<x != 0>::type>
8+
void f();
9+
10+
template <__int128_t>
11+
void f();
12+
13+
using T = decltype(f<0>());
14+
15+
// CHECK: using T = decltype(f<0>());

clang/test/CodeGenCoroutines/coro-alloc.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,8 @@ extern "C" int f4(promise_on_alloc_failure_tag) {
245245

246246
// CHECK: %[[Tmp1:.*]] = load i32, i32* %[[Gro]]
247247
// CHECK-NEXT: store i32 %[[Tmp1]], i32* %[[RetVal]]
248+
// CHECK-NEXT: %[[Gro_CAST:.+]] = bitcast i32* %[[Gro]] to i8*
249+
// CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* %[[Gro_CAST]]) #2
248250
// CHECK-NEXT: br label %[[RetBB]]
249251

250252
// CHECK: [[RetBB]]:

clang/test/CodeGenCoroutines/coro-await-resume-eh.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,18 @@ throwing_task f() {
5757
// CHECK-NEXT: to label %[[RESUMEENDCATCHCONT:.+]] unwind label
5858
// CHECK: [[RESUMEENDCATCHCONT]]:
5959
// CHECK-NEXT: br label %[[RESUMETRYCONT]]
60+
// CHECK: [[RESUMETRYCONT]]:
61+
// CHECK-NEXT: br label %[[CLEANUP:.+]]
62+
// CHECK: [[CLEANUP]]:
63+
// CHECK: switch i32 %{{.+}}, label %{{.+}} [
64+
// CHECK-NEXT: i32 0, label %[[CLEANUPCONT:.+]]
65+
// CHECK-NEXT: ]
6066

6167
// The variable RESUMETHREW is loaded and if true, then 'await_resume'
6268
// threw an exception and the coroutine body is skipped, and the final
6369
// suspend is executed immediately. Otherwise, the coroutine body is
6470
// executed, and then the final suspend.
65-
// CHECK: [[RESUMETRYCONT]]:
71+
// CHECK: [[CLEANUPCONT]]:
6672
// CHECK-NEXT: %[[RESUMETHREWLOAD:.+]] = load i1, i1* %[[RESUMETHREW]]
6773
// CHECK-NEXT: br i1 %[[RESUMETHREWLOAD]], label %[[RESUMEDCONT:.+]], label %[[RESUMEDBODY:.+]]
6874

@@ -76,7 +82,7 @@ throwing_task f() {
7682
// CHECK-NEXT: br label %[[COROFINAL]]
7783

7884
// CHECK: [[COROFINAL]]:
79-
// CHECK-NEXT: call void @_ZN13throwing_task12promise_type13final_suspendEv
85+
// CHECK: call void @_ZN13throwing_task12promise_type13final_suspendEv
8086
co_return;
8187
}
8288

clang/test/CodeGenCoroutines/coro-await.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,9 @@ extern "C" void TestScalar() {
231231

232232
int Val = co_await ScalarAwaiter{};
233233
// CHECK: %[[Result2:.+]] = call i32 @_ZN13ScalarAwaiter12await_resumeEv(%struct.ScalarAwaiter*
234-
// CHECK: store i32 %[[Result2]], i32* %Val
234+
// CHECK: store i32 %[[Result2]], i32* %[[TMP_EXPRCLEANUP:.+]],
235+
// CHECK: %[[TMP:.+]] = load i32, i32* %[[TMP_EXPRCLEANUP]],
236+
// CHECK: store i32 %[[TMP]], i32* %Val,
235237

236238
co_await ScalarAwaiter{};
237239
// CHECK: call i32 @_ZN13ScalarAwaiter12await_resumeEv(%struct.ScalarAwaiter*
@@ -312,19 +314,25 @@ void AwaitReturnsLValue(double) {
312314
// CHECK: %[[YVAR:.+]] = alloca %struct.RefTag*,
313315
// CHECK-NEXT: %[[TMP1:.+]] = alloca %struct.AwaitResumeReturnsLValue,
314316

317+
// CHECK: %[[TMP_EXPRCLEANUP1:.+]] = alloca %struct.RefTag*,
315318
// CHECK: %[[ZVAR:.+]] = alloca %struct.RefTag*,
316319
// CHECK-NEXT: %[[TMP2:.+]] = alloca %struct.AwaitResumeReturnsLValue,
320+
// CHECK: %[[TMP_EXPRCLEANUP2:.+]] = alloca %struct.RefTag*,
317321

318322
// CHECK: %[[RES1:.+]] = call nonnull align 1 dereferenceable({{.*}}) %struct.RefTag* @_ZN24AwaitResumeReturnsLValue12await_resumeEv(%struct.AwaitResumeReturnsLValue* {{[^,]*}} %[[AVAR]])
319323
// CHECK-NEXT: store %struct.RefTag* %[[RES1]], %struct.RefTag** %[[XVAR]],
320324
RefTag& x = co_await a;
321325

322326
// CHECK: %[[RES2:.+]] = call nonnull align 1 dereferenceable({{.*}}) %struct.RefTag* @_ZN24AwaitResumeReturnsLValue12await_resumeEv(%struct.AwaitResumeReturnsLValue* {{[^,]*}} %[[TMP1]])
323-
// CHECK-NEXT: store %struct.RefTag* %[[RES2]], %struct.RefTag** %[[YVAR]],
327+
// CHECK-NEXT: store %struct.RefTag* %[[RES2]], %struct.RefTag** %[[TMP_EXPRCLEANUP1]],
328+
// CHECK: %[[LOAD_TMP1:.+]] = load %struct.RefTag*, %struct.RefTag** %[[TMP_EXPRCLEANUP1]],
329+
// CHECK: store %struct.RefTag* %[[LOAD_TMP1]], %struct.RefTag** %[[YVAR]],
324330

325331
RefTag& y = co_await AwaitResumeReturnsLValue{};
326332
// CHECK: %[[RES3:.+]] = call nonnull align 1 dereferenceable({{.*}}) %struct.RefTag* @_ZN24AwaitResumeReturnsLValue12await_resumeEv(%struct.AwaitResumeReturnsLValue* {{[^,]*}} %[[TMP2]])
327-
// CHECK-NEXT: store %struct.RefTag* %[[RES3]], %struct.RefTag** %[[ZVAR]],
333+
// CHECK-NEXT: store %struct.RefTag* %[[RES3]], %struct.RefTag** %[[TMP_EXPRCLEANUP2]],
334+
// CHECK: %[[LOAD_TMP2:.+]] = load %struct.RefTag*, %struct.RefTag** %[[TMP_EXPRCLEANUP2]],
335+
// CHECK: store %struct.RefTag* %[[LOAD_TMP2]], %struct.RefTag** %[[ZVAR]],
328336
RefTag& z = co_yield 42;
329337
}
330338

clang/test/CodeGenCoroutines/coro-dest-slot.cpp

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,24 @@ struct coro {
1717
extern "C" coro f(int) { co_return; }
1818
// Verify that cleanup.dest.slot is eliminated in a coroutine.
1919
// CHECK-LABEL: f(
20+
// CHECK: %[[INIT_SUSPEND:.+]] = call i8 @llvm.coro.suspend(
21+
// CHECK-NEXT: switch i8 %[[INIT_SUSPEND]], label
22+
// CHECK-NEXT: i8 0, label %[[INIT_READY:.+]]
23+
// CHECK-NEXT: i8 1, label %[[INIT_CLEANUP:.+]]
24+
// CHECK-NEXT: ]
25+
// CHECK: %[[CLEANUP_DEST0:.+]] = phi i32 [ 0, %[[INIT_READY]] ], [ 2, %[[INIT_CLEANUP]] ]
26+
27+
// CHECK: %[[FINAL_SUSPEND:.+]] = call i8 @llvm.coro.suspend(
28+
// CHECK-NEXT: switch i8 %29, label %coro.ret [
29+
// CHECK-NEXT: i8 0, label %[[FINAL_READY:.+]]
30+
// CHECK-NEXT: i8 1, label %[[FINAL_CLEANUP:.+]]
31+
// CHECK-NEXT: ]
32+
2033
// CHECK: call void @_ZNSt12experimental13coroutines_v113suspend_never12await_resumeEv(
21-
// CHECK: %[[CLEANUP_DEST:.+]] = phi i32 [ 0, %{{.+}} ], [ 2, %{{.+}} ], [ 2, %{{.+}} ]
34+
// CHECK: %[[CLEANUP_DEST1:.+]] = phi i32 [ 0, %[[FINAL_READY]] ], [ 2, %[[FINAL_CLEANUP]] ]
35+
// CHECK: %[[CLEANUP_DEST2:.+]] = phi i32 [ %[[CLEANUP_DEST0]], %{{.+}} ], [ %[[CLEANUP_DEST1]], %{{.+}} ], [ 0, %{{.+}} ]
2236
// CHECK: call i8* @llvm.coro.free(
23-
// CHECK: switch i32 %cleanup.dest.slot.0, label %{{.+}} [
37+
// CHECK: switch i32 %[[CLEANUP_DEST2]], label %{{.+}} [
2438
// CHECK-NEXT: i32 0
2539
// CHECK-NEXT: i32 2
2640
// CHECK-NEXT: ]

clang/test/CodeGenCoroutines/coro-params.cpp

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,11 @@ void f(int val, MoveOnly moParam, MoveAndCopy mcParam) {
7070

7171
// CHECK: call i8* @llvm.coro.begin(
7272
// CHECK: call void @_ZN8MoveOnlyC1EOS_(%struct.MoveOnly* {{[^,]*}} %[[MoCopy]], %struct.MoveOnly* nonnull align 4 dereferenceable(4) %[[MoParam]])
73+
// CHECK-NEXT: bitcast %struct.MoveAndCopy* %[[McCopy]] to i8*
74+
// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(
7375
// CHECK-NEXT: call void @_ZN11MoveAndCopyC1EOS_(%struct.MoveAndCopy* {{[^,]*}} %[[McCopy]], %struct.MoveAndCopy* nonnull align 4 dereferenceable(4) %[[McParam]]) #
76+
// CHECK-NEXT: bitcast %"struct.std::experimental::coroutine_traits<void, int, MoveOnly, MoveAndCopy>::promise_type"* %__promise to i8*
77+
// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(
7478
// CHECK-NEXT: invoke void @_ZNSt12experimental16coroutine_traitsIJvi8MoveOnly11MoveAndCopyEE12promise_typeC1Ev(
7579

7680
// CHECK: call void @_ZN14suspend_always12await_resumeEv(
@@ -89,9 +93,17 @@ void f(int val, MoveOnly moParam, MoveAndCopy mcParam) {
8993
// CHECK: call void @_ZN14suspend_always12await_resumeEv(
9094

9195
// Destroy promise, then parameter copies:
92-
// CHECK: call void @_ZNSt12experimental16coroutine_traitsIJvi8MoveOnly11MoveAndCopyEE12promise_typeD1Ev(%"struct.std::experimental::coroutine_traits<void, int, MoveOnly, MoveAndCopy>::promise_type"* {{[^,]*}} %__promise) #2
96+
// CHECK: call void @_ZNSt12experimental16coroutine_traitsIJvi8MoveOnly11MoveAndCopyEE12promise_typeD1Ev(%"struct.std::experimental::coroutine_traits<void, int, MoveOnly, MoveAndCopy>::promise_type"* {{[^,]*}} %__promise)
97+
// CHECK-NEXT: bitcast %"struct.std::experimental::coroutine_traits<void, int, MoveOnly, MoveAndCopy>::promise_type"* %__promise to i8*
98+
// CHECK-NEXT: call void @llvm.lifetime.end.p0i8(
9399
// CHECK-NEXT: call void @_ZN11MoveAndCopyD1Ev(%struct.MoveAndCopy* {{[^,]*}} %[[McCopy]])
100+
// CHECK-NEXT: bitcast %struct.MoveAndCopy* %[[McCopy]] to i8*
101+
// CHECK-NEXT: call void @llvm.lifetime.end.p0i8(
94102
// CHECK-NEXT: call void @_ZN8MoveOnlyD1Ev(%struct.MoveOnly* {{[^,]*}} %[[MoCopy]]
103+
// CHECK-NEXT: bitcast %struct.MoveOnly* %[[MoCopy]] to i8*
104+
// CHECK-NEXT: call void @llvm.lifetime.end.p0i8(
105+
// CHECK-NEXT: bitcast i32* %{{.+}} to i8*
106+
// CHECK-NEXT: call void @llvm.lifetime.end.p0i8(
95107
// CHECK-NEXT: call i8* @llvm.coro.free(
96108
}
97109

@@ -103,9 +115,17 @@ void dependent_params(T x, U, U y) {
103115
// CHECK-NEXT: %[[y_copy:.+]] = alloca %struct.B
104116

105117
// CHECK: call i8* @llvm.coro.begin
118+
// CHECK-NEXT: bitcast %struct.A* %[[x_copy]] to i8*
119+
// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(
106120
// CHECK-NEXT: call void @_ZN1AC1EOS_(%struct.A* {{[^,]*}} %[[x_copy]], %struct.A* nonnull align 4 dereferenceable(512) %x)
121+
// CHECK-NEXT: bitcast %struct.B* %[[unnamed_copy]] to i8*
122+
// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(
107123
// CHECK-NEXT: call void @_ZN1BC1EOS_(%struct.B* {{[^,]*}} %[[unnamed_copy]], %struct.B* nonnull align 4 dereferenceable(512) %0)
124+
// CHECK-NEXT: %10 = bitcast %struct.B* %[[y_copy]] to i8*
125+
// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(
108126
// CHECK-NEXT: call void @_ZN1BC1EOS_(%struct.B* {{[^,]*}} %[[y_copy]], %struct.B* nonnull align 4 dereferenceable(512) %y)
127+
// CHECK-NEXT: bitcast %"struct.std::experimental::coroutine_traits<void, A, B, B>::promise_type"* %__promise to i8*
128+
// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(
109129
// CHECK-NEXT: invoke void @_ZNSt12experimental16coroutine_traitsIJv1A1BS2_EE12promise_typeC1Ev(
110130

111131
co_return;

0 commit comments

Comments
 (0)