253 lines · plain
1; The llc commands override two options2; - 'aarch64-enable-atomic-cfg-tidy' to false to turn off simplifycfg pass,3; which can simplify away switch instructions before isel lowers switch instructions.4; - 'aarch64-min-jump-table-entries' so 'switch' needs fewer cases to generate5; a jump table.6 7; The static-data-splitter pass doesn't run.8; RUN: llc -mtriple=aarch64-unknown-linux-gnu -function-sections=true \9; RUN: -aarch64-enable-atomic-cfg-tidy=false -aarch64-min-jump-table-entries=2 \10; RUN: -unique-section-names=true %s -o - 2>&1 | FileCheck %s --check-prefixes=DEFAULT11 12; DEFAULT: .section .rodata.hot.foo,"a",@progbits13; DEFAULT: .LJTI0_0:14; DEFAULT: .LJTI0_1:15; DEFAULT: .LJTI0_2:16; DEFAULT: .LJTI0_3:17; DEFAULT: .section .rodata.func_without_profile,"a",@progbits18; DEFAULT: .LJTI1_0:19; DEFAULT: .section .rodata.bar_prefix.bar,"a",@progbits20; DEFAULT: .LJTI2_021 22; Test that section names are uniqufied by numbers but not function names with23; {-function-sections, -unique-section-names=false}. Specifically, @foo jump24; tables are emitted in two sections, one with unique ID 2 and the other with25; unique ID 3.26; RUN: llc -mtriple=aarch64-unknown-linux-gnu -partition-static-data-sections \27; RUN: -function-sections -unique-section-names=false \28; RUN: -aarch64-enable-atomic-cfg-tidy=false -aarch64-min-jump-table-entries=2 \29; RUN: %s -o - 2>&1 | FileCheck %s --check-prefixes=NUM,JT30 31; Section names will optionally have `.<func>` with {-function-sections, -unique-section-names}.32; RUN: llc -mtriple=aarch64-unknown-linux-gnu -partition-static-data-sections \33; RUN: -function-sections -unique-section-names \34; RUN: -aarch64-enable-atomic-cfg-tidy=false -aarch64-min-jump-table-entries=2 \35; RUN: %s -o - 2>&1 | FileCheck %s --check-prefixes=FUNC,JT36 37; Test that section names won't have `.<func>` with -function-sections=false.38; RUN: llc -mtriple=aarch64-unknown-linux-gnu -partition-static-data-sections \39; RUN: -function-sections=false \40; RUN: -aarch64-enable-atomic-cfg-tidy=false -aarch64-min-jump-table-entries=2 \41; RUN: %s -o - 2>&1 | FileCheck %s --check-prefixes=FUNCLESS,JT42 43target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"44target triple = "aarch64-unknown-linux-gnu"45 46@str.9 = private constant [7 x i8] c".str.9\00"47@str.10 = private constant [8 x i8] c".str.10\00"48@str.11 = private constant [8 x i8] c".str.11\00"49 50@case2 = private constant [7 x i8] c"case 2\00"51@case1 = private constant [7 x i8] c"case 1\00"52@default = private constant [8 x i8] c"default\00"53@jt3 = private constant [4 x i8] c"jt3\00"54 55; In function @foo, the 2 switch instructions to jt0.* and jt1.* are placed in56; hot-prefixed sections, and the 2 switch instructions to jt2.* and jt3.* are57; placed in cold-prefixed sections.58; NUM: .section .rodata.hot.,"a",@progbits,unique,259; FUNC: .section .rodata.hot.foo,"a",@progbits60; FUNCLESS: .section .rodata.hot.,"a",@progbits61; JT: .LJTI0_0:62; JT: .LJTI0_2:63; NUM: .section .rodata.unlikely.,"a",@progbits,unique,364; FUNC: .section .rodata.unlikely.foo65; FUNCLESS: .section .rodata.unlikely.,"a",@progbits66; JT: .LJTI0_1:67; JT: .LJTI0_3:68 69; jt0 and jt2 are hot. jt1 and jt3 are cold.70define i32 @foo(i32 %num) !prof !13 {71entry:72 %mod3 = sdiv i32 %num, 373 switch i32 %mod3, label %jt0.default [74 i32 1, label %jt0.bb175 i32 2, label %jt0.bb276 ], !prof !1477 78jt0.bb1:79 call i32 @puts(ptr @case1)80 br label %jt0.epilog81 82jt0.bb2:83 call i32 @puts(ptr @case2)84 br label %jt0.epilog85 86jt0.default:87 call i32 @puts(ptr @default)88 br label %jt0.epilog89 90jt0.epilog:91 %zero = icmp eq i32 %num, 092 br i1 %zero, label %hot, label %cold, !prof !1793 94hot:95 %c2 = call i32 @transform(i32 %num)96 switch i32 %c2, label %jt2.default [97 i32 1, label %jt2.bb198 i32 2, label %jt2.bb299 ], !prof !14100 101jt2.bb1:102 call i32 @puts(ptr @case1)103 br label %jt1.epilog104 105jt2.bb2:106 call i32 @puts(ptr @case2)107 br label %jt1.epilog108 109jt2.default:110 call i32 @puts(ptr @default)111 br label %jt2.epilog112 113jt2.epilog:114 %c2cmp = icmp ne i32 %c2, 0115 br i1 %c2cmp, label %return, label %jt3.prologue, !prof !18116 117cold:118 %c1 = call i32 @compute(i32 %num)119 switch i32 %c1, label %jt1.default [120 i32 1, label %jt1.bb1121 i32 2, label %jt1.bb2122 ], !prof !14123 124jt1.bb1:125 call i32 @puts(ptr @case1)126 br label %jt1.epilog127 128jt1.bb2:129 call i32 @puts(ptr @case2)130 br label %jt1.epilog131 132jt1.default:133 call i32 @puts(ptr @default)134 br label %jt1.epilog135 136jt1.epilog:137 br label %return138 139jt3.prologue:140 %c3 = call i32 @cleanup(i32 %num)141 switch i32 %c3, label %jt3.default [142 i32 1, label %jt3.bb1143 i32 2, label %jt3.bb2144 ], !prof !14145 146jt3.bb1:147 call i32 @puts(ptr @case1)148 br label %jt3.epilog149 150jt3.bb2:151 call i32 @puts(ptr @case2)152 br label %jt3.epilog153 154jt3.default:155 call i32 @puts(ptr @default)156 br label %jt3.epilog157 158jt3.epilog:159 call i32 @puts(ptr @jt3)160 br label %return161 162return:163 ret i32 %mod3164}165 166; @func_without_profile doesn't have profiles, so its jumptable doesn't have167; hotness-based prefix.168; NUM: .section .rodata,"a",@progbits,unique,5169; FUNC: .section .rodata.func_without_profile,"a",@progbits170; FUNCLESS: .section .rodata,"a",@progbits171; JT: .LJTI1_0:172define void @func_without_profile(i32 %num) {173entry:174 switch i32 %num, label %sw.default [175 i32 1, label %sw.bb176 i32 2, label %sw.bb1177 ]178 179sw.bb:180 call i32 @puts(ptr @str.10)181 br label %sw.epilog182 183sw.bb1: 184 call i32 @puts(ptr @str.9)185 br label %sw.epilog186 187sw.default:188 call i32 @puts(ptr @str.11)189 br label %sw.epilog190 191sw.epilog: 192 ret void193}194 195; @bar doesn't have profile information and it has a section prefix.196; Tests that its jump tables are placed in sections with function prefixes.197; NUM: .section .rodata.bar_prefix.,"a",@progbits,unique,7198; FUNC: .section .rodata.bar_prefix.bar199; FUNCLESS: .section .rodata.bar_prefix.,"a"200; JT: .LJTI2_0201define void @bar(i32 %num) !section_prefix !20 {202entry:203 switch i32 %num, label %sw.default [204 i32 1, label %sw.bb205 i32 2, label %sw.bb1206 ]207 208sw.bb:209 call i32 @puts(ptr @str.10)210 br label %sw.epilog211 212sw.bb1:213 call i32 @puts(ptr @str.9)214 br label %sw.epilog215 216sw.default:217 call i32 @puts(ptr @str.11)218 br label %sw.epilog219 220sw.epilog:221 ret void222}223 224declare i32 @puts(ptr)225declare i32 @printf(ptr, ...)226declare i32 @compute(i32)227declare i32 @transform(i32)228declare i32 @cleanup(i32)229 230!llvm.module.flags = !{!0}231 232!0 = !{i32 1, !"ProfileSummary", !1}233!1 = !{!2, !3, !4, !5, !6, !7, !8, !9}234!2 = !{!"ProfileFormat", !"InstrProf"}235!3 = !{!"TotalCount", i64 230002}236!4 = !{!"MaxCount", i64 100000}237!5 = !{!"MaxInternalCount", i64 50000}238!6 = !{!"MaxFunctionCount", i64 100000}239!7 = !{!"NumCounts", i64 14}240!8 = !{!"NumFunctions", i64 3}241!9 = !{!"DetailedSummary", !10}242!10 = !{!11, !12}243!11 = !{i32 990000, i64 10000, i32 7}244!12 = !{i32 999999, i64 1, i32 9}245!13 = !{!"function_entry_count", i64 100000}246!14 = !{!"branch_weights", i32 60000, i32 20000, i32 20000}247!15 = !{!"function_entry_count", i64 1}248!16 = !{!"branch_weights", i32 1, i32 0, i32 0, i32 0, i32 0, i32 0}249!17 = !{!"branch_weights", i32 99999, i32 1}250!18 = !{!"branch_weights", i32 99998, i32 1}251!19 = !{!"branch_weights", i32 97000, i32 1000, i32 1000, i32 1000}252!20 = !{!"function_section_prefix", !"bar_prefix"}253