1 ; RUN: opt -S -early-cse < %s | FileCheck %s 2 ; RUN: opt < %s -S -basicaa -early-cse-memssa | FileCheck %s 3 4 declare void @llvm.experimental.guard(i1,...) 5 6 declare void @llvm.assume(i1) 7 8 define i32 @test0(i32* %ptr, i1 %cond) { 9 ; We can do store to load forwarding over a guard, since it does not 10 ; clobber memory 11 12 ; CHECK-LABEL: @test0( 13 ; CHECK-NEXT: store i32 40, i32* %ptr 14 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 %cond) [ "deopt"() ] 15 ; CHECK-NEXT: ret i32 40 16 17 store i32 40, i32* %ptr 18 call void(i1,...) @llvm.experimental.guard(i1 %cond) [ "deopt"() ] 19 %rval = load i32, i32* %ptr 20 ret i32 %rval 21 } 22 23 define i32 @test1(i32* %val, i1 %cond) { 24 ; We can CSE loads over a guard, since it does not clobber memory 25 26 ; CHECK-LABEL: @test1( 27 ; CHECK-NEXT: %val0 = load i32, i32* %val 28 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 %cond) [ "deopt"() ] 29 ; CHECK-NEXT: ret i32 0 30 31 %val0 = load i32, i32* %val 32 call void(i1,...) @llvm.experimental.guard(i1 %cond) [ "deopt"() ] 33 %val1 = load i32, i32* %val 34 %rval = sub i32 %val0, %val1 35 ret i32 %rval 36 } 37 38 define i32 @test2() { 39 ; Guards on "true" get removed 40 41 ; CHECK-LABEL: @test2( 42 ; CHECK-NEXT: ret i32 0 43 call void(i1, ...) @llvm.experimental.guard(i1 true) [ "deopt"() ] 44 ret i32 0 45 } 46 47 define i32 @test3(i32 %val) { 48 ; After a guard has executed the condition it was guarding is known to 49 ; be true. 50 51 ; CHECK-LABEL: @test3( 52 ; CHECK-NEXT: %cond0 = icmp slt i32 %val, 40 53 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 %cond0) [ "deopt"() ] 54 ; CHECK-NEXT: ret i32 -1 55 56 %cond0 = icmp slt i32 %val, 40 57 call void(i1,...) @llvm.experimental.guard(i1 %cond0) [ "deopt"() ] 58 %cond1 = icmp slt i32 %val, 40 59 call void(i1,...) @llvm.experimental.guard(i1 %cond1) [ "deopt"() ] 60 61 %cond2 = icmp slt i32 %val, 40 62 %rval = sext i1 %cond2 to i32 63 ret i32 %rval 64 } 65 66 define i32 @test3.unhandled(i32 %val) { 67 ; After a guard has executed the condition it was guarding is known to 68 ; be true. 69 70 ; CHECK-LABEL: @test3.unhandled( 71 ; CHECK-NEXT: %cond0 = icmp slt i32 %val, 40 72 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 %cond0) [ "deopt"() ] 73 ; CHECK-NEXT: %cond1 = icmp sge i32 %val, 40 74 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 %cond1) [ "deopt"() ] 75 ; CHECK-NEXT: ret i32 0 76 77 ; Demonstrates a case we do not yet handle (it is legal to fold %cond2 78 ; to false) 79 %cond0 = icmp slt i32 %val, 40 80 call void(i1,...) @llvm.experimental.guard(i1 %cond0) [ "deopt"() ] 81 %cond1 = icmp sge i32 %val, 40 82 call void(i1,...) @llvm.experimental.guard(i1 %cond1) [ "deopt"() ] 83 ret i32 0 84 } 85 86 define i32 @test4(i32 %val, i1 %c) { 87 ; Same as test3, but with some control flow involved. 88 89 ; CHECK-LABEL: @test4( 90 ; CHECK: entry: 91 ; CHECK-NEXT: %cond0 = icmp slt i32 %val, 40 92 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 %cond0 93 ; CHECK-NEXT: br label %bb0 94 95 ; CHECK: bb0: 96 ; CHECK-NEXT: %cond2 = icmp ult i32 %val, 200 97 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 %cond2 98 ; CHECK-NEXT: br i1 %c, label %left, label %right 99 100 ; CHECK: left: 101 ; CHECK-NEXT: ret i32 0 102 103 ; CHECK: right: 104 ; CHECK-NEXT: ret i32 20 105 106 entry: 107 %cond0 = icmp slt i32 %val, 40 108 call void(i1,...) @llvm.experimental.guard(i1 %cond0) [ "deopt"() ] 109 %cond1 = icmp slt i32 %val, 40 110 call void(i1,...) @llvm.experimental.guard(i1 %cond1) [ "deopt"() ] 111 br label %bb0 112 113 bb0: 114 %cond2 = icmp ult i32 %val, 200 115 call void(i1,...) @llvm.experimental.guard(i1 %cond2) [ "deopt"() ] 116 br i1 %c, label %left, label %right 117 118 left: 119 %cond3 = icmp ult i32 %val, 200 120 call void(i1,...) @llvm.experimental.guard(i1 %cond3) [ "deopt"() ] 121 ret i32 0 122 123 right: 124 ret i32 20 125 } 126 127 define i32 @test5(i32 %val, i1 %c) { 128 ; Same as test4, but the %left block has mutliple predecessors. 129 130 ; CHECK-LABEL: @test5( 131 132 ; CHECK: entry: 133 ; CHECK-NEXT: %cond0 = icmp slt i32 %val, 40 134 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 %cond0 135 ; CHECK-NEXT: br label %bb0 136 137 ; CHECK: bb0: 138 ; CHECK-NEXT: %cond2 = icmp ult i32 %val, 200 139 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 %cond2 140 ; CHECK-NEXT: br i1 %c, label %left, label %right 141 142 ; CHECK: left: 143 ; CHECK-NEXT: br label %right 144 145 ; CHECK: right: 146 ; CHECK-NEXT: br label %left 147 148 entry: 149 %cond0 = icmp slt i32 %val, 40 150 call void(i1,...) @llvm.experimental.guard(i1 %cond0) [ "deopt"() ] 151 %cond1 = icmp slt i32 %val, 40 152 call void(i1,...) @llvm.experimental.guard(i1 %cond1) [ "deopt"() ] 153 br label %bb0 154 155 bb0: 156 %cond2 = icmp ult i32 %val, 200 157 call void(i1,...) @llvm.experimental.guard(i1 %cond2) [ "deopt"() ] 158 br i1 %c, label %left, label %right 159 160 left: 161 %cond3 = icmp ult i32 %val, 200 162 call void(i1,...) @llvm.experimental.guard(i1 %cond3) [ "deopt"() ] 163 br label %right 164 165 right: 166 br label %left 167 } 168 169 define void @test6(i1 %c, i32* %ptr) { 170 ; Check that we do not DSE over calls to @llvm.experimental.guard. 171 ; Guard intrinsics do _read_ memory, so th call to guard below needs 172 ; to see the store of 500 to %ptr 173 174 ; CHECK-LABEL: @test6( 175 ; CHECK-NEXT: store i32 500, i32* %ptr 176 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 %c) [ "deopt"() ] 177 ; CHECK-NEXT: store i32 600, i32* %ptr 178 179 180 store i32 500, i32* %ptr 181 call void(i1,...) @llvm.experimental.guard(i1 %c) [ "deopt"() ] 182 store i32 600, i32* %ptr 183 ret void 184 } 185 186 define void @test07(i32 %a, i32 %b) { 187 ; Check that we are able to remove the guards on the same condition even if the 188 ; condition is not being recalculated. 189 190 ; CHECK-LABEL: @test07( 191 ; CHECK-NEXT: %cmp = icmp eq i32 %a, %b 192 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ] 193 ; CHECK-NEXT: ret void 194 195 %cmp = icmp eq i32 %a, %b 196 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ] 197 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ] 198 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ] 199 ret void 200 } 201 202 define void @test08(i32 %a, i32 %b, i32* %ptr) { 203 ; Check that we deal correctly with stores when removing guards in the same 204 ; block in case when the condition is not recalculated. 205 206 ; CHECK-LABEL: @test08( 207 ; CHECK-NEXT: %cmp = icmp eq i32 %a, %b 208 ; CHECK-NEXT: store i32 100, i32* %ptr 209 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ] 210 ; CHECK-NEXT: store i32 400, i32* %ptr 211 ; CHECK-NEXT: ret void 212 213 %cmp = icmp eq i32 %a, %b 214 store i32 100, i32* %ptr 215 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ] 216 store i32 200, i32* %ptr 217 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ] 218 store i32 300, i32* %ptr 219 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ] 220 store i32 400, i32* %ptr 221 ret void 222 } 223 224 define void @test09(i32 %a, i32 %b, i1 %c, i32* %ptr) { 225 ; Similar to test08, but with more control flow. 226 ; TODO: Can we get rid of the store in the end of entry given that it is 227 ; post-dominated by other stores? 228 229 ; CHECK-LABEL: @test09( 230 ; CHECK: entry: 231 ; CHECK-NEXT: %cmp = icmp eq i32 %a, %b 232 ; CHECK-NEXT: store i32 100, i32* %ptr 233 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ] 234 ; CHECK-NEXT: store i32 400, i32* %ptr 235 ; CHECK-NEXT: br i1 %c, label %if.true, label %if.false 236 ; CHECK: if.true: 237 ; CHECK-NEXT: store i32 500, i32* %ptr 238 ; CHECK-NEXT: br label %merge 239 ; CHECK: if.false: 240 ; CHECK-NEXT: store i32 600, i32* %ptr 241 ; CHECK-NEXT: br label %merge 242 ; CHECK: merge: 243 ; CHECK-NEXT: ret void 244 245 entry: 246 %cmp = icmp eq i32 %a, %b 247 store i32 100, i32* %ptr 248 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ] 249 store i32 200, i32* %ptr 250 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ] 251 store i32 300, i32* %ptr 252 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ] 253 store i32 400, i32* %ptr 254 br i1 %c, label %if.true, label %if.false 255 256 if.true: 257 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ] 258 store i32 500, i32* %ptr 259 br label %merge 260 261 if.false: 262 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ] 263 store i32 600, i32* %ptr 264 br label %merge 265 266 merge: 267 ret void 268 } 269 270 define void @test10(i32 %a, i32 %b, i1 %c, i32* %ptr) { 271 ; Make sure that non-dominating guards do not cause other guards removal. 272 273 ; CHECK-LABEL: @test10( 274 ; CHECK: entry: 275 ; CHECK-NEXT: %cmp = icmp eq i32 %a, %b 276 ; CHECK-NEXT: br i1 %c, label %if.true, label %if.false 277 ; CHECK: if.true: 278 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ] 279 ; CHECK-NEXT: store i32 100, i32* %ptr 280 ; CHECK-NEXT: br label %merge 281 ; CHECK: if.false: 282 ; CHECK-NEXT: store i32 200, i32* %ptr 283 ; CHECK-NEXT: br label %merge 284 ; CHECK: merge: 285 ; CHECK-NEXT: store i32 300, i32* %ptr 286 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ] 287 ; CHECK-NEXT: store i32 400, i32* %ptr 288 ; CHECK-NEXT: ret void 289 290 entry: 291 %cmp = icmp eq i32 %a, %b 292 br i1 %c, label %if.true, label %if.false 293 294 if.true: 295 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ] 296 store i32 100, i32* %ptr 297 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ] 298 br label %merge 299 300 if.false: 301 store i32 200, i32* %ptr 302 br label %merge 303 304 merge: 305 store i32 300, i32* %ptr 306 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ] 307 store i32 400, i32* %ptr 308 ret void 309 } 310 311 define void @test11(i32 %a, i32 %b, i32* %ptr) { 312 ; Make sure that branching condition is applied to guards. 313 314 ; CHECK-LABEL: @test11( 315 ; CHECK: entry: 316 ; CHECK-NEXT: %cmp = icmp eq i32 %a, %b 317 ; CHECK-NEXT: br i1 %cmp, label %if.true, label %if.false 318 ; CHECK: if.true: 319 ; CHECK-NEXT: br label %merge 320 ; CHECK: if.false: 321 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 false) [ "deopt"() ] 322 ; CHECK-NEXT: br label %merge 323 ; CHECK: merge: 324 ; CHECK-NEXT: ret void 325 326 entry: 327 %cmp = icmp eq i32 %a, %b 328 br i1 %cmp, label %if.true, label %if.false 329 330 if.true: 331 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ] 332 br label %merge 333 334 if.false: 335 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ] 336 br label %merge 337 338 merge: 339 ret void 340 } 341 342 define void @test12(i32 %a, i32 %b) { 343 ; Check that the assume marks its condition as being true (and thus allows to 344 ; eliminate the dominated guards). 345 346 ; CHECK-LABEL: @test12( 347 ; CHECK-NEXT: %cmp = icmp eq i32 %a, %b 348 ; CHECK-NEXT: call void @llvm.assume(i1 %cmp) 349 ; CHECK-NEXT: ret void 350 351 %cmp = icmp eq i32 %a, %b 352 call void @llvm.assume(i1 %cmp) 353 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ] 354 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ] 355 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ] 356 ret void 357 } 358 359 define void @test13(i32 %a, i32 %b, i32* %ptr) { 360 ; Check that we deal correctly with stores when removing guards due to assume. 361 362 ; CHECK-LABEL: @test13( 363 ; CHECK-NEXT: %cmp = icmp eq i32 %a, %b 364 ; CHECK-NEXT: call void @llvm.assume(i1 %cmp) 365 ; CHECK-NEXT: store i32 400, i32* %ptr 366 ; CHECK-NEXT: ret void 367 368 %cmp = icmp eq i32 %a, %b 369 call void @llvm.assume(i1 %cmp) 370 store i32 100, i32* %ptr 371 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ] 372 store i32 200, i32* %ptr 373 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ] 374 store i32 300, i32* %ptr 375 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ] 376 store i32 400, i32* %ptr 377 ret void 378 } 379 380 define void @test14(i32 %a, i32 %b, i1 %c, i32* %ptr) { 381 ; Similar to test13, but with more control flow. 382 ; TODO: Can we get rid of the store in the end of entry given that it is 383 ; post-dominated by other stores? 384 385 ; CHECK-LABEL: @test14( 386 ; CHECK: entry: 387 ; CHECK-NEXT: %cmp = icmp eq i32 %a, %b 388 ; CHECK-NEXT: call void @llvm.assume(i1 %cmp) 389 ; CHECK-NEXT: store i32 400, i32* %ptr 390 ; CHECK-NEXT: br i1 %c, label %if.true, label %if.false 391 ; CHECK: if.true: 392 ; CHECK-NEXT: store i32 500, i32* %ptr 393 ; CHECK-NEXT: br label %merge 394 ; CHECK: if.false: 395 ; CHECK-NEXT: store i32 600, i32* %ptr 396 ; CHECK-NEXT: br label %merge 397 ; CHECK: merge: 398 ; CHECK-NEXT: ret void 399 400 entry: 401 %cmp = icmp eq i32 %a, %b 402 call void @llvm.assume(i1 %cmp) 403 store i32 100, i32* %ptr 404 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ] 405 store i32 200, i32* %ptr 406 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ] 407 store i32 300, i32* %ptr 408 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ] 409 store i32 400, i32* %ptr 410 br i1 %c, label %if.true, label %if.false 411 412 if.true: 413 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ] 414 store i32 500, i32* %ptr 415 br label %merge 416 417 if.false: 418 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ] 419 store i32 600, i32* %ptr 420 br label %merge 421 422 merge: 423 ret void 424 } 425 426 define void @test15(i32 %a, i32 %b, i1 %c, i32* %ptr) { 427 ; Make sure that non-dominating assumes do not cause guards removal. 428 429 ; CHECK-LABEL: @test15( 430 ; CHECK: entry: 431 ; CHECK-NEXT: %cmp = icmp eq i32 %a, %b 432 ; CHECK-NEXT: br i1 %c, label %if.true, label %if.false 433 ; CHECK: if.true: 434 ; CHECK-NEXT: call void @llvm.assume(i1 %cmp) 435 ; CHECK-NEXT: store i32 100, i32* %ptr 436 ; CHECK-NEXT: br label %merge 437 ; CHECK: if.false: 438 ; CHECK-NEXT: store i32 200, i32* %ptr 439 ; CHECK-NEXT: br label %merge 440 ; CHECK: merge: 441 ; CHECK-NEXT: store i32 300, i32* %ptr 442 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ] 443 ; CHECK-NEXT: store i32 400, i32* %ptr 444 ; CHECK-NEXT: ret void 445 446 entry: 447 %cmp = icmp eq i32 %a, %b 448 br i1 %c, label %if.true, label %if.false 449 450 if.true: 451 call void @llvm.assume(i1 %cmp) 452 store i32 100, i32* %ptr 453 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ] 454 br label %merge 455 456 if.false: 457 store i32 200, i32* %ptr 458 br label %merge 459 460 merge: 461 store i32 300, i32* %ptr 462 call void (i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ] 463 store i32 400, i32* %ptr 464 ret void 465 } 466 467 define void @test16(i32 %a, i32 %b) { 468 ; Check that we don't bother to do anything with assumes even if we know the 469 ; condition being true. 470 471 ; CHECK-LABEL: @test16( 472 ; CHECK-NEXT: %cmp = icmp eq i32 %a, %b 473 ; CHECK-NEXT: call void @llvm.assume(i1 %cmp) 474 ; CHECK-NEXT: call void @llvm.assume(i1 %cmp) 475 ; CHECK-NEXT: ret void 476 477 %cmp = icmp eq i32 %a, %b 478 call void @llvm.assume(i1 %cmp) 479 call void @llvm.assume(i1 %cmp) 480 ret void 481 } 482 483 define void @test17(i32 %a, i32 %b, i1 %c, i32* %ptr) { 484 ; Check that we don't bother to do anything with assumes even if we know the 485 ; condition being true or false (includes come control flow). 486 487 ; CHECK-LABEL: @test17( 488 ; CHECK: entry: 489 ; CHECK-NEXT: %cmp = icmp eq i32 %a, %b 490 ; CHECK-NEXT: br i1 %c, label %if.true, label %if.false 491 ; CHECK: if.true: 492 ; CHECK-NEXT: call void @llvm.assume(i1 %cmp) 493 ; CHECK-NEXT: br label %merge 494 ; CHECK: if.false: 495 ; CHECK-NEXT: call void @llvm.assume(i1 %cmp) 496 ; CHECK-NEXT: br label %merge 497 ; CHECK: merge: 498 ; CHECK-NEXT: ret void 499 500 entry: 501 %cmp = icmp eq i32 %a, %b 502 br i1 %c, label %if.true, label %if.false 503 504 if.true: 505 call void @llvm.assume(i1 %cmp) 506 br label %merge 507 508 if.false: 509 call void @llvm.assume(i1 %cmp) 510 br label %merge 511 512 merge: 513 ret void 514 } 515 516 define void @test18(i1 %c) { 517 ; Check that we don't bother to do anything with assumes even if we know the 518 ; condition being true and not being an instruction. 519 520 ; CHECK-LABEL: @test18( 521 ; CHECK-NEXT: call void @llvm.assume(i1 %c) 522 ; CHECK-NEXT: call void @llvm.assume(i1 %c) 523 ; CHECK-NEXT: ret void 524 525 call void @llvm.assume(i1 %c) 526 call void @llvm.assume(i1 %c) 527 ret void 528 } 529