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