1bf70494bSFangrui Song; RUN: opt < %s -codegenprepare -S | FileCheck %s 266055230SFangrui Song; RUN: llc < %s | FileCheck --check-prefix=ASM1 %s 366055230SFangrui Song; RUN: llc < %s -function-sections | FileCheck --check-prefix=ASM2 %s 4bf70494bSFangrui Song 5bf70494bSFangrui Songtarget triple = "x86_64-pc-linux-gnu" 6bf70494bSFangrui Song 7bf70494bSFangrui Song; This tests that hot/cold functions get correct section prefix assigned 8bf70494bSFangrui Song 9bf70494bSFangrui Song; CHECK: hot_func1{{.*}}!section_prefix ![[HOT_ID:[0-9]+]] 1066055230SFangrui Song; ASM1: .section .text.hot.,"ax",@progbits 1166055230SFangrui Song; ASM2: .section .text.hot.hot_func1,"ax",@progbits 12bf70494bSFangrui Song; The entry is hot 13bf70494bSFangrui Songdefine void @hot_func1() !prof !15 { 14bf70494bSFangrui Song ret void 15bf70494bSFangrui Song} 16bf70494bSFangrui Song 17bf70494bSFangrui Song; CHECK: hot_func2{{.*}}!section_prefix ![[HOT_ID:[0-9]+]] 18bf70494bSFangrui Song; Entry is cold but inner block is hot 19bf70494bSFangrui Songdefine void @hot_func2(i32 %n) !prof !16 { 20bf70494bSFangrui Songentry: 21bf70494bSFangrui Song %n.addr = alloca i32, align 4 22bf70494bSFangrui Song %i = alloca i32, align 4 23*d9e51e75SMatt Arsenault store i32 %n, ptr %n.addr, align 4 24*d9e51e75SMatt Arsenault store i32 0, ptr %i, align 4 25bf70494bSFangrui Song br label %for.cond 26bf70494bSFangrui Song 27bf70494bSFangrui Songfor.cond: 28*d9e51e75SMatt Arsenault %0 = load i32, ptr %i, align 4 29*d9e51e75SMatt Arsenault %1 = load i32, ptr %n.addr, align 4 30bf70494bSFangrui Song %cmp = icmp slt i32 %0, %1 31bf70494bSFangrui Song br i1 %cmp, label %for.body, label %for.end, !prof !19 32bf70494bSFangrui Song 33bf70494bSFangrui Songfor.body: 34*d9e51e75SMatt Arsenault %2 = load i32, ptr %i, align 4 35bf70494bSFangrui Song %inc = add nsw i32 %2, 1 36*d9e51e75SMatt Arsenault store i32 %inc, ptr %i, align 4 37bf70494bSFangrui Song br label %for.cond 38bf70494bSFangrui Song 39bf70494bSFangrui Songfor.end: 40bf70494bSFangrui Song ret void 41bf70494bSFangrui Song} 42bf70494bSFangrui Song 43bf70494bSFangrui Song; For instrumentation based PGO, we should only look at block counts, 44bf70494bSFangrui Song; not call site VP metadata (which can exist on value profiled memcpy, 45bf70494bSFangrui Song; or possibly left behind after static analysis based devirtualization). 46bf70494bSFangrui Song; CHECK: cold_func1{{.*}}!section_prefix ![[COLD_ID:[0-9]+]] 4766055230SFangrui Song; ASM1: .section .text.unlikely.,"ax",@progbits 4866055230SFangrui Song; ASM2: .section .text.unlikely.cold_func1,"ax",@progbits 49bf70494bSFangrui Songdefine void @cold_func1() !prof !16 { 50bf70494bSFangrui Song call void @hot_func1(), !prof !17 51bf70494bSFangrui Song call void @hot_func1(), !prof !17 52bf70494bSFangrui Song ret void 53bf70494bSFangrui Song} 54bf70494bSFangrui Song 55bf70494bSFangrui Song; CHECK: cold_func2{{.*}}!section_prefix ![[COLD_ID]] 56bf70494bSFangrui Songdefine void @cold_func2() !prof !16 { 57bf70494bSFangrui Song call void @hot_func1(), !prof !17 58bf70494bSFangrui Song call void @hot_func1(), !prof !18 59bf70494bSFangrui Song call void @hot_func1(), !prof !18 60bf70494bSFangrui Song ret void 61bf70494bSFangrui Song} 62bf70494bSFangrui Song 63bf70494bSFangrui Song; CHECK: cold_func3{{.*}}!section_prefix ![[COLD_ID]] 64bf70494bSFangrui Songdefine void @cold_func3() !prof !16 { 65bf70494bSFangrui Song call void @hot_func1(), !prof !18 66bf70494bSFangrui Song ret void 67bf70494bSFangrui Song} 68bf70494bSFangrui Song 697af80299SPan, Tao; CHECK: ![[HOT_ID]] = !{!"function_section_prefix", !"hot"} 707af80299SPan, Tao; CHECK: ![[COLD_ID]] = !{!"function_section_prefix", !"unlikely"} 71bf70494bSFangrui Song!llvm.module.flags = !{!1} 72bf70494bSFangrui Song!1 = !{i32 1, !"ProfileSummary", !2} 73bf70494bSFangrui Song!2 = !{!3, !4, !5, !6, !7, !8, !9, !10} 74bf70494bSFangrui Song!3 = !{!"ProfileFormat", !"InstrProf"} 75bf70494bSFangrui Song!4 = !{!"TotalCount", i64 10000} 76bf70494bSFangrui Song!5 = !{!"MaxCount", i64 1000} 77bf70494bSFangrui Song!6 = !{!"MaxInternalCount", i64 1} 78bf70494bSFangrui Song!7 = !{!"MaxFunctionCount", i64 1000} 79bf70494bSFangrui Song!8 = !{!"NumCounts", i64 3} 80bf70494bSFangrui Song!9 = !{!"NumFunctions", i64 3} 81bf70494bSFangrui Song!10 = !{!"DetailedSummary", !11} 82bf70494bSFangrui Song!11 = !{!12, !13, !14} 83bf70494bSFangrui Song!12 = !{i32 10000, i64 100, i32 1} 84bf70494bSFangrui Song!13 = !{i32 999000, i64 100, i32 1} 85bf70494bSFangrui Song!14 = !{i32 999999, i64 1, i32 2} 86bf70494bSFangrui Song!15 = !{!"function_entry_count", i64 1000} 87bf70494bSFangrui Song!16 = !{!"function_entry_count", i64 1} 88bf70494bSFangrui Song!17 = !{!"branch_weights", i32 80} 89bf70494bSFangrui Song!18 = !{!"branch_weights", i32 1} 90bf70494bSFangrui Song!19 = !{!"branch_weights", i32 1000, i32 1} 91