| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals all --version 4 |
| ; RUN: opt -passes=ctx-instr-gen -profile-context-root=an_entrypoint \ |
| ; RUN: -S < %s | FileCheck --check-prefix=INSTRUMENT %s |
| ; RUN: opt -passes=ctx-instr-gen,assign-guid,ctx-instr-lower -profile-context-root=an_entrypoint \ |
| ; RUN: -profile-context-root=another_entrypoint_no_callees \ |
| ; RUN: -S < %s | FileCheck --check-prefix=LOWERING %s |
| |
| |
| declare void @bar() |
| |
| ;. |
| ; INSTRUMENT: @foo_alias = weak_odr unnamed_addr alias void (i32, ptr), ptr @foo |
| ;. |
| ; LOWERING: @__llvm_ctx_profile_callsite = external hidden thread_local global ptr |
| ; LOWERING: @__llvm_ctx_profile_expected_callee = external hidden thread_local global ptr |
| ; LOWERING: @[[GLOB0:[0-9]+]] = internal global { ptr, ptr, ptr, ptr, i8 } zeroinitializer |
| ; LOWERING: @[[GLOB1:[0-9]+]] = internal global { ptr, ptr, ptr, ptr, i8 } zeroinitializer |
| ; LOWERING: @[[GLOB2:[0-9]+]] = internal global { ptr, ptr, ptr, ptr, i8 } zeroinitializer |
| ; LOWERING: @[[GLOB3:[0-9]+]] = internal global { ptr, ptr, ptr, ptr, i8 } zeroinitializer |
| ; LOWERING: @[[GLOB4:[0-9]+]] = internal global { ptr, ptr, ptr, ptr, i8 } zeroinitializer |
| ; LOWERING: @[[GLOB5:[0-9]+]] = internal global { ptr, ptr, ptr, ptr, i8 } zeroinitializer |
| ; LOWERING: @[[GLOB6:[0-9]+]] = internal global { ptr, ptr, ptr, ptr, i8 } zeroinitializer |
| ; LOWERING: @[[GLOB7:[0-9]+]] = internal global { ptr, ptr, ptr, ptr, i8 } { ptr null, ptr null, ptr inttoptr (i64 1 to ptr), ptr null, i8 0 } |
| ; LOWERING: @[[GLOB8:[0-9]+]] = internal global { ptr, ptr, ptr, ptr, i8 } zeroinitializer |
| ; LOWERING: @foo_alias = weak_odr unnamed_addr alias void (i32, ptr), ptr @foo |
| ;. |
| define void @foo(i32 %a, ptr %fct) { |
| ; INSTRUMENT-LABEL: define void @foo( |
| ; INSTRUMENT-SAME: i32 [[A:%.*]], ptr [[FCT:%.*]]) { |
| ; INSTRUMENT-NEXT: call void @llvm.instrprof.increment(ptr @foo, i64 728453322856651412, i32 2, i32 0) |
| ; INSTRUMENT-NEXT: [[T:%.*]] = icmp eq i32 [[A]], 0 |
| ; INSTRUMENT-NEXT: br i1 [[T]], label [[YES:%.*]], label [[NO:%.*]] |
| ; INSTRUMENT: yes: |
| ; INSTRUMENT-NEXT: call void @llvm.instrprof.increment(ptr @foo, i64 728453322856651412, i32 2, i32 1) |
| ; INSTRUMENT-NEXT: call void @llvm.instrprof.callsite(ptr @foo, i64 728453322856651412, i32 2, i32 0, ptr [[FCT]]) |
| ; INSTRUMENT-NEXT: call void [[FCT]](i32 [[A]]) |
| ; INSTRUMENT-NEXT: br label [[EXIT:%.*]] |
| ; INSTRUMENT: no: |
| ; INSTRUMENT-NEXT: call void @llvm.instrprof.callsite(ptr @foo, i64 728453322856651412, i32 2, i32 1, ptr @bar) |
| ; INSTRUMENT-NEXT: call void @bar() |
| ; INSTRUMENT-NEXT: br label [[EXIT]] |
| ; INSTRUMENT: exit: |
| ; INSTRUMENT-NEXT: ret void |
| ; |
| ; LOWERING-LABEL: define void @foo( |
| ; LOWERING-SAME: i32 [[A:%.*]], ptr [[FCT:%.*]]) !guid [[META0:![0-9]+]] { |
| ; LOWERING-NEXT: [[TMP1:%.*]] = call ptr @__llvm_ctx_profile_get_context(ptr @[[GLOB0]], ptr @foo, i64 6699318081062747564, i32 2, i32 2) |
| ; LOWERING-NEXT: [[TMP2:%.*]] = ptrtoint ptr [[TMP1]] to i64 |
| ; LOWERING-NEXT: [[TMP3:%.*]] = and i64 [[TMP2]], 1 |
| ; LOWERING-NEXT: [[TMP4:%.*]] = call ptr @llvm.threadlocal.address.p0(ptr @__llvm_ctx_profile_expected_callee) |
| ; LOWERING-NEXT: [[TMP5:%.*]] = getelementptr ptr, ptr [[TMP4]], i64 [[TMP3]] |
| ; LOWERING-NEXT: [[TMP6:%.*]] = call ptr @llvm.threadlocal.address.p0(ptr @__llvm_ctx_profile_callsite) |
| ; LOWERING-NEXT: [[TMP7:%.*]] = getelementptr i32, ptr [[TMP6]], i64 [[TMP3]] |
| ; LOWERING-NEXT: [[TMP8:%.*]] = and i64 [[TMP2]], -2 |
| ; LOWERING-NEXT: [[TMP9:%.*]] = inttoptr i64 [[TMP8]] to ptr |
| ; LOWERING-NEXT: [[T:%.*]] = icmp eq i32 [[A]], 0 |
| ; LOWERING-NEXT: br i1 [[T]], label [[YES:%.*]], label [[NO:%.*]] |
| ; LOWERING: yes: |
| ; LOWERING-NEXT: [[TMP10:%.*]] = getelementptr { { i64, ptr, i32, i32 }, [2 x i64], [2 x ptr] }, ptr [[TMP9]], i32 0, i32 1, i32 1 |
| ; LOWERING-NEXT: [[TMP11:%.*]] = load i64, ptr [[TMP10]], align 4 |
| ; LOWERING-NEXT: [[TMP12:%.*]] = add i64 [[TMP11]], 1 |
| ; LOWERING-NEXT: store i64 [[TMP12]], ptr [[TMP10]], align 4 |
| ; LOWERING-NEXT: store volatile ptr [[FCT]], ptr [[TMP5]], align 8 |
| ; LOWERING-NEXT: [[TMP13:%.*]] = getelementptr { { i64, ptr, i32, i32 }, [2 x i64], [2 x ptr] }, ptr [[TMP1]], i32 0, i32 2, i32 0 |
| ; LOWERING-NEXT: store volatile ptr [[TMP13]], ptr [[TMP7]], align 8 |
| ; LOWERING-NEXT: call void [[FCT]](i32 [[A]]) |
| ; LOWERING-NEXT: br label [[EXIT:%.*]] |
| ; LOWERING: no: |
| ; LOWERING-NEXT: store volatile ptr @bar, ptr [[TMP5]], align 8 |
| ; LOWERING-NEXT: [[TMP14:%.*]] = getelementptr { { i64, ptr, i32, i32 }, [2 x i64], [2 x ptr] }, ptr [[TMP1]], i32 0, i32 2, i32 1 |
| ; LOWERING-NEXT: store volatile ptr [[TMP14]], ptr [[TMP7]], align 8 |
| ; LOWERING-NEXT: call void @bar() |
| ; LOWERING-NEXT: br label [[EXIT]] |
| ; LOWERING: exit: |
| ; LOWERING-NEXT: call void @__llvm_ctx_profile_release_context(ptr @[[GLOB0]]) |
| ; LOWERING-NEXT: ret void |
| ; |
| %t = icmp eq i32 %a, 0 |
| br i1 %t, label %yes, label %no |
| yes: |
| call void %fct(i32 %a) |
| br label %exit |
| no: |
| call void @bar() |
| br label %exit |
| exit: |
| ret void |
| } |
| |
| define void @an_entrypoint(i32 %a) { |
| ; INSTRUMENT-LABEL: define void @an_entrypoint( |
| ; INSTRUMENT-SAME: i32 [[A:%.*]]) { |
| ; INSTRUMENT-NEXT: call void @llvm.instrprof.increment(ptr @an_entrypoint, i64 784007058953177093, i32 2, i32 0) |
| ; INSTRUMENT-NEXT: [[T:%.*]] = icmp eq i32 [[A]], 0 |
| ; INSTRUMENT-NEXT: br i1 [[T]], label [[YES:%.*]], label [[NO:%.*]] |
| ; INSTRUMENT: yes: |
| ; INSTRUMENT-NEXT: call void @llvm.instrprof.increment(ptr @an_entrypoint, i64 784007058953177093, i32 2, i32 1) |
| ; INSTRUMENT-NEXT: call void @llvm.instrprof.callsite(ptr @an_entrypoint, i64 784007058953177093, i32 1, i32 0, ptr @foo) |
| ; INSTRUMENT-NEXT: call void @foo(i32 1, ptr null) |
| ; INSTRUMENT-NEXT: ret void |
| ; INSTRUMENT: no: |
| ; INSTRUMENT-NEXT: ret void |
| ; |
| ; LOWERING-LABEL: define void @an_entrypoint( |
| ; LOWERING-SAME: i32 [[A:%.*]]) !guid [[META1:![0-9]+]] { |
| ; LOWERING-NEXT: [[TMP1:%.*]] = call ptr @__llvm_ctx_profile_start_context(ptr @[[GLOB1]], i64 4909520559318251808, i32 2, i32 1) |
| ; LOWERING-NEXT: [[TMP2:%.*]] = ptrtoint ptr [[TMP1]] to i64 |
| ; LOWERING-NEXT: [[TMP3:%.*]] = and i64 [[TMP2]], 1 |
| ; LOWERING-NEXT: [[TMP4:%.*]] = call ptr @llvm.threadlocal.address.p0(ptr @__llvm_ctx_profile_expected_callee) |
| ; LOWERING-NEXT: [[TMP5:%.*]] = getelementptr ptr, ptr [[TMP4]], i64 [[TMP3]] |
| ; LOWERING-NEXT: [[TMP6:%.*]] = call ptr @llvm.threadlocal.address.p0(ptr @__llvm_ctx_profile_callsite) |
| ; LOWERING-NEXT: [[TMP7:%.*]] = getelementptr i32, ptr [[TMP6]], i64 [[TMP3]] |
| ; LOWERING-NEXT: [[TMP8:%.*]] = and i64 [[TMP2]], -2 |
| ; LOWERING-NEXT: [[TMP9:%.*]] = inttoptr i64 [[TMP8]] to ptr |
| ; LOWERING-NEXT: [[T:%.*]] = icmp eq i32 [[A]], 0 |
| ; LOWERING-NEXT: br i1 [[T]], label [[YES:%.*]], label [[NO:%.*]] |
| ; LOWERING: yes: |
| ; LOWERING-NEXT: [[TMP10:%.*]] = getelementptr { { i64, ptr, i32, i32 }, [2 x i64], [1 x ptr] }, ptr [[TMP9]], i32 0, i32 1, i32 1 |
| ; LOWERING-NEXT: [[TMP11:%.*]] = load i64, ptr [[TMP10]], align 4 |
| ; LOWERING-NEXT: [[TMP12:%.*]] = add i64 [[TMP11]], 1 |
| ; LOWERING-NEXT: store i64 [[TMP12]], ptr [[TMP10]], align 4 |
| ; LOWERING-NEXT: store volatile ptr @foo, ptr [[TMP5]], align 8 |
| ; LOWERING-NEXT: [[TMP13:%.*]] = getelementptr { { i64, ptr, i32, i32 }, [2 x i64], [1 x ptr] }, ptr [[TMP1]], i32 0, i32 2, i32 0 |
| ; LOWERING-NEXT: store volatile ptr [[TMP13]], ptr [[TMP7]], align 8 |
| ; LOWERING-NEXT: call void @foo(i32 1, ptr null) |
| ; LOWERING-NEXT: call void @__llvm_ctx_profile_release_context(ptr @[[GLOB1]]) |
| ; LOWERING-NEXT: ret void |
| ; LOWERING: no: |
| ; LOWERING-NEXT: call void @__llvm_ctx_profile_release_context(ptr @[[GLOB1]]) |
| ; LOWERING-NEXT: ret void |
| ; |
| %t = icmp eq i32 %a, 0 |
| br i1 %t, label %yes, label %no |
| |
| yes: |
| call void @foo(i32 1, ptr null) |
| ret void |
| no: |
| ret void |
| } |
| |
| define void @another_entrypoint_no_callees(i32 %a) { |
| ; INSTRUMENT-LABEL: define void @another_entrypoint_no_callees( |
| ; INSTRUMENT-SAME: i32 [[A:%.*]]) { |
| ; INSTRUMENT-NEXT: call void @llvm.instrprof.increment(ptr @another_entrypoint_no_callees, i64 784007058953177093, i32 2, i32 0) |
| ; INSTRUMENT-NEXT: [[T:%.*]] = icmp eq i32 [[A]], 0 |
| ; INSTRUMENT-NEXT: br i1 [[T]], label [[YES:%.*]], label [[NO:%.*]] |
| ; INSTRUMENT: yes: |
| ; INSTRUMENT-NEXT: call void @llvm.instrprof.increment(ptr @another_entrypoint_no_callees, i64 784007058953177093, i32 2, i32 1) |
| ; INSTRUMENT-NEXT: ret void |
| ; INSTRUMENT: no: |
| ; INSTRUMENT-NEXT: ret void |
| ; |
| ; LOWERING-LABEL: define void @another_entrypoint_no_callees( |
| ; LOWERING-SAME: i32 [[A:%.*]]) !guid [[META2:![0-9]+]] { |
| ; LOWERING-NEXT: [[TMP1:%.*]] = call ptr @__llvm_ctx_profile_start_context(ptr @[[GLOB2]], i64 -6371873725078000974, i32 2, i32 0) |
| ; LOWERING-NEXT: [[TMP2:%.*]] = ptrtoint ptr [[TMP1]] to i64 |
| ; LOWERING-NEXT: [[TMP3:%.*]] = and i64 [[TMP2]], -2 |
| ; LOWERING-NEXT: [[TMP4:%.*]] = inttoptr i64 [[TMP3]] to ptr |
| ; LOWERING-NEXT: [[T:%.*]] = icmp eq i32 [[A]], 0 |
| ; LOWERING-NEXT: br i1 [[T]], label [[YES:%.*]], label [[NO:%.*]] |
| ; LOWERING: yes: |
| ; LOWERING-NEXT: [[TMP5:%.*]] = getelementptr { { i64, ptr, i32, i32 }, [2 x i64], [0 x ptr] }, ptr [[TMP4]], i32 0, i32 1, i32 1 |
| ; LOWERING-NEXT: [[TMP6:%.*]] = load i64, ptr [[TMP5]], align 4 |
| ; LOWERING-NEXT: [[TMP7:%.*]] = add i64 [[TMP6]], 1 |
| ; LOWERING-NEXT: store i64 [[TMP7]], ptr [[TMP5]], align 4 |
| ; LOWERING-NEXT: call void @__llvm_ctx_profile_release_context(ptr @[[GLOB2]]) |
| ; LOWERING-NEXT: ret void |
| ; LOWERING: no: |
| ; LOWERING-NEXT: call void @__llvm_ctx_profile_release_context(ptr @[[GLOB2]]) |
| ; LOWERING-NEXT: ret void |
| ; |
| %t = icmp eq i32 %a, 0 |
| br i1 %t, label %yes, label %no |
| |
| yes: |
| ret void |
| no: |
| ret void |
| } |
| |
| define void @simple(i32 %a) { |
| ; INSTRUMENT-LABEL: define void @simple( |
| ; INSTRUMENT-SAME: i32 [[A:%.*]]) { |
| ; INSTRUMENT-NEXT: call void @llvm.instrprof.increment(ptr @simple, i64 742261418966908927, i32 1, i32 0) |
| ; INSTRUMENT-NEXT: ret void |
| ; |
| ; LOWERING-LABEL: define void @simple( |
| ; LOWERING-SAME: i32 [[A:%.*]]) !guid [[META3:![0-9]+]] { |
| ; LOWERING-NEXT: [[TMP1:%.*]] = call ptr @__llvm_ctx_profile_get_context(ptr @[[GLOB3]], ptr @simple, i64 -3006003237940970099, i32 1, i32 0) |
| ; LOWERING-NEXT: [[TMP2:%.*]] = ptrtoint ptr [[TMP1]] to i64 |
| ; LOWERING-NEXT: [[TMP3:%.*]] = and i64 [[TMP2]], -2 |
| ; LOWERING-NEXT: [[TMP4:%.*]] = inttoptr i64 [[TMP3]] to ptr |
| ; LOWERING-NEXT: call void @__llvm_ctx_profile_release_context(ptr @[[GLOB3]]) |
| ; LOWERING-NEXT: ret void |
| ; |
| ret void |
| } |
| |
| |
| define i32 @no_callsites(i32 %a) { |
| ; INSTRUMENT-LABEL: define i32 @no_callsites( |
| ; INSTRUMENT-SAME: i32 [[A:%.*]]) { |
| ; INSTRUMENT-NEXT: call void @llvm.instrprof.increment(ptr @no_callsites, i64 784007058953177093, i32 2, i32 0) |
| ; INSTRUMENT-NEXT: [[C:%.*]] = icmp eq i32 [[A]], 0 |
| ; INSTRUMENT-NEXT: br i1 [[C]], label [[YES:%.*]], label [[NO:%.*]] |
| ; INSTRUMENT: yes: |
| ; INSTRUMENT-NEXT: call void @llvm.instrprof.increment(ptr @no_callsites, i64 784007058953177093, i32 2, i32 1) |
| ; INSTRUMENT-NEXT: ret i32 1 |
| ; INSTRUMENT: no: |
| ; INSTRUMENT-NEXT: ret i32 0 |
| ; |
| ; LOWERING-LABEL: define i32 @no_callsites( |
| ; LOWERING-SAME: i32 [[A:%.*]]) !guid [[META4:![0-9]+]] { |
| ; LOWERING-NEXT: [[TMP1:%.*]] = call ptr @__llvm_ctx_profile_get_context(ptr @[[GLOB4]], ptr @no_callsites, i64 5679753335911435902, i32 2, i32 0) |
| ; LOWERING-NEXT: [[TMP2:%.*]] = ptrtoint ptr [[TMP1]] to i64 |
| ; LOWERING-NEXT: [[TMP3:%.*]] = and i64 [[TMP2]], -2 |
| ; LOWERING-NEXT: [[TMP4:%.*]] = inttoptr i64 [[TMP3]] to ptr |
| ; LOWERING-NEXT: [[C:%.*]] = icmp eq i32 [[A]], 0 |
| ; LOWERING-NEXT: br i1 [[C]], label [[YES:%.*]], label [[NO:%.*]] |
| ; LOWERING: yes: |
| ; LOWERING-NEXT: [[TMP5:%.*]] = getelementptr { { i64, ptr, i32, i32 }, [2 x i64], [0 x ptr] }, ptr [[TMP4]], i32 0, i32 1, i32 1 |
| ; LOWERING-NEXT: [[TMP6:%.*]] = load i64, ptr [[TMP5]], align 4 |
| ; LOWERING-NEXT: [[TMP7:%.*]] = add i64 [[TMP6]], 1 |
| ; LOWERING-NEXT: store i64 [[TMP7]], ptr [[TMP5]], align 4 |
| ; LOWERING-NEXT: call void @__llvm_ctx_profile_release_context(ptr @[[GLOB4]]) |
| ; LOWERING-NEXT: ret i32 1 |
| ; LOWERING: no: |
| ; LOWERING-NEXT: call void @__llvm_ctx_profile_release_context(ptr @[[GLOB4]]) |
| ; LOWERING-NEXT: ret i32 0 |
| ; |
| %c = icmp eq i32 %a, 0 |
| br i1 %c, label %yes, label %no |
| yes: |
| ret i32 1 |
| no: |
| ret i32 0 |
| } |
| |
| define void @no_counters() { |
| ; INSTRUMENT-LABEL: define void @no_counters() { |
| ; INSTRUMENT-NEXT: call void @llvm.instrprof.increment(ptr @no_counters, i64 742261418966908927, i32 1, i32 0) |
| ; INSTRUMENT-NEXT: call void @llvm.instrprof.callsite(ptr @no_counters, i64 742261418966908927, i32 1, i32 0, ptr @bar) |
| ; INSTRUMENT-NEXT: call void @bar() |
| ; INSTRUMENT-NEXT: ret void |
| ; |
| ; LOWERING-LABEL: define void @no_counters( |
| ; LOWERING-SAME: ) !guid [[META5:![0-9]+]] { |
| ; LOWERING-NEXT: [[TMP1:%.*]] = call ptr @__llvm_ctx_profile_get_context(ptr @[[GLOB5]], ptr @no_counters, i64 5458232184388660970, i32 1, i32 1) |
| ; LOWERING-NEXT: [[TMP2:%.*]] = ptrtoint ptr [[TMP1]] to i64 |
| ; LOWERING-NEXT: [[TMP3:%.*]] = and i64 [[TMP2]], 1 |
| ; LOWERING-NEXT: [[TMP4:%.*]] = call ptr @llvm.threadlocal.address.p0(ptr @__llvm_ctx_profile_expected_callee) |
| ; LOWERING-NEXT: [[TMP5:%.*]] = getelementptr ptr, ptr [[TMP4]], i64 [[TMP3]] |
| ; LOWERING-NEXT: [[TMP6:%.*]] = call ptr @llvm.threadlocal.address.p0(ptr @__llvm_ctx_profile_callsite) |
| ; LOWERING-NEXT: [[TMP7:%.*]] = getelementptr i32, ptr [[TMP6]], i64 [[TMP3]] |
| ; LOWERING-NEXT: [[TMP8:%.*]] = and i64 [[TMP2]], -2 |
| ; LOWERING-NEXT: [[TMP9:%.*]] = inttoptr i64 [[TMP8]] to ptr |
| ; LOWERING-NEXT: store volatile ptr @bar, ptr [[TMP5]], align 8 |
| ; LOWERING-NEXT: [[TMP10:%.*]] = getelementptr { { i64, ptr, i32, i32 }, [1 x i64], [1 x ptr] }, ptr [[TMP1]], i32 0, i32 2, i32 0 |
| ; LOWERING-NEXT: store volatile ptr [[TMP10]], ptr [[TMP7]], align 8 |
| ; LOWERING-NEXT: call void @bar() |
| ; LOWERING-NEXT: call void @__llvm_ctx_profile_release_context(ptr @[[GLOB5]]) |
| ; LOWERING-NEXT: ret void |
| ; |
| call void @bar() |
| ret void |
| } |
| |
| ; Ensure "calls" to inline asm don't get callsite-instrumented. |
| define void @inlineasm() { |
| ; INSTRUMENT-LABEL: define void @inlineasm() { |
| ; INSTRUMENT-NEXT: call void @llvm.instrprof.increment(ptr @inlineasm, i64 742261418966908927, i32 1, i32 0) |
| ; INSTRUMENT-NEXT: call void asm "nop", ""() |
| ; INSTRUMENT-NEXT: ret void |
| ; |
| ; LOWERING-LABEL: define void @inlineasm( |
| ; LOWERING-SAME: ) !guid [[META6:![0-9]+]] { |
| ; LOWERING-NEXT: [[TMP1:%.*]] = call ptr @__llvm_ctx_profile_get_context(ptr @[[GLOB6]], ptr @inlineasm, i64 -3771893999295659109, i32 1, i32 0) |
| ; LOWERING-NEXT: [[TMP2:%.*]] = ptrtoint ptr [[TMP1]] to i64 |
| ; LOWERING-NEXT: [[TMP3:%.*]] = and i64 [[TMP2]], -2 |
| ; LOWERING-NEXT: [[TMP4:%.*]] = inttoptr i64 [[TMP3]] to ptr |
| ; LOWERING-NEXT: call void asm "nop", ""() |
| ; LOWERING-NEXT: call void @__llvm_ctx_profile_release_context(ptr @[[GLOB6]]) |
| ; LOWERING-NEXT: ret void |
| ; |
| call void asm "nop", ""() |
| ret void |
| } |
| |
| define void @has_musttail_calls() { |
| ; INSTRUMENT-LABEL: define void @has_musttail_calls() { |
| ; INSTRUMENT-NEXT: call void @llvm.instrprof.increment(ptr @has_musttail_calls, i64 742261418966908927, i32 1, i32 0) |
| ; INSTRUMENT-NEXT: call void @llvm.instrprof.callsite(ptr @has_musttail_calls, i64 742261418966908927, i32 1, i32 0, ptr @bar) |
| ; INSTRUMENT-NEXT: musttail call void @bar() |
| ; INSTRUMENT-NEXT: ret void |
| ; |
| ; LOWERING-LABEL: define void @has_musttail_calls( |
| ; LOWERING-SAME: ) !guid [[META7:![0-9]+]] { |
| ; LOWERING-NEXT: [[TMP1:%.*]] = call ptr @__llvm_ctx_profile_get_context(ptr @[[GLOB7]], ptr @has_musttail_calls, i64 -4680624981836544329, i32 1, i32 1) |
| ; LOWERING-NEXT: [[TMP2:%.*]] = ptrtoint ptr [[TMP1]] to i64 |
| ; LOWERING-NEXT: [[TMP3:%.*]] = and i64 [[TMP2]], 1 |
| ; LOWERING-NEXT: [[TMP4:%.*]] = call ptr @llvm.threadlocal.address.p0(ptr @__llvm_ctx_profile_expected_callee) |
| ; LOWERING-NEXT: [[TMP5:%.*]] = getelementptr ptr, ptr [[TMP4]], i64 [[TMP3]] |
| ; LOWERING-NEXT: [[TMP6:%.*]] = call ptr @llvm.threadlocal.address.p0(ptr @__llvm_ctx_profile_callsite) |
| ; LOWERING-NEXT: [[TMP7:%.*]] = getelementptr i32, ptr [[TMP6]], i64 [[TMP3]] |
| ; LOWERING-NEXT: [[TMP8:%.*]] = and i64 [[TMP2]], -2 |
| ; LOWERING-NEXT: [[TMP9:%.*]] = inttoptr i64 [[TMP8]] to ptr |
| ; LOWERING-NEXT: store volatile ptr @bar, ptr [[TMP5]], align 8 |
| ; LOWERING-NEXT: [[TMP10:%.*]] = getelementptr { { i64, ptr, i32, i32 }, [1 x i64], [1 x ptr] }, ptr [[TMP1]], i32 0, i32 2, i32 0 |
| ; LOWERING-NEXT: store volatile ptr [[TMP10]], ptr [[TMP7]], align 8 |
| ; LOWERING-NEXT: musttail call void @bar() |
| ; LOWERING-NEXT: ret void |
| ; |
| musttail call void @bar() |
| ret void |
| } |
| |
| define void @does_not_return() noreturn { |
| ; INSTRUMENT-LABEL: define void @does_not_return( |
| ; INSTRUMENT-SAME: ) #[[ATTR0:[0-9]+]] { |
| ; INSTRUMENT-NEXT: call void @llvm.instrprof.increment(ptr @does_not_return, i64 742261418966908927, i32 1, i32 0) |
| ; INSTRUMENT-NEXT: unreachable |
| ; |
| ; LOWERING-LABEL: define void @does_not_return( |
| ; LOWERING-SAME: ) #[[ATTR0:[0-9]+]] !guid [[META8:![0-9]+]] { |
| ; LOWERING-NEXT: unreachable |
| ; |
| unreachable |
| } |
| |
| define void @unreachable() { |
| ; INSTRUMENT-LABEL: define void @unreachable() { |
| ; INSTRUMENT-NEXT: call void @llvm.instrprof.increment(ptr @unreachable, i64 742261418966908927, i32 1, i32 0) |
| ; INSTRUMENT-NEXT: unreachable |
| ; |
| ; LOWERING-LABEL: define void @unreachable( |
| ; LOWERING-SAME: ) !guid [[META9:![0-9]+]] { |
| ; LOWERING-NEXT: unreachable |
| ; |
| unreachable |
| } |
| |
| @foo_alias = weak_odr unnamed_addr alias void (i32, ptr), ptr @foo |
| |
| define void @call_alias(ptr %a) { |
| ; INSTRUMENT-LABEL: define void @call_alias( |
| ; INSTRUMENT-SAME: ptr [[A:%.*]]) { |
| ; INSTRUMENT-NEXT: entry: |
| ; INSTRUMENT-NEXT: call void @llvm.instrprof.increment(ptr @call_alias, i64 742261418966908927, i32 1, i32 0) |
| ; INSTRUMENT-NEXT: call void @llvm.instrprof.callsite(ptr @call_alias, i64 742261418966908927, i32 1, i32 0, ptr @foo_alias) |
| ; INSTRUMENT-NEXT: call void @foo_alias(i32 0, ptr [[A]]) |
| ; INSTRUMENT-NEXT: ret void |
| ; |
| ; LOWERING-LABEL: define void @call_alias( |
| ; LOWERING-SAME: ptr [[A:%.*]]) !guid [[META10:![0-9]+]] { |
| ; LOWERING-NEXT: entry: |
| ; LOWERING-NEXT: [[TMP0:%.*]] = call ptr @__llvm_ctx_profile_get_context(ptr @[[GLOB8]], ptr @call_alias, i64 2172368043968427688, i32 1, i32 1) |
| ; LOWERING-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[TMP0]] to i64 |
| ; LOWERING-NEXT: [[TMP2:%.*]] = and i64 [[TMP1]], 1 |
| ; LOWERING-NEXT: [[TMP3:%.*]] = call ptr @llvm.threadlocal.address.p0(ptr @__llvm_ctx_profile_expected_callee) |
| ; LOWERING-NEXT: [[TMP4:%.*]] = getelementptr ptr, ptr [[TMP3]], i64 [[TMP2]] |
| ; LOWERING-NEXT: [[TMP5:%.*]] = call ptr @llvm.threadlocal.address.p0(ptr @__llvm_ctx_profile_callsite) |
| ; LOWERING-NEXT: [[TMP6:%.*]] = getelementptr i32, ptr [[TMP5]], i64 [[TMP2]] |
| ; LOWERING-NEXT: [[TMP7:%.*]] = and i64 [[TMP1]], -2 |
| ; LOWERING-NEXT: [[TMP8:%.*]] = inttoptr i64 [[TMP7]] to ptr |
| ; LOWERING-NEXT: store volatile ptr @foo_alias, ptr [[TMP4]], align 8 |
| ; LOWERING-NEXT: [[TMP9:%.*]] = getelementptr { { i64, ptr, i32, i32 }, [1 x i64], [1 x ptr] }, ptr [[TMP0]], i32 0, i32 2, i32 0 |
| ; LOWERING-NEXT: store volatile ptr [[TMP9]], ptr [[TMP6]], align 8 |
| ; LOWERING-NEXT: call void @foo_alias(i32 0, ptr [[A]]) |
| ; LOWERING-NEXT: call void @__llvm_ctx_profile_release_context(ptr @[[GLOB8]]) |
| ; LOWERING-NEXT: ret void |
| ; |
| entry: |
| call void @foo_alias(i32 0, ptr %a) |
| ret void |
| } |
| ;. |
| ; LOWERING: attributes #[[ATTR0]] = { noreturn } |
| ; LOWERING: attributes #[[ATTR1:[0-9]+]] = { nounwind } |
| ; LOWERING: attributes #[[ATTR2:[0-9]+]] = { nocallback nofree nosync nounwind speculatable willreturn memory(none) } |
| ;. |
| ; INSTRUMENT: attributes #[[ATTR0]] = { noreturn } |
| ; INSTRUMENT: attributes #[[ATTR1:[0-9]+]] = { nounwind } |
| ;. |
| ; LOWERING: [[META0]] = !{i64 6699318081062747564} |
| ; LOWERING: [[META1]] = !{i64 4909520559318251808} |
| ; LOWERING: [[META2]] = !{i64 -6371873725078000974} |
| ; LOWERING: [[META3]] = !{i64 -3006003237940970099} |
| ; LOWERING: [[META4]] = !{i64 5679753335911435902} |
| ; LOWERING: [[META5]] = !{i64 5458232184388660970} |
| ; LOWERING: [[META6]] = !{i64 -3771893999295659109} |
| ; LOWERING: [[META7]] = !{i64 -4680624981836544329} |
| ; LOWERING: [[META8]] = !{i64 5519225910966780583} |
| ; LOWERING: [[META9]] = !{i64 -565652589829076809} |
| ; LOWERING: [[META10]] = !{i64 2172368043968427688} |
| ;. |