1; Test the static branch probability heuristics for no-return functions. 2; RUN: opt < %s -passes='print<branch-prob>' -disable-output 2>&1 | FileCheck %s 3 4declare void @abort() noreturn 5 6define i32 @test1(i32 %a, i32 %b) { 7; CHECK: Printing analysis {{.*}} for function 'test1' 8entry: 9 %cond = icmp eq i32 %a, 42 10 br i1 %cond, label %exit, label %abort 11; CHECK: edge %entry -> %exit probability is 0x7ffff800 / 0x80000000 = 100.00% [HOT edge] 12; CHECK: edge %entry -> %abort probability is 0x00000800 / 0x80000000 = 0.00% 13 14abort: 15 call void @abort() noreturn 16 unreachable 17 18exit: 19 ret i32 %b 20} 21 22define i32 @test2(i32 %a, i32 %b) { 23; CHECK: Printing analysis {{.*}} for function 'test2' 24entry: 25 switch i32 %a, label %exit [i32 1, label %case_a 26 i32 2, label %case_b 27 i32 3, label %case_c 28 i32 4, label %case_d] 29; CHECK: edge %entry -> %exit probability is 0x7fffe000 / 0x80000000 = 100.00% [HOT edge] 30; CHECK: edge %entry -> %case_a probability is 0x00000800 / 0x80000000 = 0.00% 31; CHECK: edge %entry -> %case_b probability is 0x00000800 / 0x80000000 = 0.00% 32; CHECK: edge %entry -> %case_c probability is 0x00000800 / 0x80000000 = 0.00% 33; CHECK: edge %entry -> %case_d probability is 0x00000800 / 0x80000000 = 0.00% 34 35case_a: 36 br label %case_b 37 38case_b: 39 br label %case_c 40 41case_c: 42 br label %case_d 43 44case_d: 45 call void @abort() noreturn 46 unreachable 47 48exit: 49 ret i32 %b 50} 51 52define i32 @test3(i32 %a, i32 %b) { 53; CHECK: Printing analysis {{.*}} for function 'test3' 54; Make sure we unify across multiple conditional branches. 55entry: 56 %cond1 = icmp eq i32 %a, 42 57 br i1 %cond1, label %exit, label %dom 58; CHECK: edge %entry -> %exit probability is 0x7ffff800 / 0x80000000 = 100.00% [HOT edge] 59; CHECK: edge %entry -> %dom probability is 0x00000800 / 0x80000000 = 0.00% 60 61dom: 62 %cond2 = icmp ult i32 %a, 42 63 br i1 %cond2, label %idom1, label %idom2 64; CHECK: edge %dom -> %idom1 probability is 0x40000000 / 0x80000000 = 50.00% 65; CHECK: edge %dom -> %idom2 probability is 0x40000000 / 0x80000000 = 50.00% 66 67idom1: 68 br label %abort 69 70idom2: 71 br label %abort 72 73abort: 74 call void @abort() noreturn 75 unreachable 76 77exit: 78 ret i32 %b 79} 80 81define i32 @test4(i32 %a, i32 %b) { 82; CHECK: Printing analysis {{.*}} for function 'test4' 83; Make sure we handle loops post-dominated by unreachables. 84entry: 85 %cond1 = icmp eq i32 %a, 42 86 br i1 %cond1, label %header, label %exit 87; CHECK: edge %entry -> %header probability is 0x00000800 / 0x80000000 = 0.00% 88; CHECK: edge %entry -> %exit probability is 0x7ffff800 / 0x80000000 = 100.00% [HOT edge] 89 90header: 91 br label %body 92 93body: 94 %cond2 = icmp eq i32 %a, 42 95 br i1 %cond2, label %header, label %abort 96; CHECK: edge %body -> %header probability is 0x7ffff800 / 0x80000000 = 100.00% [HOT edge] 97; CHECK: edge %body -> %abort probability is 0x00000800 / 0x80000000 = 0.00% 98abort: 99 call void @abort() noreturn 100 unreachable 101 102exit: 103 ret i32 %b 104} 105 106@_ZTIi = external global ptr 107 108; CHECK-LABEL: throwSmallException 109; CHECK-NOT: invoke i32 @smallFunction 110define i32 @throwSmallException(i32 %idx, i32 %limit) #0 personality ptr @__gxx_personality_v0 { 111entry: 112 %cmp = icmp sge i32 %idx, %limit 113 br i1 %cmp, label %if.then, label %if.end 114; CHECK: edge %entry -> %if.then probability is 0x00000800 / 0x80000000 = 0.00% 115; CHECK: edge %entry -> %if.end probability is 0x7ffff800 / 0x80000000 = 100.00% [HOT edge] 116 117if.then: ; preds = %entry 118 %exception = call ptr @__cxa_allocate_exception(i64 1) #0 119 invoke i32 @smallFunction(i32 %idx) 120 to label %invoke.cont unwind label %lpad 121; CHECK: edge %if.then -> %invoke.cont probability is 0x40000000 / 0x80000000 = 50.00% 122; CHECK: edge %if.then -> %lpad probability is 0x40000000 / 0x80000000 = 50.00% 123 124invoke.cont: ; preds = %if.then 125 call void @__cxa_throw(ptr %exception, ptr @_ZTIi, ptr null) #1 126 unreachable 127 128lpad: ; preds = %if.then 129 %ll = landingpad { ptr, i32 } 130 cleanup 131 ret i32 %idx 132 133if.end: ; preds = %entry 134 ret i32 %idx 135} 136 137@a = global i32 4 138define i32 @smallFunction(i32 %a) { 139entry: 140 %r = load volatile i32, ptr @a 141 ret i32 %r 142} 143 144attributes #0 = { nounwind } 145attributes #1 = { noreturn } 146 147declare ptr @__cxa_allocate_exception(i64) 148declare i32 @__gxx_personality_v0(...) 149declare void @__cxa_throw(ptr, ptr, ptr) 150