Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Asan] Pre-commit test for asan support of funclet token #82631

Merged
merged 1 commit into from
Mar 1, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
459 changes: 459 additions & 0 deletions llvm/test/Instrumentation/AddressSanitizer/asan-funclet.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,459 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4

; Warning! The output of this test is currently invalid.
; It serves as a base for the bugfix patch to highlight the modified generated code.

; Test appropriate tagging of funclet for function calls generated by asan.
; RUN: opt -S -passes=asan,win-eh-prepare -asan-use-stack-safety=0 -asan-max-inline-poisoning-size=0 \
; RUN: -asan-detect-invalid-pointer-cmp -asan-detect-invalid-pointer-sub -asan-use-after-scope < %s | FileCheck %s --check-prefixes=CHECK,CHECK-INLINE
; RUN: opt -S -passes=asan,win-eh-prepare -asan-use-stack-safety=0 -asan-max-inline-poisoning-size=0 -asan-instrumentation-with-call-threshold=0 \
; RUN: -asan-detect-invalid-pointer-cmp -asan-detect-invalid-pointer-sub -asan-use-after-scope < %s | FileCheck %s --check-prefixes=CHECK,CHECK-OUTLINE

; REQUIRES: x86-registered-target

target triple = "x86_64-pc-windows-msvc"

declare void @DeInit(ptr)
declare void @MayThrowFunc()
declare void @NoReturn() noreturn

declare void @llvm.memmove.p0.p0.i64(ptr nocapture, ptr nocapture readonly, i64, i1)
declare void @llvm.memcpy.p0.p0.i64(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i64, i1)
declare void @llvm.memset.p0.i64(ptr nocapture writeonly, i8, i64, i1)
declare void @llvm.lifetime.start.p0(i64, ptr nocapture) nounwind
declare void @llvm.lifetime.end.p0(i64, ptr nocapture) nounwind

declare i32 @__CxxFrameHandler3(...)
declare i32 @dummyPersonality(...)

define void @FuncletPersonality(ptr %ptrParam) sanitize_address personality ptr @__CxxFrameHandler3 {
; CHECK-INLINE-LABEL: define void @FuncletPersonality(
; CHECK-INLINE-SAME: ptr [[PTRPARAM:%.*]]) #[[ATTR4:[0-9]+]] personality ptr @__CxxFrameHandler3 {
; CHECK-INLINE-NEXT: entry:
; CHECK-INLINE-NEXT: [[TMP0:%.*]] = alloca i64, align 32
; CHECK-INLINE-NEXT: store i64 0, ptr [[TMP0]], align 8
; CHECK-INLINE-NEXT: [[TMP1:%.*]] = load i64, ptr @__asan_shadow_memory_dynamic_address, align 8
; CHECK-INLINE-NEXT: [[ASAN_LOCAL_STACK_BASE:%.*]] = alloca i64, align 8
; CHECK-INLINE-NEXT: [[TMP2:%.*]] = load i32, ptr @__asan_option_detect_stack_use_after_return, align 4
; CHECK-INLINE-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 0
; CHECK-INLINE-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP6:%.*]]
; CHECK-INLINE: 4:
; CHECK-INLINE-NEXT: [[TMP5:%.*]] = call i64 @__asan_stack_malloc_8(i64 8544)
; CHECK-INLINE-NEXT: br label [[TMP6]]
; CHECK-INLINE: 6:
; CHECK-INLINE-NEXT: [[TMP7:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[TMP5]], [[TMP4]] ]
; CHECK-INLINE-NEXT: [[TMP8:%.*]] = icmp eq i64 [[TMP7]], 0
; CHECK-INLINE-NEXT: br i1 [[TMP8]], label [[TMP9:%.*]], label [[TMP11:%.*]]
; CHECK-INLINE: 9:
; CHECK-INLINE-NEXT: [[MYALLOCA:%.*]] = alloca i8, i64 8544, align 32
; CHECK-INLINE-NEXT: [[TMP10:%.*]] = ptrtoint ptr [[MYALLOCA]] to i64
; CHECK-INLINE-NEXT: br label [[TMP11]]
; CHECK-INLINE: 11:
; CHECK-INLINE-NEXT: [[TMP12:%.*]] = phi i64 [ [[TMP7]], [[TMP6]] ], [ [[TMP10]], [[TMP9]] ]
; CHECK-INLINE-NEXT: store i64 [[TMP12]], ptr [[ASAN_LOCAL_STACK_BASE]], align 8
; CHECK-INLINE-NEXT: [[TMP13:%.*]] = add i64 [[TMP12]], 32
; CHECK-INLINE-NEXT: [[TMP14:%.*]] = inttoptr i64 [[TMP13]] to ptr
; CHECK-INLINE-NEXT: [[TMP15:%.*]] = add i64 [[TMP12]], 8528
; CHECK-INLINE-NEXT: [[TMP16:%.*]] = inttoptr i64 [[TMP15]] to ptr
; CHECK-INLINE-NEXT: [[TMP17:%.*]] = inttoptr i64 [[TMP12]] to ptr
; CHECK-INLINE-NEXT: store i64 1102416563, ptr [[TMP17]], align 8
; CHECK-INLINE-NEXT: [[TMP18:%.*]] = add i64 [[TMP12]], 8
; CHECK-INLINE-NEXT: [[TMP19:%.*]] = inttoptr i64 [[TMP18]] to ptr
; CHECK-INLINE-NEXT: store i64 ptrtoint (ptr @___asan_gen_ to i64), ptr [[TMP19]], align 8
; CHECK-INLINE-NEXT: [[TMP20:%.*]] = add i64 [[TMP12]], 16
; CHECK-INLINE-NEXT: [[TMP21:%.*]] = inttoptr i64 [[TMP20]] to ptr
; CHECK-INLINE-NEXT: store i64 ptrtoint (ptr @FuncletPersonality to i64), ptr [[TMP21]], align 8
; CHECK-INLINE-NEXT: [[TMP22:%.*]] = lshr i64 [[TMP12]], 3
; CHECK-INLINE-NEXT: [[TMP23:%.*]] = add i64 [[TMP22]], [[TMP1]]
; CHECK-INLINE-NEXT: call void @__asan_set_shadow_f1(i64 [[TMP23]], i64 4)
; CHECK-INLINE-NEXT: [[TMP24:%.*]] = add i64 [[TMP23]], 1028
; CHECK-INLINE-NEXT: call void @__asan_set_shadow_f2(i64 [[TMP24]], i64 32)
; CHECK-INLINE-NEXT: [[TMP25:%.*]] = add i64 [[TMP23]], 1060
; CHECK-INLINE-NEXT: call void @__asan_set_shadow_04(i64 [[TMP25]], i64 1)
; CHECK-INLINE-NEXT: [[TMP26:%.*]] = add i64 [[TMP23]], 1061
; CHECK-INLINE-NEXT: call void @__asan_set_shadow_f2(i64 [[TMP26]], i64 1)
; CHECK-INLINE-NEXT: [[TMP27:%.*]] = add i64 [[TMP23]], 1062
; CHECK-INLINE-NEXT: call void @__asan_set_shadow_04(i64 [[TMP27]], i64 1)
; CHECK-INLINE-NEXT: [[TMP28:%.*]] = add i64 [[TMP23]], 1063
; CHECK-INLINE-NEXT: call void @__asan_set_shadow_f2(i64 [[TMP28]], i64 1)
; CHECK-INLINE-NEXT: [[TMP29:%.*]] = add i64 [[TMP23]], 1064
; CHECK-INLINE-NEXT: call void @__asan_set_shadow_04(i64 [[TMP29]], i64 1)
; CHECK-INLINE-NEXT: [[TMP30:%.*]] = add i64 [[TMP23]], 1065
; CHECK-INLINE-NEXT: call void @__asan_set_shadow_f2(i64 [[TMP30]], i64 1)
; CHECK-INLINE-NEXT: [[TMP31:%.*]] = add i64 [[TMP23]], 1066
; CHECK-INLINE-NEXT: call void @__asan_set_shadow_f8(i64 [[TMP31]], i64 1)
; CHECK-INLINE-NEXT: [[TMP32:%.*]] = add i64 [[TMP23]], 1067
; CHECK-INLINE-NEXT: call void @__asan_set_shadow_f3(i64 [[TMP32]], i64 1)
; CHECK-INLINE-NEXT: [[TMP33:%.*]] = add i64 [[TMP23]], 1066
; CHECK-INLINE-NEXT: call void @__asan_set_shadow_04(i64 [[TMP33]], i64 1)
; CHECK-INLINE-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr [[TMP16]])
; CHECK-INLINE-NEXT: [[TMP34:%.*]] = lshr i64 [[TMP15]], 3
; CHECK-INLINE-NEXT: [[TMP35:%.*]] = add i64 [[TMP34]], [[TMP1]]
; CHECK-INLINE-NEXT: [[TMP36:%.*]] = inttoptr i64 [[TMP35]] to ptr
; CHECK-INLINE-NEXT: [[TMP37:%.*]] = load i8, ptr [[TMP36]], align 1
; CHECK-INLINE-NEXT: [[TMP38:%.*]] = icmp ne i8 [[TMP37]], 0
; CHECK-INLINE-NEXT: br i1 [[TMP38]], label [[TMP39:%.*]], label [[TMP44:%.*]], !prof [[PROF0:![0-9]+]]
; CHECK-INLINE: 39:
; CHECK-INLINE-NEXT: [[TMP40:%.*]] = and i64 [[TMP15]], 7
; CHECK-INLINE-NEXT: [[TMP41:%.*]] = trunc i64 [[TMP40]] to i8
; CHECK-INLINE-NEXT: [[TMP42:%.*]] = icmp sge i8 [[TMP41]], [[TMP37]]
; CHECK-INLINE-NEXT: br i1 [[TMP42]], label [[TMP43:%.*]], label [[TMP44]]
; CHECK-INLINE: 43:
; CHECK-INLINE-NEXT: call void @__asan_report_store1(i64 [[TMP15]]) #[[ATTR8:[0-9]+]]
; CHECK-INLINE-NEXT: unreachable
; CHECK-INLINE: 44:
; CHECK-INLINE-NEXT: store volatile i8 0, ptr [[TMP16]], align 1
; CHECK-INLINE-NEXT: [[TMP45:%.*]] = add i64 [[TMP23]], 1066
; CHECK-INLINE-NEXT: call void @__asan_set_shadow_f8(i64 [[TMP45]], i64 1)
; CHECK-INLINE-NEXT: call void @llvm.lifetime.end.p0(i64 4, ptr [[TMP16]])
; CHECK-INLINE-NEXT: [[TMP46:%.*]] = alloca i8, i64 96, align 32
; CHECK-INLINE-NEXT: [[TMP47:%.*]] = ptrtoint ptr [[TMP46]] to i64
; CHECK-INLINE-NEXT: [[TMP48:%.*]] = add i64 [[TMP47]], 32
; CHECK-INLINE-NEXT: call void @__asan_alloca_poison(i64 [[TMP48]], i64 4)
; CHECK-INLINE-NEXT: [[TMP49:%.*]] = ptrtoint ptr [[TMP46]] to i64
; CHECK-INLINE-NEXT: store i64 [[TMP49]], ptr [[TMP0]], align 8
; CHECK-INLINE-NEXT: [[TMP50:%.*]] = inttoptr i64 [[TMP48]] to ptr
; CHECK-INLINE-NEXT: [[TMP51:%.*]] = alloca i8, i64 96, align 32
; CHECK-INLINE-NEXT: [[TMP52:%.*]] = ptrtoint ptr [[TMP51]] to i64
; CHECK-INLINE-NEXT: [[TMP53:%.*]] = add i64 [[TMP52]], 32
; CHECK-INLINE-NEXT: call void @__asan_alloca_poison(i64 [[TMP53]], i64 8)
; CHECK-INLINE-NEXT: [[TMP54:%.*]] = ptrtoint ptr [[TMP51]] to i64
; CHECK-INLINE-NEXT: store i64 [[TMP54]], ptr [[TMP0]], align 8
; CHECK-INLINE-NEXT: [[TMP55:%.*]] = inttoptr i64 [[TMP53]] to ptr
; CHECK-INLINE-NEXT: [[TMP56:%.*]] = lshr i64 [[TMP53]], 3
; CHECK-INLINE-NEXT: [[TMP57:%.*]] = add i64 [[TMP56]], [[TMP1]]
; CHECK-INLINE-NEXT: [[TMP58:%.*]] = inttoptr i64 [[TMP57]] to ptr
; CHECK-INLINE-NEXT: [[TMP59:%.*]] = load i8, ptr [[TMP58]], align 1
; CHECK-INLINE-NEXT: [[TMP60:%.*]] = icmp ne i8 [[TMP59]], 0
; CHECK-INLINE-NEXT: br i1 [[TMP60]], label [[TMP61:%.*]], label [[TMP62:%.*]]
; CHECK-INLINE: 61:
; CHECK-INLINE-NEXT: call void @__asan_report_store8(i64 [[TMP53]]) #[[ATTR8]]
; CHECK-INLINE-NEXT: unreachable
; CHECK-INLINE: 62:
; CHECK-INLINE-NEXT: store volatile i64 0, ptr [[TMP55]], align 8
; CHECK-INLINE-NEXT: [[TMPCOPYI64:%.*]] = load i64, ptr [[TMP55]], align 8
; CHECK-INLINE-NEXT: [[TMP63:%.*]] = and i64 [[TMPCOPYI64]], 31
; CHECK-INLINE-NEXT: [[TMP64:%.*]] = sub i64 32, [[TMP63]]
; CHECK-INLINE-NEXT: [[TMP65:%.*]] = icmp ne i64 [[TMP64]], 32
; CHECK-INLINE-NEXT: [[TMP66:%.*]] = select i1 [[TMP65]], i64 [[TMP64]], i64 0
; CHECK-INLINE-NEXT: [[TMP67:%.*]] = add i64 64, [[TMP66]]
; CHECK-INLINE-NEXT: [[TMP68:%.*]] = add i64 [[TMPCOPYI64]], [[TMP67]]
; CHECK-INLINE-NEXT: [[TMP69:%.*]] = alloca i8, i64 [[TMP68]], align 32
; CHECK-INLINE-NEXT: [[TMP70:%.*]] = ptrtoint ptr [[TMP69]] to i64
; CHECK-INLINE-NEXT: [[TMP71:%.*]] = add i64 [[TMP70]], 32
; CHECK-INLINE-NEXT: call void @__asan_alloca_poison(i64 [[TMP71]], i64 [[TMPCOPYI64]])
; CHECK-INLINE-NEXT: [[TMP72:%.*]] = ptrtoint ptr [[TMP69]] to i64
; CHECK-INLINE-NEXT: store i64 [[TMP72]], ptr [[TMP0]], align 8
; CHECK-INLINE-NEXT: [[TMP73:%.*]] = inttoptr i64 [[TMP71]] to ptr
; CHECK-INLINE-NEXT: [[TMP74:%.*]] = lshr i64 [[TMP71]], 3
; CHECK-INLINE-NEXT: [[TMP75:%.*]] = add i64 [[TMP74]], [[TMP1]]
; CHECK-INLINE-NEXT: [[TMP76:%.*]] = inttoptr i64 [[TMP75]] to ptr
; CHECK-INLINE-NEXT: [[TMP77:%.*]] = load i8, ptr [[TMP76]], align 1
; CHECK-INLINE-NEXT: [[TMP78:%.*]] = icmp ne i8 [[TMP77]], 0
; CHECK-INLINE-NEXT: br i1 [[TMP78]], label [[TMP79:%.*]], label [[TMP84:%.*]], !prof [[PROF0]]
; CHECK-INLINE: 79:
; CHECK-INLINE-NEXT: [[TMP80:%.*]] = and i64 [[TMP71]], 7
; CHECK-INLINE-NEXT: [[TMP81:%.*]] = trunc i64 [[TMP80]] to i8
; CHECK-INLINE-NEXT: [[TMP82:%.*]] = icmp sge i8 [[TMP81]], [[TMP77]]
; CHECK-INLINE-NEXT: br i1 [[TMP82]], label [[TMP83:%.*]], label [[TMP84]]
; CHECK-INLINE: 83:
; CHECK-INLINE-NEXT: call void @__asan_report_store1(i64 [[TMP71]]) #[[ATTR8]]
; CHECK-INLINE-NEXT: unreachable
; CHECK-INLINE: 84:
; CHECK-INLINE-NEXT: store volatile i8 0, ptr [[TMP73]], align 1
; CHECK-INLINE-NEXT: invoke void @MayThrowFunc()
; CHECK-INLINE-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[EHCLEANUP:%.*]]
; CHECK-INLINE: invoke.cont:
; CHECK-INLINE-NEXT: call void @DeInit(ptr [[TMP14]])
; CHECK-INLINE-NEXT: [[TMP85:%.*]] = ptrtoint ptr [[TMP0]] to i64
; CHECK-INLINE-NEXT: [[TMP86:%.*]] = load i64, ptr [[TMP0]], align 8
; CHECK-INLINE-NEXT: call void @__asan_allocas_unpoison(i64 [[TMP86]], i64 [[TMP85]])
; CHECK-INLINE-NEXT: store i64 1172321806, ptr [[TMP17]], align 8
; CHECK-INLINE-NEXT: [[TMP87:%.*]] = icmp ne i64 [[TMP7]], 0
; CHECK-INLINE-NEXT: br i1 [[TMP87]], label [[TMP88:%.*]], label [[TMP89:%.*]]
; CHECK-INLINE: 88:
; CHECK-INLINE-NEXT: call void @__asan_stack_free_8(i64 [[TMP7]], i64 8544)
; CHECK-INLINE-NEXT: br label [[TMP91:%.*]]
; CHECK-INLINE: 89:
; CHECK-INLINE-NEXT: call void @__asan_set_shadow_00(i64 [[TMP23]], i64 4)
; CHECK-INLINE-NEXT: [[TMP90:%.*]] = add i64 [[TMP23]], 1028
; CHECK-INLINE-NEXT: call void @__asan_set_shadow_00(i64 [[TMP90]], i64 40)
; CHECK-INLINE-NEXT: br label [[TMP91]]
; CHECK-INLINE: 91:
; CHECK-INLINE-NEXT: ret void
; CHECK-INLINE: ehcleanup:
; CHECK-INLINE-NEXT: [[TMP92:%.*]] = cleanuppad within none []
; CHECK-INLINE-NEXT: unreachable
;
; CHECK-OUTLINE-LABEL: define void @FuncletPersonality(
; CHECK-OUTLINE-SAME: ptr [[PTRPARAM:%.*]]) #[[ATTR4:[0-9]+]] personality ptr @__CxxFrameHandler3 {
; CHECK-OUTLINE-NEXT: entry:
; CHECK-OUTLINE-NEXT: [[TMP0:%.*]] = alloca i64, align 32
; CHECK-OUTLINE-NEXT: store i64 0, ptr [[TMP0]], align 8
; CHECK-OUTLINE-NEXT: [[TMP1:%.*]] = load i64, ptr @__asan_shadow_memory_dynamic_address, align 8
; CHECK-OUTLINE-NEXT: [[ASAN_LOCAL_STACK_BASE:%.*]] = alloca i64, align 8
; CHECK-OUTLINE-NEXT: [[TMP2:%.*]] = load i32, ptr @__asan_option_detect_stack_use_after_return, align 4
; CHECK-OUTLINE-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 0
; CHECK-OUTLINE-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP6:%.*]]
; CHECK-OUTLINE: 4:
; CHECK-OUTLINE-NEXT: [[TMP5:%.*]] = call i64 @__asan_stack_malloc_8(i64 8608)
; CHECK-OUTLINE-NEXT: br label [[TMP6]]
; CHECK-OUTLINE: 6:
; CHECK-OUTLINE-NEXT: [[TMP7:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[TMP5]], [[TMP4]] ]
; CHECK-OUTLINE-NEXT: [[TMP8:%.*]] = icmp eq i64 [[TMP7]], 0
; CHECK-OUTLINE-NEXT: br i1 [[TMP8]], label [[TMP9:%.*]], label [[TMP11:%.*]]
; CHECK-OUTLINE: 9:
; CHECK-OUTLINE-NEXT: [[MYALLOCA:%.*]] = alloca i8, i64 8608, align 32
; CHECK-OUTLINE-NEXT: [[TMP10:%.*]] = ptrtoint ptr [[MYALLOCA]] to i64
; CHECK-OUTLINE-NEXT: br label [[TMP11]]
; CHECK-OUTLINE: 11:
; CHECK-OUTLINE-NEXT: [[TMP12:%.*]] = phi i64 [ [[TMP7]], [[TMP6]] ], [ [[TMP10]], [[TMP9]] ]
; CHECK-OUTLINE-NEXT: store i64 [[TMP12]], ptr [[ASAN_LOCAL_STACK_BASE]], align 8
; CHECK-OUTLINE-NEXT: [[TMP13:%.*]] = add i64 [[TMP12]], 32
; CHECK-OUTLINE-NEXT: [[TMP14:%.*]] = inttoptr i64 [[TMP13]] to ptr
; CHECK-OUTLINE-NEXT: [[TMP15:%.*]] = add i64 [[TMP12]], 8528
; CHECK-OUTLINE-NEXT: [[TMP16:%.*]] = inttoptr i64 [[TMP15]] to ptr
; CHECK-OUTLINE-NEXT: [[TMP17:%.*]] = add i64 [[TMP12]], 8560
; CHECK-OUTLINE-NEXT: [[TMP18:%.*]] = inttoptr i64 [[TMP17]] to ptr
; CHECK-OUTLINE-NEXT: [[TMP19:%.*]] = inttoptr i64 [[TMP12]] to ptr
; CHECK-OUTLINE-NEXT: store i64 1102416563, ptr [[TMP19]], align 8
; CHECK-OUTLINE-NEXT: [[TMP20:%.*]] = add i64 [[TMP12]], 8
; CHECK-OUTLINE-NEXT: [[TMP21:%.*]] = inttoptr i64 [[TMP20]] to ptr
; CHECK-OUTLINE-NEXT: store i64 ptrtoint (ptr @___asan_gen_ to i64), ptr [[TMP21]], align 8
; CHECK-OUTLINE-NEXT: [[TMP22:%.*]] = add i64 [[TMP12]], 16
; CHECK-OUTLINE-NEXT: [[TMP23:%.*]] = inttoptr i64 [[TMP22]] to ptr
; CHECK-OUTLINE-NEXT: store i64 ptrtoint (ptr @FuncletPersonality to i64), ptr [[TMP23]], align 8
; CHECK-OUTLINE-NEXT: [[TMP24:%.*]] = lshr i64 [[TMP12]], 3
; CHECK-OUTLINE-NEXT: [[TMP25:%.*]] = add i64 [[TMP24]], [[TMP1]]
; CHECK-OUTLINE-NEXT: call void @__asan_set_shadow_f1(i64 [[TMP25]], i64 4)
; CHECK-OUTLINE-NEXT: [[TMP26:%.*]] = add i64 [[TMP25]], 1028
; CHECK-OUTLINE-NEXT: call void @__asan_set_shadow_f2(i64 [[TMP26]], i64 32)
; CHECK-OUTLINE-NEXT: [[TMP27:%.*]] = add i64 [[TMP25]], 1060
; CHECK-OUTLINE-NEXT: call void @__asan_set_shadow_04(i64 [[TMP27]], i64 1)
; CHECK-OUTLINE-NEXT: [[TMP28:%.*]] = add i64 [[TMP25]], 1061
; CHECK-OUTLINE-NEXT: call void @__asan_set_shadow_f2(i64 [[TMP28]], i64 1)
; CHECK-OUTLINE-NEXT: [[TMP29:%.*]] = add i64 [[TMP25]], 1062
; CHECK-OUTLINE-NEXT: call void @__asan_set_shadow_04(i64 [[TMP29]], i64 1)
; CHECK-OUTLINE-NEXT: [[TMP30:%.*]] = add i64 [[TMP25]], 1063
; CHECK-OUTLINE-NEXT: call void @__asan_set_shadow_f2(i64 [[TMP30]], i64 1)
; CHECK-OUTLINE-NEXT: [[TMP31:%.*]] = add i64 [[TMP25]], 1064
; CHECK-OUTLINE-NEXT: call void @__asan_set_shadow_04(i64 [[TMP31]], i64 1)
; CHECK-OUTLINE-NEXT: [[TMP32:%.*]] = add i64 [[TMP25]], 1065
; CHECK-OUTLINE-NEXT: call void @__asan_set_shadow_f2(i64 [[TMP32]], i64 1)
; CHECK-OUTLINE-NEXT: [[TMP33:%.*]] = add i64 [[TMP25]], 1066
; CHECK-OUTLINE-NEXT: call void @__asan_set_shadow_f8(i64 [[TMP33]], i64 1)
; CHECK-OUTLINE-NEXT: [[TMP34:%.*]] = add i64 [[TMP25]], 1067
; CHECK-OUTLINE-NEXT: call void @__asan_set_shadow_f2(i64 [[TMP34]], i64 1)
; CHECK-OUTLINE-NEXT: [[TMP35:%.*]] = add i64 [[TMP25]], 1068
; CHECK-OUTLINE-NEXT: call void @__asan_set_shadow_f8(i64 [[TMP35]], i64 1)
; CHECK-OUTLINE-NEXT: [[TMP36:%.*]] = add i64 [[TMP25]], 1069
; CHECK-OUTLINE-NEXT: call void @__asan_set_shadow_f2(i64 [[TMP36]], i64 1)
; CHECK-OUTLINE-NEXT: [[TMP37:%.*]] = add i64 [[TMP25]], 1071
; CHECK-OUTLINE-NEXT: call void @__asan_set_shadow_f3(i64 [[TMP37]], i64 5)
; CHECK-OUTLINE-NEXT: [[TMP38:%.*]] = add i64 [[TMP25]], 1066
; CHECK-OUTLINE-NEXT: call void @__asan_set_shadow_04(i64 [[TMP38]], i64 1)
; CHECK-OUTLINE-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr [[TMP16]])
; CHECK-OUTLINE-NEXT: call void @__asan_store1(i64 [[TMP15]])
; CHECK-OUTLINE-NEXT: store volatile i8 0, ptr [[TMP16]], align 1
; CHECK-OUTLINE-NEXT: [[TMP39:%.*]] = add i64 [[TMP25]], 1066
; CHECK-OUTLINE-NEXT: call void @__asan_set_shadow_f8(i64 [[TMP39]], i64 1)
; CHECK-OUTLINE-NEXT: call void @llvm.lifetime.end.p0(i64 4, ptr [[TMP16]])
; CHECK-OUTLINE-NEXT: call void @__asan_store8(i64 [[TMP17]])
; CHECK-OUTLINE-NEXT: store volatile i64 0, ptr [[TMP18]], align 8
; CHECK-OUTLINE-NEXT: [[TMPCOPYI64:%.*]] = load i64, ptr [[TMP18]], align 8
; CHECK-OUTLINE-NEXT: [[TMP40:%.*]] = and i64 [[TMPCOPYI64]], 31
; CHECK-OUTLINE-NEXT: [[TMP41:%.*]] = sub i64 32, [[TMP40]]
; CHECK-OUTLINE-NEXT: [[TMP42:%.*]] = icmp ne i64 [[TMP41]], 32
; CHECK-OUTLINE-NEXT: [[TMP43:%.*]] = select i1 [[TMP42]], i64 [[TMP41]], i64 0
; CHECK-OUTLINE-NEXT: [[TMP44:%.*]] = add i64 64, [[TMP43]]
; CHECK-OUTLINE-NEXT: [[TMP45:%.*]] = add i64 [[TMPCOPYI64]], [[TMP44]]
; CHECK-OUTLINE-NEXT: [[TMP46:%.*]] = alloca i8, i64 [[TMP45]], align 32
; CHECK-OUTLINE-NEXT: [[TMP47:%.*]] = ptrtoint ptr [[TMP46]] to i64
; CHECK-OUTLINE-NEXT: [[TMP48:%.*]] = add i64 [[TMP47]], 32
; CHECK-OUTLINE-NEXT: call void @__asan_alloca_poison(i64 [[TMP48]], i64 [[TMPCOPYI64]])
; CHECK-OUTLINE-NEXT: [[TMP49:%.*]] = ptrtoint ptr [[TMP46]] to i64
; CHECK-OUTLINE-NEXT: store i64 [[TMP49]], ptr [[TMP0]], align 8
; CHECK-OUTLINE-NEXT: [[TMP50:%.*]] = inttoptr i64 [[TMP48]] to ptr
; CHECK-OUTLINE-NEXT: call void @__asan_store1(i64 [[TMP48]])
; CHECK-OUTLINE-NEXT: store volatile i8 0, ptr [[TMP50]], align 1
; CHECK-OUTLINE-NEXT: invoke void @MayThrowFunc()
; CHECK-OUTLINE-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[EHCLEANUP:%.*]]
; CHECK-OUTLINE: invoke.cont:
; CHECK-OUTLINE-NEXT: call void @DeInit(ptr [[TMP14]])
; CHECK-OUTLINE-NEXT: [[TMP51:%.*]] = ptrtoint ptr [[TMP0]] to i64
; CHECK-OUTLINE-NEXT: [[TMP52:%.*]] = load i64, ptr [[TMP0]], align 8
; CHECK-OUTLINE-NEXT: call void @__asan_allocas_unpoison(i64 [[TMP52]], i64 [[TMP51]])
; CHECK-OUTLINE-NEXT: store i64 1172321806, ptr [[TMP19]], align 8
; CHECK-OUTLINE-NEXT: [[TMP53:%.*]] = icmp ne i64 [[TMP7]], 0
; CHECK-OUTLINE-NEXT: br i1 [[TMP53]], label [[TMP54:%.*]], label [[TMP55:%.*]]
; CHECK-OUTLINE: 54:
; CHECK-OUTLINE-NEXT: call void @__asan_stack_free_8(i64 [[TMP7]], i64 8608)
; CHECK-OUTLINE-NEXT: br label [[TMP58:%.*]]
; CHECK-OUTLINE: 55:
; CHECK-OUTLINE-NEXT: call void @__asan_set_shadow_00(i64 [[TMP25]], i64 4)
; CHECK-OUTLINE-NEXT: [[TMP56:%.*]] = add i64 [[TMP25]], 1028
; CHECK-OUTLINE-NEXT: call void @__asan_set_shadow_00(i64 [[TMP56]], i64 42)
; CHECK-OUTLINE-NEXT: [[TMP57:%.*]] = add i64 [[TMP25]], 1071
; CHECK-OUTLINE-NEXT: call void @__asan_set_shadow_00(i64 [[TMP57]], i64 5)
; CHECK-OUTLINE-NEXT: br label [[TMP58]]
; CHECK-OUTLINE: 58:
; CHECK-OUTLINE-NEXT: ret void
; CHECK-OUTLINE: ehcleanup:
; CHECK-OUTLINE-NEXT: [[TMP59:%.*]] = cleanuppad within none []
; CHECK-OUTLINE-NEXT: unreachable
;


entry:
; Large enough local alloca to have asan generate a __asan_stack_free_#() call
%largeObj = alloca [2048 x i32], align 16
%tmpInt1 = alloca i32, align 4
%tmpInt2 = alloca i32, align 4
%tmpInt3 = alloca i32, align 4

; Creating %lifetimeInt and %lifetimeArr, and managing their lifetimes
; to make asan generate stack poisoning calls
%lifetimeInt = alloca i32, align 4
call void @llvm.lifetime.start.p0(i64 4, ptr %lifetimeInt)
store volatile i8 0, ptr %lifetimeInt
call void @llvm.lifetime.end.p0(i64 4, ptr %lifetimeInt)
%lifetimeArr = alloca i32, align 4

; Dynamic alloca to generate a @__asan_allocas_unpoison call in ehcleanup
%tmpVolatilei64 = alloca i64, align 8
store volatile i64 0, ptr %tmpVolatilei64, align 8
%tmpCopyi64 = load i64, ptr %tmpVolatilei64, align 8
%tmpVolatilei8 = alloca i8, i64 %tmpCopyi64, align 32
store volatile i8 0, ptr %tmpVolatilei8

invoke void @MayThrowFunc()
to label %invoke.cont unwind label %ehcleanup
invoke.cont: ; preds = %entry
call void @DeInit(ptr %largeObj)
ret void

ehcleanup: ; preds = %entry
%0 = cleanuppad within none []

; Make asan add a call to __asan_unpoison_stack_memory
call void @llvm.lifetime.start.p0(i64 4, ptr %lifetimeArr)
; Make asan add a call to __asan_report_store1
store volatile i8 0, ptr %lifetimeArr
; Make asan add a call to __asan_poison_stack_memory
call void @llvm.lifetime.end.p0(i64 4, ptr %lifetimeArr)

call void @DeInit(ptr %largeObj) [ "funclet"(token %0) ]
call void @llvm.memset.p0.i64(ptr align 4 %tmpInt1, i8 0, i64 4, i1 false)
call void @llvm.memcpy.p0.p0.i64(ptr align 4 %tmpInt2, ptr align 4 %tmpInt1, i64 4, i1 false)
call void @llvm.memmove.p0.p0.i64(ptr align 4 %tmpInt3, ptr align 4 %tmpInt1, i64 4, i1 false)
%cmpAddr = icmp ule ptr %tmpInt1, %tmpInt2
%addr1 = ptrtoint ptr %tmpInt1 to i64
%addr2 = ptrtoint ptr %tmpInt2 to i64
%subAddr = sub i64 %addr1, %addr2

store i64 0, ptr %ptrParam, align 1

%cmp = icmp ne i64 %subAddr, 0
br i1 %cmp, label %ehexit, label %noreturncall

noreturncall:
call void @NoReturn(ptr null, ptr null) noreturn [ "funclet"(token %0) ]
unreachable

ehexit:
cleanupret from %0 unwind to caller

; Ensure unreachable basic block doesn't make the compiler assert, as it's a special case for coloring computation.
nopredecessor:
call void @llvm.memset.p0.i64(ptr align 4 %tmpInt1, i8 0, i64 4, i1 false)
unreachable
}

; Non-Windows personality, ensure no funclet gets attached to asan runtime call.
define void @OtherPersonality(ptr %ptrParam) sanitize_address personality ptr @dummyPersonality {
; CHECK-LABEL: define void @OtherPersonality(
; CHECK-SAME: ptr [[PTRPARAM:%.*]]) #[[ATTR4:[0-9]+]] personality ptr @dummyPersonality {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__asan_shadow_memory_dynamic_address, align 8
; CHECK-NEXT: [[ASAN_LOCAL_STACK_BASE:%.*]] = alloca i64, align 8
; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr @__asan_option_detect_stack_use_after_return, align 4
; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 0
; CHECK-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP5:%.*]]
; CHECK: 3:
; CHECK-NEXT: [[TMP4:%.*]] = call i64 @__asan_stack_malloc_0(i64 64)
; CHECK-NEXT: br label [[TMP5]]
; CHECK: 5:
; CHECK-NEXT: [[TMP6:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[TMP4]], [[TMP3]] ]
; CHECK-NEXT: [[TMP7:%.*]] = icmp eq i64 [[TMP6]], 0
; CHECK-NEXT: br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP10:%.*]]
; CHECK: 8:
; CHECK-NEXT: [[MYALLOCA:%.*]] = alloca i8, i64 64, align 32
; CHECK-NEXT: [[TMP9:%.*]] = ptrtoint ptr [[MYALLOCA]] to i64
; CHECK-NEXT: br label [[TMP10]]
; CHECK: 10:
; CHECK-NEXT: [[TMP11:%.*]] = phi i64 [ [[TMP6]], [[TMP5]] ], [ [[TMP9]], [[TMP8]] ]
; CHECK-NEXT: store i64 [[TMP11]], ptr [[ASAN_LOCAL_STACK_BASE]], align 8
; CHECK-NEXT: [[TMP12:%.*]] = add i64 [[TMP11]], 32
; CHECK-NEXT: [[TMP13:%.*]] = inttoptr i64 [[TMP12]] to ptr
; CHECK-NEXT: [[TMP14:%.*]] = inttoptr i64 [[TMP11]] to ptr
; CHECK-NEXT: store i64 1102416563, ptr [[TMP14]], align 8
; CHECK-NEXT: [[TMP15:%.*]] = add i64 [[TMP11]], 8
; CHECK-NEXT: [[TMP16:%.*]] = inttoptr i64 [[TMP15]] to ptr
; CHECK-NEXT: store i64 ptrtoint (ptr @___asan_gen_.1 to i64), ptr [[TMP16]], align 8
; CHECK-NEXT: [[TMP17:%.*]] = add i64 [[TMP11]], 16
; CHECK-NEXT: [[TMP18:%.*]] = inttoptr i64 [[TMP17]] to ptr
; CHECK-NEXT: store i64 ptrtoint (ptr @OtherPersonality to i64), ptr [[TMP18]], align 8
; CHECK-NEXT: [[TMP19:%.*]] = lshr i64 [[TMP11]], 3
; CHECK-NEXT: [[TMP20:%.*]] = add i64 [[TMP19]], [[TMP0]]
; CHECK-NEXT: [[TMP21:%.*]] = add i64 [[TMP20]], 0
; CHECK-NEXT: call void @__asan_set_shadow_f1(i64 [[TMP21]], i64 4)
; CHECK-NEXT: [[TMP22:%.*]] = add i64 [[TMP20]], 4
; CHECK-NEXT: call void @__asan_set_shadow_04(i64 [[TMP22]], i64 1)
; CHECK-NEXT: [[TMP23:%.*]] = add i64 [[TMP20]], 5
; CHECK-NEXT: call void @__asan_set_shadow_f3(i64 [[TMP23]], i64 3)
; CHECK-NEXT: invoke void @MayThrowFunc()
; CHECK-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[EHCLEANUP:%.*]]
; CHECK: invoke.cont:
; CHECK-NEXT: store i64 1172321806, ptr [[TMP14]], align 8
; CHECK-NEXT: [[TMP24:%.*]] = icmp ne i64 [[TMP6]], 0
; CHECK-NEXT: br i1 [[TMP24]], label [[TMP25:%.*]], label [[TMP26:%.*]]
; CHECK: 25:
; CHECK-NEXT: call void @__asan_stack_free_0(i64 [[TMP6]], i64 64)
; CHECK-NEXT: br label [[TMP28:%.*]]
; CHECK: 26:
; CHECK-NEXT: [[TMP27:%.*]] = add i64 [[TMP20]], 0
; CHECK-NEXT: call void @__asan_set_shadow_00(i64 [[TMP27]], i64 8)
; CHECK-NEXT: br label [[TMP28]]
; CHECK: 28:
; CHECK-NEXT: ret void
; CHECK: ehcleanup:
; CHECK-NEXT: [[TMP29:%.*]] = cleanuppad within none []
; CHECK-NEXT: [[TMP30:%.*]] = call ptr @__asan_memset(ptr [[TMP13]], i32 0, i64 4)
; CHECK-NEXT: store i64 1172321806, ptr [[TMP14]], align 8
; CHECK-NEXT: [[TMP31:%.*]] = icmp ne i64 [[TMP6]], 0
; CHECK-NEXT: br i1 [[TMP31]], label [[TMP32:%.*]], label [[TMP33:%.*]]
; CHECK: 32:
; CHECK-NEXT: call void @__asan_stack_free_0(i64 [[TMP6]], i64 64)
; CHECK-NEXT: br label [[TMP35:%.*]]
; CHECK: 33:
; CHECK-NEXT: [[TMP34:%.*]] = add i64 [[TMP20]], 0
; CHECK-NEXT: call void @__asan_set_shadow_00(i64 [[TMP34]], i64 8)
; CHECK-NEXT: br label [[TMP35]]
; CHECK: 35:
; CHECK-NEXT: cleanupret from [[TMP29]] unwind to caller
;
entry:
%tmpInt = alloca i32, align 4
invoke void @MayThrowFunc()
to label %invoke.cont unwind label %ehcleanup
invoke.cont: ; preds = %entry
ret void

ehcleanup: ; preds = %entry
%0 = cleanuppad within none []
call void @llvm.memset.p0.i64(ptr align 4 %tmpInt, i8 0, i64 4, i1 false)
cleanupret from %0 unwind to caller
}
;.
; CHECK-INLINE: [[PROF0]] = !{!"branch_weights", i32 1, i32 100000}
;.