1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals all --version 4 2; RUN: opt -passes=ctx-instr-gen -profile-context-root=an_entrypoint \ 3; RUN: -S < %s | FileCheck --check-prefix=INSTRUMENT %s 4; RUN: opt -passes=ctx-instr-gen,assign-guid,ctx-instr-lower -profile-context-root=an_entrypoint \ 5; RUN: -profile-context-root=another_entrypoint_no_callees \ 6; RUN: -S < %s | FileCheck --check-prefix=LOWERING %s 7 8 9declare void @bar() 10 11;. 12; LOWERING: @an_entrypoint_ctx_root = global { ptr, ptr, ptr, i8 } zeroinitializer 13; LOWERING: @another_entrypoint_no_callees_ctx_root = global { ptr, ptr, ptr, i8 } zeroinitializer 14; LOWERING: @__llvm_ctx_profile_callsite = external hidden thread_local global ptr 15; LOWERING: @__llvm_ctx_profile_expected_callee = external hidden thread_local global ptr 16;. 17define void @foo(i32 %a, ptr %fct) { 18; INSTRUMENT-LABEL: define void @foo( 19; INSTRUMENT-SAME: i32 [[A:%.*]], ptr [[FCT:%.*]]) { 20; INSTRUMENT-NEXT: call void @llvm.instrprof.increment(ptr @foo, i64 728453322856651412, i32 2, i32 0) 21; INSTRUMENT-NEXT: [[T:%.*]] = icmp eq i32 [[A]], 0 22; INSTRUMENT-NEXT: br i1 [[T]], label [[YES:%.*]], label [[NO:%.*]] 23; INSTRUMENT: yes: 24; INSTRUMENT-NEXT: call void @llvm.instrprof.increment(ptr @foo, i64 728453322856651412, i32 2, i32 1) 25; INSTRUMENT-NEXT: call void @llvm.instrprof.callsite(ptr @foo, i64 728453322856651412, i32 2, i32 0, ptr [[FCT]]) 26; INSTRUMENT-NEXT: call void [[FCT]](i32 [[A]]) 27; INSTRUMENT-NEXT: br label [[EXIT:%.*]] 28; INSTRUMENT: no: 29; INSTRUMENT-NEXT: call void @llvm.instrprof.callsite(ptr @foo, i64 728453322856651412, i32 2, i32 1, ptr @bar) 30; INSTRUMENT-NEXT: call void @bar() 31; INSTRUMENT-NEXT: br label [[EXIT]] 32; INSTRUMENT: exit: 33; INSTRUMENT-NEXT: ret void 34; 35; LOWERING-LABEL: define void @foo( 36; LOWERING-SAME: i32 [[A:%.*]], ptr [[FCT:%.*]]) !guid [[META0:![0-9]+]] { 37; LOWERING-NEXT: [[TMP1:%.*]] = call ptr @__llvm_ctx_profile_get_context(ptr @foo, i64 6699318081062747564, i32 2, i32 2) 38; LOWERING-NEXT: [[TMP2:%.*]] = ptrtoint ptr [[TMP1]] to i64 39; LOWERING-NEXT: [[TMP3:%.*]] = and i64 [[TMP2]], 1 40; LOWERING-NEXT: [[TMP4:%.*]] = call ptr @llvm.threadlocal.address.p0(ptr @__llvm_ctx_profile_expected_callee) 41; LOWERING-NEXT: [[TMP5:%.*]] = getelementptr ptr, ptr [[TMP4]], i64 [[TMP3]] 42; LOWERING-NEXT: [[TMP6:%.*]] = call ptr @llvm.threadlocal.address.p0(ptr @__llvm_ctx_profile_callsite) 43; LOWERING-NEXT: [[TMP7:%.*]] = getelementptr i32, ptr [[TMP6]], i64 [[TMP3]] 44; LOWERING-NEXT: [[TMP8:%.*]] = and i64 [[TMP2]], -2 45; LOWERING-NEXT: [[TMP9:%.*]] = inttoptr i64 [[TMP8]] to ptr 46; LOWERING-NEXT: [[T:%.*]] = icmp eq i32 [[A]], 0 47; LOWERING-NEXT: br i1 [[T]], label [[YES:%.*]], label [[NO:%.*]] 48; LOWERING: yes: 49; LOWERING-NEXT: [[TMP10:%.*]] = getelementptr { { i64, ptr, i32, i32 }, [2 x i64], [2 x ptr] }, ptr [[TMP9]], i32 0, i32 1, i32 1 50; LOWERING-NEXT: [[TMP11:%.*]] = load i64, ptr [[TMP10]], align 4 51; LOWERING-NEXT: [[TMP12:%.*]] = add i64 [[TMP11]], 1 52; LOWERING-NEXT: store i64 [[TMP12]], ptr [[TMP10]], align 4 53; LOWERING-NEXT: store volatile ptr [[FCT]], ptr [[TMP5]], align 8 54; LOWERING-NEXT: [[TMP13:%.*]] = getelementptr { { i64, ptr, i32, i32 }, [2 x i64], [2 x ptr] }, ptr [[TMP1]], i32 0, i32 2, i32 0 55; LOWERING-NEXT: store volatile ptr [[TMP13]], ptr [[TMP7]], align 8 56; LOWERING-NEXT: call void [[FCT]](i32 [[A]]) 57; LOWERING-NEXT: br label [[EXIT:%.*]] 58; LOWERING: no: 59; LOWERING-NEXT: store volatile ptr @bar, ptr [[TMP5]], align 8 60; LOWERING-NEXT: [[TMP14:%.*]] = getelementptr { { i64, ptr, i32, i32 }, [2 x i64], [2 x ptr] }, ptr [[TMP1]], i32 0, i32 2, i32 1 61; LOWERING-NEXT: store volatile ptr [[TMP14]], ptr [[TMP7]], align 8 62; LOWERING-NEXT: call void @bar() 63; LOWERING-NEXT: br label [[EXIT]] 64; LOWERING: exit: 65; LOWERING-NEXT: ret void 66; 67 %t = icmp eq i32 %a, 0 68 br i1 %t, label %yes, label %no 69yes: 70 call void %fct(i32 %a) 71 br label %exit 72no: 73 call void @bar() 74 br label %exit 75exit: 76 ret void 77} 78 79define void @an_entrypoint(i32 %a) { 80; INSTRUMENT-LABEL: define void @an_entrypoint( 81; INSTRUMENT-SAME: i32 [[A:%.*]]) { 82; INSTRUMENT-NEXT: call void @llvm.instrprof.increment(ptr @an_entrypoint, i64 784007058953177093, i32 2, i32 0) 83; INSTRUMENT-NEXT: [[T:%.*]] = icmp eq i32 [[A]], 0 84; INSTRUMENT-NEXT: br i1 [[T]], label [[YES:%.*]], label [[NO:%.*]] 85; INSTRUMENT: yes: 86; INSTRUMENT-NEXT: call void @llvm.instrprof.increment(ptr @an_entrypoint, i64 784007058953177093, i32 2, i32 1) 87; INSTRUMENT-NEXT: call void @llvm.instrprof.callsite(ptr @an_entrypoint, i64 784007058953177093, i32 1, i32 0, ptr @foo) 88; INSTRUMENT-NEXT: call void @foo(i32 1, ptr null) 89; INSTRUMENT-NEXT: ret void 90; INSTRUMENT: no: 91; INSTRUMENT-NEXT: ret void 92; 93; LOWERING-LABEL: define void @an_entrypoint( 94; LOWERING-SAME: i32 [[A:%.*]]) !guid [[META1:![0-9]+]] { 95; LOWERING-NEXT: [[TMP1:%.*]] = call ptr @__llvm_ctx_profile_start_context(ptr @an_entrypoint_ctx_root, i64 4909520559318251808, i32 2, i32 1) 96; LOWERING-NEXT: [[TMP2:%.*]] = ptrtoint ptr [[TMP1]] to i64 97; LOWERING-NEXT: [[TMP3:%.*]] = and i64 [[TMP2]], 1 98; LOWERING-NEXT: [[TMP4:%.*]] = call ptr @llvm.threadlocal.address.p0(ptr @__llvm_ctx_profile_expected_callee) 99; LOWERING-NEXT: [[TMP5:%.*]] = getelementptr ptr, ptr [[TMP4]], i64 [[TMP3]] 100; LOWERING-NEXT: [[TMP6:%.*]] = call ptr @llvm.threadlocal.address.p0(ptr @__llvm_ctx_profile_callsite) 101; LOWERING-NEXT: [[TMP7:%.*]] = getelementptr i32, ptr [[TMP6]], i64 [[TMP3]] 102; LOWERING-NEXT: [[TMP8:%.*]] = and i64 [[TMP2]], -2 103; LOWERING-NEXT: [[TMP9:%.*]] = inttoptr i64 [[TMP8]] to ptr 104; LOWERING-NEXT: [[T:%.*]] = icmp eq i32 [[A]], 0 105; LOWERING-NEXT: br i1 [[T]], label [[YES:%.*]], label [[NO:%.*]] 106; LOWERING: yes: 107; LOWERING-NEXT: [[TMP10:%.*]] = getelementptr { { i64, ptr, i32, i32 }, [2 x i64], [1 x ptr] }, ptr [[TMP9]], i32 0, i32 1, i32 1 108; LOWERING-NEXT: [[TMP11:%.*]] = load i64, ptr [[TMP10]], align 4 109; LOWERING-NEXT: [[TMP12:%.*]] = add i64 [[TMP11]], 1 110; LOWERING-NEXT: store i64 [[TMP12]], ptr [[TMP10]], align 4 111; LOWERING-NEXT: store volatile ptr @foo, ptr [[TMP5]], align 8 112; LOWERING-NEXT: [[TMP13:%.*]] = getelementptr { { i64, ptr, i32, i32 }, [2 x i64], [1 x ptr] }, ptr [[TMP1]], i32 0, i32 2, i32 0 113; LOWERING-NEXT: store volatile ptr [[TMP13]], ptr [[TMP7]], align 8 114; LOWERING-NEXT: call void @foo(i32 1, ptr null) 115; LOWERING-NEXT: call void @__llvm_ctx_profile_release_context(ptr @an_entrypoint_ctx_root) 116; LOWERING-NEXT: ret void 117; LOWERING: no: 118; LOWERING-NEXT: call void @__llvm_ctx_profile_release_context(ptr @an_entrypoint_ctx_root) 119; LOWERING-NEXT: ret void 120; 121 %t = icmp eq i32 %a, 0 122 br i1 %t, label %yes, label %no 123 124yes: 125 call void @foo(i32 1, ptr null) 126 ret void 127no: 128 ret void 129} 130 131define void @another_entrypoint_no_callees(i32 %a) { 132; INSTRUMENT-LABEL: define void @another_entrypoint_no_callees( 133; INSTRUMENT-SAME: i32 [[A:%.*]]) { 134; INSTRUMENT-NEXT: call void @llvm.instrprof.increment(ptr @another_entrypoint_no_callees, i64 784007058953177093, i32 2, i32 0) 135; INSTRUMENT-NEXT: [[T:%.*]] = icmp eq i32 [[A]], 0 136; INSTRUMENT-NEXT: br i1 [[T]], label [[YES:%.*]], label [[NO:%.*]] 137; INSTRUMENT: yes: 138; INSTRUMENT-NEXT: call void @llvm.instrprof.increment(ptr @another_entrypoint_no_callees, i64 784007058953177093, i32 2, i32 1) 139; INSTRUMENT-NEXT: ret void 140; INSTRUMENT: no: 141; INSTRUMENT-NEXT: ret void 142; 143; LOWERING-LABEL: define void @another_entrypoint_no_callees( 144; LOWERING-SAME: i32 [[A:%.*]]) !guid [[META2:![0-9]+]] { 145; LOWERING-NEXT: [[TMP1:%.*]] = call ptr @__llvm_ctx_profile_start_context(ptr @another_entrypoint_no_callees_ctx_root, i64 -6371873725078000974, i32 2, i32 0) 146; LOWERING-NEXT: [[TMP2:%.*]] = ptrtoint ptr [[TMP1]] to i64 147; LOWERING-NEXT: [[TMP3:%.*]] = and i64 [[TMP2]], -2 148; LOWERING-NEXT: [[TMP4:%.*]] = inttoptr i64 [[TMP3]] to ptr 149; LOWERING-NEXT: [[T:%.*]] = icmp eq i32 [[A]], 0 150; LOWERING-NEXT: br i1 [[T]], label [[YES:%.*]], label [[NO:%.*]] 151; LOWERING: yes: 152; LOWERING-NEXT: [[TMP5:%.*]] = getelementptr { { i64, ptr, i32, i32 }, [2 x i64], [0 x ptr] }, ptr [[TMP4]], i32 0, i32 1, i32 1 153; LOWERING-NEXT: [[TMP6:%.*]] = load i64, ptr [[TMP5]], align 4 154; LOWERING-NEXT: [[TMP7:%.*]] = add i64 [[TMP6]], 1 155; LOWERING-NEXT: store i64 [[TMP7]], ptr [[TMP5]], align 4 156; LOWERING-NEXT: call void @__llvm_ctx_profile_release_context(ptr @another_entrypoint_no_callees_ctx_root) 157; LOWERING-NEXT: ret void 158; LOWERING: no: 159; LOWERING-NEXT: call void @__llvm_ctx_profile_release_context(ptr @another_entrypoint_no_callees_ctx_root) 160; LOWERING-NEXT: ret void 161; 162 %t = icmp eq i32 %a, 0 163 br i1 %t, label %yes, label %no 164 165yes: 166 ret void 167no: 168 ret void 169} 170 171define void @simple(i32 %a) { 172; INSTRUMENT-LABEL: define void @simple( 173; INSTRUMENT-SAME: i32 [[A:%.*]]) { 174; INSTRUMENT-NEXT: call void @llvm.instrprof.increment(ptr @simple, i64 742261418966908927, i32 1, i32 0) 175; INSTRUMENT-NEXT: ret void 176; 177; LOWERING-LABEL: define void @simple( 178; LOWERING-SAME: i32 [[A:%.*]]) !guid [[META3:![0-9]+]] { 179; LOWERING-NEXT: [[TMP1:%.*]] = call ptr @__llvm_ctx_profile_get_context(ptr @simple, i64 -3006003237940970099, i32 1, i32 0) 180; LOWERING-NEXT: [[TMP2:%.*]] = ptrtoint ptr [[TMP1]] to i64 181; LOWERING-NEXT: [[TMP3:%.*]] = and i64 [[TMP2]], -2 182; LOWERING-NEXT: [[TMP4:%.*]] = inttoptr i64 [[TMP3]] to ptr 183; LOWERING-NEXT: ret void 184; 185 ret void 186} 187 188 189define i32 @no_callsites(i32 %a) { 190; INSTRUMENT-LABEL: define i32 @no_callsites( 191; INSTRUMENT-SAME: i32 [[A:%.*]]) { 192; INSTRUMENT-NEXT: call void @llvm.instrprof.increment(ptr @no_callsites, i64 784007058953177093, i32 2, i32 0) 193; INSTRUMENT-NEXT: [[C:%.*]] = icmp eq i32 [[A]], 0 194; INSTRUMENT-NEXT: br i1 [[C]], label [[YES:%.*]], label [[NO:%.*]] 195; INSTRUMENT: yes: 196; INSTRUMENT-NEXT: call void @llvm.instrprof.increment(ptr @no_callsites, i64 784007058953177093, i32 2, i32 1) 197; INSTRUMENT-NEXT: ret i32 1 198; INSTRUMENT: no: 199; INSTRUMENT-NEXT: ret i32 0 200; 201; LOWERING-LABEL: define i32 @no_callsites( 202; LOWERING-SAME: i32 [[A:%.*]]) !guid [[META4:![0-9]+]] { 203; LOWERING-NEXT: [[TMP1:%.*]] = call ptr @__llvm_ctx_profile_get_context(ptr @no_callsites, i64 5679753335911435902, i32 2, i32 0) 204; LOWERING-NEXT: [[TMP2:%.*]] = ptrtoint ptr [[TMP1]] to i64 205; LOWERING-NEXT: [[TMP3:%.*]] = and i64 [[TMP2]], -2 206; LOWERING-NEXT: [[TMP4:%.*]] = inttoptr i64 [[TMP3]] to ptr 207; LOWERING-NEXT: [[C:%.*]] = icmp eq i32 [[A]], 0 208; LOWERING-NEXT: br i1 [[C]], label [[YES:%.*]], label [[NO:%.*]] 209; LOWERING: yes: 210; LOWERING-NEXT: [[TMP5:%.*]] = getelementptr { { i64, ptr, i32, i32 }, [2 x i64], [0 x ptr] }, ptr [[TMP4]], i32 0, i32 1, i32 1 211; LOWERING-NEXT: [[TMP6:%.*]] = load i64, ptr [[TMP5]], align 4 212; LOWERING-NEXT: [[TMP7:%.*]] = add i64 [[TMP6]], 1 213; LOWERING-NEXT: store i64 [[TMP7]], ptr [[TMP5]], align 4 214; LOWERING-NEXT: ret i32 1 215; LOWERING: no: 216; LOWERING-NEXT: ret i32 0 217; 218 %c = icmp eq i32 %a, 0 219 br i1 %c, label %yes, label %no 220yes: 221 ret i32 1 222no: 223 ret i32 0 224} 225 226define void @no_counters() { 227; INSTRUMENT-LABEL: define void @no_counters() { 228; INSTRUMENT-NEXT: call void @llvm.instrprof.increment(ptr @no_counters, i64 742261418966908927, i32 1, i32 0) 229; INSTRUMENT-NEXT: call void @llvm.instrprof.callsite(ptr @no_counters, i64 742261418966908927, i32 1, i32 0, ptr @bar) 230; INSTRUMENT-NEXT: call void @bar() 231; INSTRUMENT-NEXT: ret void 232; 233; LOWERING-LABEL: define void @no_counters( 234; LOWERING-SAME: ) !guid [[META5:![0-9]+]] { 235; LOWERING-NEXT: [[TMP1:%.*]] = call ptr @__llvm_ctx_profile_get_context(ptr @no_counters, i64 5458232184388660970, i32 1, i32 1) 236; LOWERING-NEXT: [[TMP2:%.*]] = ptrtoint ptr [[TMP1]] to i64 237; LOWERING-NEXT: [[TMP3:%.*]] = and i64 [[TMP2]], 1 238; LOWERING-NEXT: [[TMP4:%.*]] = call ptr @llvm.threadlocal.address.p0(ptr @__llvm_ctx_profile_expected_callee) 239; LOWERING-NEXT: [[TMP5:%.*]] = getelementptr ptr, ptr [[TMP4]], i64 [[TMP3]] 240; LOWERING-NEXT: [[TMP6:%.*]] = call ptr @llvm.threadlocal.address.p0(ptr @__llvm_ctx_profile_callsite) 241; LOWERING-NEXT: [[TMP7:%.*]] = getelementptr i32, ptr [[TMP6]], i64 [[TMP3]] 242; LOWERING-NEXT: [[TMP8:%.*]] = and i64 [[TMP2]], -2 243; LOWERING-NEXT: [[TMP9:%.*]] = inttoptr i64 [[TMP8]] to ptr 244; LOWERING-NEXT: store volatile ptr @bar, ptr [[TMP5]], align 8 245; LOWERING-NEXT: [[TMP10:%.*]] = getelementptr { { i64, ptr, i32, i32 }, [1 x i64], [1 x ptr] }, ptr [[TMP1]], i32 0, i32 2, i32 0 246; LOWERING-NEXT: store volatile ptr [[TMP10]], ptr [[TMP7]], align 8 247; LOWERING-NEXT: call void @bar() 248; LOWERING-NEXT: ret void 249; 250 call void @bar() 251 ret void 252} 253 254; Ensure "calls" to inline asm don't get callsite-instrumented. 255define void @inlineasm() { 256; INSTRUMENT-LABEL: define void @inlineasm() { 257; INSTRUMENT-NEXT: call void @llvm.instrprof.increment(ptr @inlineasm, i64 742261418966908927, i32 1, i32 0) 258; INSTRUMENT-NEXT: call void asm "nop", ""() 259; INSTRUMENT-NEXT: ret void 260; 261; LOWERING-LABEL: define void @inlineasm( 262; LOWERING-SAME: ) !guid [[META6:![0-9]+]] { 263; LOWERING-NEXT: [[TMP1:%.*]] = call ptr @__llvm_ctx_profile_get_context(ptr @inlineasm, i64 -3771893999295659109, i32 1, i32 0) 264; LOWERING-NEXT: [[TMP2:%.*]] = ptrtoint ptr [[TMP1]] to i64 265; LOWERING-NEXT: [[TMP3:%.*]] = and i64 [[TMP2]], -2 266; LOWERING-NEXT: [[TMP4:%.*]] = inttoptr i64 [[TMP3]] to ptr 267; LOWERING-NEXT: call void asm "nop", ""() 268; LOWERING-NEXT: ret void 269; 270 call void asm "nop", ""() 271 ret void 272} 273;. 274; LOWERING: attributes #[[ATTR0:[0-9]+]] = { nounwind } 275; LOWERING: attributes #[[ATTR1:[0-9]+]] = { nocallback nofree nosync nounwind speculatable willreturn memory(none) } 276;. 277; INSTRUMENT: attributes #[[ATTR0:[0-9]+]] = { nounwind } 278;. 279; LOWERING: [[META0]] = !{i64 6699318081062747564} 280; LOWERING: [[META1]] = !{i64 4909520559318251808} 281; LOWERING: [[META2]] = !{i64 -6371873725078000974} 282; LOWERING: [[META3]] = !{i64 -3006003237940970099} 283; LOWERING: [[META4]] = !{i64 5679753335911435902} 284; LOWERING: [[META5]] = !{i64 5458232184388660970} 285; LOWERING: [[META6]] = !{i64 -3771893999295659109} 286;. 287