1; RUN: opt -S -passes=hotcoldsplit -hotcoldsplit-threshold=0 < %s | FileCheck %s 2 3; Source: 4; 5; extern void sideeffect(int); 6; extern void __attribute__((cold)) sink(); 7; void foo(int cond) { 8; if (cond) { //< Start outlining here. 9; while (cond > 10) { 10; --cond; 11; sideeffect(0); 12; } 13; sink(); 14; } 15; sideeffect(1); 16; } 17 18target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" 19target triple = "x86_64-apple-macosx10.14.0" 20 21; CHECK-LABEL: define {{.*}}@foo( 22; CHECK: br i1 {{.*}}, label %if.end, label %codeRepl 23; CHECK-LABEL: codeRepl: 24; CHECK-NEXT: call void @foo.cold.1 25; CHECK-LABEL: if.end: 26; CHECK: call void @sideeffect(i32 1) 27define void @foo(i32 %cond) { 28entry: 29 %tobool = icmp eq i32 %cond, 0 30 br i1 %tobool, label %if.end, label %while.cond.preheader 31 32while.cond.preheader: ; preds = %entry 33 %cmp3 = icmp sgt i32 %cond, 10 34 br i1 %cmp3, label %while.body.preheader, label %while.end 35 36while.body.preheader: ; preds = %while.cond.preheader 37 br label %while.body 38 39while.body: ; preds = %while.body.preheader, %while.body 40 %cond.addr.04 = phi i32 [ %dec, %while.body ], [ %cond, %while.body.preheader ] 41 %dec = add nsw i32 %cond.addr.04, -1 42 tail call void @sideeffect(i32 0) #3 43 %cmp = icmp sgt i32 %dec, 10 44 br i1 %cmp, label %while.body, label %while.end.loopexit 45 46while.end.loopexit: ; preds = %while.body 47 br label %while.end 48 49while.end: ; preds = %while.end.loopexit, %while.cond.preheader 50 tail call void (...) @sink() 51 ret void 52 53if.end: ; preds = %entry 54 tail call void @sideeffect(i32 1) 55 ret void 56} 57 58; This is the same as @foo, but the while loop comes after the sink block. 59; CHECK-LABEL: define {{.*}}@while_loop_after_sink( 60; CHECK: br i1 {{.*}}, label %if.end, label %codeRepl 61; CHECK-LABEL: codeRepl: 62; CHECK-NEXT: call void @while_loop_after_sink.cold.1 63; CHECK-LABEL: if.end: 64; CHECK: call void @sideeffect(i32 1) 65define void @while_loop_after_sink(i32 %cond) { 66entry: 67 %tobool = icmp eq i32 %cond, 0 68 br i1 %tobool, label %if.end, label %sink 69 70sink: 71 tail call void (...) @sink() 72 br label %while.cond.preheader 73 74while.cond.preheader: 75 %cmp3 = icmp sgt i32 %cond, 10 76 br i1 %cmp3, label %while.body.preheader, label %while.end 77 78while.body.preheader: ; preds = %while.cond.preheader 79 br label %while.body 80 81while.body: ; preds = %while.body.preheader, %while.body 82 %cond.addr.04 = phi i32 [ %dec, %while.body ], [ %cond, %while.body.preheader ] 83 %dec = add nsw i32 %cond.addr.04, -1 84 tail call void @sideeffect(i32 0) #3 85 %cmp = icmp sgt i32 %dec, 10 86 br i1 %cmp, label %while.body, label %while.end.loopexit 87 88while.end.loopexit: ; preds = %while.body 89 br label %while.end 90 91while.end: ; preds = %while.end.loopexit, %while.cond.preheader 92 ret void 93 94if.end: ; preds = %entry 95 tail call void @sideeffect(i32 1) 96 ret void 97} 98 99; CHECK-LABEL: define {{.*}}@foo.cold.1 100; CHECK: phi i32 101; CHECK-NEXT: add nsw i32 102; CHECK-NEXT: call {{.*}}@sideeffect 103; CHECK-NEXT: icmp 104; CHECK-NEXT: br 105 106; CHECK-LABEL: define {{.*}}@while_loop_after_sink.cold.1 107; CHECK: call {{.*}}@sink 108; CHECK: phi i32 109; CHECK-NEXT: add nsw i32 110; CHECK-NEXT: call {{.*}}@sideeffect 111; CHECK-NEXT: icmp 112; CHECK-NEXT: br 113 114declare void @sideeffect(i32) 115 116declare void @sink(...) cold 117