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