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 8 target datalayout = "e-i64:64-v16:16-v32:32-n16:32:64" 9 10 ; Hoist in if-then pattern. 11 define 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: 17 a: 18 %x = add i32 2, 3 19 ; CHECK: br label 20 br label %b 21 ; CHECK: b: 22 b: 23 ; CHECK: ret void 24 ret void 25 } 26 27 ; Hoist in if-else pattern. 28 define 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: 34 a: 35 %x = add i32 2, 3 36 ; CHECK: br label 37 br label %b 38 ; CHECK: b: 39 b: 40 ; CHECK: ret void 41 ret void 42 } 43 44 ; Hoist in if-then-else pattern if it is equivalent to if-then. 45 define 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: 51 a: 52 %x = add i32 2, 3 53 ; CHECK: br label 54 br label %c 55 ; CHECK: b: 56 b: 57 br label %c 58 ; CHECK: c 59 c: 60 ret void 61 } 62 63 ; Hoist in if-then-else pattern if it is equivalent to if-else. 64 define 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: 70 a: 71 %x = add i32 2, 3 72 ; CHECK: br label 73 br label %c 74 ; CHECK: b: 75 b: 76 br label %c 77 ; CHECK: c 78 c: 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. 84 define void @ifElseThen() { 85 ; CHECK-LABEL: @ifElseThen( 86 ; CHECK: br 87 br i1 true, label %a, label %b 88 ; CHECK: a: 89 a: 90 ; CHECK: %x = add 91 %x = add i32 2, 3 92 ; CHECK: br label 93 br label %c 94 ; CHECK: b: 95 b: 96 ; CHECK: %y = add 97 %y = add i32 2, 3 98 br label %c 99 ; CHECK: c 100 c: 101 ret void 102 } 103 104 ; Do not hoist loads and do not hoist an instruction past a definition of 105 ; an operand. 106 define 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: 112 a: 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: 119 b: 120 ret void 121 } 122 123 ; Case with nothing to speculate. 124 define void @nothingToSpeculate() { 125 ; CHECK-LABEL: @nothingToSpeculate( 126 br i1 true, label %b, label %a 127 ; CHECK: a: 128 a: 129 ; CHECK: %def = load 130 %def = load i32, i32* null 131 br label %b 132 ; CHECK: b: 133 b: 134 ret void 135 } 136 137 ; Still hoist if an operand is defined before the block or is itself hoisted. 138 define 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: 147 a: 148 %y = add i32 %x, 1 149 %z = add i32 %y, 1 150 br label %b 151 ; CHECK: b: 152 b: 153 ret void 154 } 155 156 ; Do not hoist if the speculation cost is too high. 157 define void @costTooHigh() { 158 ; CHECK-LABEL: @costTooHigh( 159 ; CHECK: br 160 br i1 true, label %b, label %a 161 ; CHECK: a: 162 a: 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: 175 b: 176 ret void 177 } 178 179 ; Do not hoist if too many instructions are left behind. 180 define void @tooMuchLeftBehind() { 181 ; CHECK-LABEL: @tooMuchLeftBehind( 182 ; CHECK: br 183 br i1 true, label %b, label %a 184 ; CHECK: a: 185 a: 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: 196 b: 197 ret void 198 } 199