1; RUN: opt < %s -S -speculative-execution \ 2; RUN: -spec-exec-max-speculation-cost 4 -spec-exec-max-not-hoisted 3 \ 3; RUN: | FileCheck %s 4; RUN: opt < %s -S -passes='speculative-execution' \ 5; RUN: -spec-exec-max-speculation-cost 4 -spec-exec-max-not-hoisted 3 \ 6; RUN: | FileCheck %s 7 8target datalayout = "e-i64:64-v16:16-v32:32-n16:32:64" 9 10; Hoist in if-then pattern. 11define void @ifThen() { 12; CHECK-LABEL: @ifThen( 13; CHECK: %x = add i32 2, 3 14; CHECK: br i1 true 15 br i1 true, label %a, label %b 16; CHECK: a: 17a: 18 %x = add i32 2, 3 19; CHECK: br label 20 br label %b 21; CHECK: b: 22b: 23; CHECK: ret void 24 ret void 25} 26 27; Hoist in if-else pattern. 28define void @ifElse() { 29; CHECK-LABEL: @ifElse( 30; CHECK: %x = add i32 2, 3 31; CHECK: br i1 true 32 br i1 true, label %b, label %a 33; CHECK: a: 34a: 35 %x = add i32 2, 3 36; CHECK: br label 37 br label %b 38; CHECK: b: 39b: 40; CHECK: ret void 41 ret void 42} 43 44; Hoist in if-then-else pattern if it is equivalent to if-then. 45define void @ifElseThenAsIfThen() { 46; CHECK-LABEL: @ifElseThenAsIfThen( 47; CHECK: %x = add i32 2, 3 48; CHECK: br 49 br i1 true, label %a, label %b 50; CHECK: a: 51a: 52 %x = add i32 2, 3 53; CHECK: br label 54 br label %c 55; CHECK: b: 56b: 57 br label %c 58; CHECK: c 59c: 60 ret void 61} 62 63; Hoist in if-then-else pattern if it is equivalent to if-else. 64define void @ifElseThenAsIfElse() { 65; CHECK-LABEL: @ifElseThenAsIfElse( 66; CHECK: %x = add i32 2, 3 67; CHECK: br 68 br i1 true, label %b, label %a 69; CHECK: a: 70a: 71 %x = add i32 2, 3 72; CHECK: br label 73 br label %c 74; CHECK: b: 75b: 76 br label %c 77; CHECK: c 78c: 79 ret void 80} 81 82; Do not hoist if-then-else pattern if it is not equivalent to if-then 83; or if-else. 84define void @ifElseThen() { 85; CHECK-LABEL: @ifElseThen( 86; CHECK: br 87 br i1 true, label %a, label %b 88; CHECK: a: 89a: 90; CHECK: %x = add 91 %x = add i32 2, 3 92; CHECK: br label 93 br label %c 94; CHECK: b: 95b: 96; CHECK: %y = add 97 %y = add i32 2, 3 98 br label %c 99; CHECK: c 100c: 101 ret void 102} 103 104; Do not hoist loads and do not hoist an instruction past a definition of 105; an operand. 106define void @doNotHoistPastDef() { 107; CHECK-LABEL: @doNotHoistPastDef( 108 br i1 true, label %b, label %a 109; CHECK-NOT: load 110; CHECK-NOT: add 111; CHECK: a: 112a: 113; CHECK: %def = load 114 %def = load i32, i32* null 115; CHECK: %use = add 116 %use = add i32 %def, 0 117 br label %b 118; CHECK: b: 119b: 120 ret void 121} 122 123; Case with nothing to speculate. 124define void @nothingToSpeculate() { 125; CHECK-LABEL: @nothingToSpeculate( 126 br i1 true, label %b, label %a 127; CHECK: a: 128a: 129; CHECK: %def = load 130 %def = load i32, i32* null 131 br label %b 132; CHECK: b: 133b: 134 ret void 135} 136 137; Still hoist if an operand is defined before the block or is itself hoisted. 138define void @hoistIfNotPastDef() { 139; CHECK-LABEL: @hoistIfNotPastDef( 140; CHECK: %x = load 141 %x = load i32, i32* null 142; CHECK: %y = add i32 %x, 1 143; CHECK: %z = add i32 %y, 1 144; CHECK: br 145 br i1 true, label %b, label %a 146; CHECK: a: 147a: 148 %y = add i32 %x, 1 149 %z = add i32 %y, 1 150 br label %b 151; CHECK: b: 152b: 153 ret void 154} 155 156; Do not hoist if the speculation cost is too high. 157define void @costTooHigh() { 158; CHECK-LABEL: @costTooHigh( 159; CHECK: br 160 br i1 true, label %b, label %a 161; CHECK: a: 162a: 163; CHECK: %r1 = add 164 %r1 = add i32 1, 1 165; CHECK: %r2 = add 166 %r2 = add i32 1, 1 167; CHECK: %r3 = add 168 %r3 = add i32 1, 1 169; CHECK: %r4 = add 170 %r4 = add i32 1, 1 171; CHECK: %r5 = add 172 %r5 = add i32 1, 1 173 br label %b 174; CHECK: b: 175b: 176 ret void 177} 178 179; Do not hoist if too many instructions are left behind. 180define void @tooMuchLeftBehind() { 181; CHECK-LABEL: @tooMuchLeftBehind( 182; CHECK: br 183 br i1 true, label %b, label %a 184; CHECK: a: 185a: 186; CHECK: %x = load 187 %x = load i32, i32* null 188; CHECK: %r1 = add 189 %r1 = add i32 %x, 1 190; CHECK: %r2 = add 191 %r2 = add i32 %x, 1 192; CHECK: %r3 = add 193 %r3 = add i32 %x, 1 194 br label %b 195; CHECK: b: 196b: 197 ret void 198} 199