1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals 2; RUN: opt < %s -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S | FileCheck %s 3 4define void @test1(i1 %C, ptr %BP) { 5; CHECK-LABEL: @test1( 6; CHECK-NEXT: entry: 7; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[C:%.*]], true 8; CHECK-NEXT: call void @llvm.assume(i1 [[TMP0]]) 9; CHECK-NEXT: ret void 10; 11entry: 12 br i1 %C, label %T, label %F 13T: 14 store i1 %C, ptr %BP 15 unreachable 16F: 17 ret void 18} 19 20define void @test2() personality ptr @__gxx_personality_v0 { 21; CHECK-LABEL: @test2( 22; CHECK-NEXT: entry: 23; CHECK-NEXT: call void @test2() #[[ATTR4:[0-9]+]] 24; CHECK-NEXT: ret void 25; 26entry: 27 invoke void @test2( ) 28 to label %N unwind label %U 29U: 30 %res = landingpad { ptr } 31 cleanup 32 unreachable 33N: 34 ret void 35} 36 37declare i32 @__gxx_personality_v0(...) 38 39define i32 @test3(i32 %v) { 40; CHECK-LABEL: @test3( 41; CHECK-NEXT: entry: 42; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[V:%.*]], 2 43; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[COND]], i32 2, i32 1 44; CHECK-NEXT: ret i32 [[SPEC_SELECT]] 45; 46entry: 47 switch i32 %v, label %default [ 48 i32 1, label %U 49 i32 2, label %T 50 ] 51default: 52 ret i32 1 53U: 54 unreachable 55T: 56 ret i32 2 57} 58 59 60;; We can either convert the following control-flow to a select or remove the 61;; unreachable control flow because of the undef store of null. Make sure we do 62;; the latter. 63 64define void @test5(i1 %cond, ptr %ptr) { 65; CHECK-LABEL: @test5( 66; CHECK-NEXT: entry: 67; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[COND:%.*]], true 68; CHECK-NEXT: call void @llvm.assume(i1 [[TMP0]]) 69; CHECK-NEXT: store i8 2, ptr [[PTR:%.*]], align 8 70; CHECK-NEXT: ret void 71; 72entry: 73 br i1 %cond, label %bb1, label %bb3 74 75bb3: 76 br label %bb2 77 78bb1: 79 br label %bb2 80 81bb2: 82 %ptr.2 = phi ptr [ %ptr, %bb3 ], [ null, %bb1 ] 83 store i8 2, ptr %ptr.2, align 8 84 ret void 85} 86 87declare void @llvm.assume(i1) 88declare i1 @llvm.type.test(ptr, metadata) nounwind readnone 89 90;; Same as the above test but make sure the unreachable control flow is still 91;; removed in the presence of a type test / assume sequence. 92 93define void @test5_type_test_assume(i1 %cond, ptr %ptr, ptr %vtable) { 94; CHECK-LABEL: @test5_type_test_assume( 95; CHECK-NEXT: entry: 96; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[COND:%.*]], true 97; CHECK-NEXT: call void @llvm.assume(i1 [[TMP0]]) 98; CHECK-NEXT: [[P:%.*]] = call i1 @llvm.type.test(ptr [[VTABLE:%.*]], metadata !"foo") 99; CHECK-NEXT: tail call void @llvm.assume(i1 [[P]]) 100; CHECK-NEXT: store i8 2, ptr [[PTR:%.*]], align 8 101; CHECK-NEXT: ret void 102; 103entry: 104 br i1 %cond, label %bb1, label %bb3 105 106bb3: 107 br label %bb2 108 109bb1: 110 br label %bb2 111 112bb2: 113 %ptr.2 = phi ptr [ %ptr, %bb3 ], [ null, %bb1 ] 114 %p = call i1 @llvm.type.test(ptr %vtable, metadata !"foo") 115 tail call void @llvm.assume(i1 %p) 116 store i8 2, ptr %ptr.2, align 8 117 ret void 118} 119 120define void @test5_no_null_opt(i1 %cond, ptr %ptr) #0 { 121; CHECK-LABEL: @test5_no_null_opt( 122; CHECK-NEXT: entry: 123; CHECK-NEXT: [[DOTPTR:%.*]] = select i1 [[COND:%.*]], ptr null, ptr [[PTR:%.*]] 124; CHECK-NEXT: store i8 2, ptr [[DOTPTR]], align 8 125; CHECK-NEXT: ret void 126; 127entry: 128 br i1 %cond, label %bb1, label %bb3 129 130bb3: 131 br label %bb2 132 133bb1: 134 br label %bb2 135 136bb2: 137 %ptr.2 = phi ptr [ %ptr, %bb3 ], [ null, %bb1 ] 138 store i8 2, ptr %ptr.2, align 8 139 ret void 140} 141 142define void @test6(i1 %cond, ptr %ptr) { 143; CHECK-LABEL: @test6( 144; CHECK-NEXT: entry: 145; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[COND:%.*]], true 146; CHECK-NEXT: call void @llvm.assume(i1 [[TMP0]]) 147; CHECK-NEXT: store i8 2, ptr [[PTR:%.*]], align 8 148; CHECK-NEXT: ret void 149; 150entry: 151 br i1 %cond, label %bb1, label %bb2 152 153bb1: 154 br label %bb2 155 156bb2: 157 %ptr.2 = phi ptr [ %ptr, %entry ], [ null, %bb1 ] 158 store i8 2, ptr %ptr.2, align 8 159 ret void 160} 161 162define void @test6_no_null_opt(i1 %cond, ptr %ptr) #0 { 163; CHECK-LABEL: @test6_no_null_opt( 164; CHECK-NEXT: entry: 165; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[COND:%.*]], ptr null, ptr [[PTR:%.*]] 166; CHECK-NEXT: store i8 2, ptr [[SPEC_SELECT]], align 8 167; CHECK-NEXT: ret void 168; 169entry: 170 br i1 %cond, label %bb1, label %bb2 171 172bb1: 173 br label %bb2 174 175bb2: 176 %ptr.2 = phi ptr [ %ptr, %entry ], [ null, %bb1 ] 177 store i8 2, ptr %ptr.2, align 8 178 ret void 179} 180 181 182define i32 @test7(i1 %X) { 183; CHECK-LABEL: @test7( 184; CHECK-NEXT: entry: 185; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[X:%.*]], true 186; CHECK-NEXT: call void @llvm.assume(i1 [[TMP0]]) 187; CHECK-NEXT: ret i32 0 188; 189entry: 190 br i1 %X, label %if, label %else 191 192if: 193 call void undef() 194 br label %else 195 196else: 197 %phi = phi i32 [ 0, %entry ], [ 1, %if ] 198 ret i32 %phi 199} 200 201define void @test8(i1 %X, ptr %Y) { 202; CHECK-LABEL: @test8( 203; CHECK-NEXT: entry: 204; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[X:%.*]], true 205; CHECK-NEXT: call void @llvm.assume(i1 [[TMP0]]) 206; CHECK-NEXT: call void [[Y:%.*]]() 207; CHECK-NEXT: ret void 208; 209entry: 210 br i1 %X, label %if, label %else 211 212if: 213 br label %else 214 215else: 216 %phi = phi ptr [ %Y, %entry ], [ null, %if ] 217 call void %phi() 218 ret void 219} 220 221define void @test8_no_null_opt(i1 %X, ptr %Y) #0 { 222; CHECK-LABEL: @test8_no_null_opt( 223; CHECK-NEXT: entry: 224; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[X:%.*]], ptr null, ptr [[Y:%.*]] 225; CHECK-NEXT: call void [[SPEC_SELECT]]() 226; CHECK-NEXT: ret void 227; 228entry: 229 br i1 %X, label %if, label %else 230 231if: 232 br label %else 233 234else: 235 %phi = phi ptr [ %Y, %entry ], [ null, %if ] 236 call void %phi() 237 ret void 238} 239 240declare ptr @fn_nonnull_noundef_arg(ptr nonnull noundef %p) 241declare ptr @fn_nonnull_deref_arg(ptr nonnull dereferenceable(4) %p) 242declare ptr @fn_nonnull_deref_or_null_arg(ptr nonnull dereferenceable_or_null(4) %p) 243declare ptr @fn_nonnull_arg(ptr nonnull %p) 244declare ptr @fn_noundef_arg(ptr noundef %p) 245declare ptr @fn_ptr_arg(ptr) 246declare ptr @fn_ptr_arg_nounwind_willreturn(ptr) nounwind willreturn 247 248define void @test9(i1 %X, ptr %Y) { 249; CHECK-LABEL: @test9( 250; CHECK-NEXT: entry: 251; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[X:%.*]], true 252; CHECK-NEXT: call void @llvm.assume(i1 [[TMP0]]) 253; CHECK-NEXT: [[TMP1:%.*]] = call ptr @fn_nonnull_noundef_arg(ptr [[Y:%.*]]) 254; CHECK-NEXT: ret void 255; 256entry: 257 br i1 %X, label %if, label %else 258 259if: 260 br label %else 261 262else: 263 %phi = phi ptr [ %Y, %entry ], [ null, %if ] 264 call ptr @fn_nonnull_noundef_arg(ptr %phi) 265 ret void 266} 267 268; Optimizing this code should produce assume. 269define void @test9_deref(i1 %X, ptr %Y) { 270; CHECK-LABEL: @test9_deref( 271; CHECK-NEXT: entry: 272; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[X:%.*]], true 273; CHECK-NEXT: call void @llvm.assume(i1 [[TMP0]]) 274; CHECK-NEXT: [[TMP1:%.*]] = call ptr @fn_nonnull_deref_arg(ptr [[Y:%.*]]) 275; CHECK-NEXT: ret void 276; 277entry: 278 br i1 %X, label %if, label %else 279 280if: 281 br label %else 282 283else: 284 %phi = phi ptr [ %Y, %entry ], [ null, %if ] 285 call ptr @fn_nonnull_deref_arg(ptr %phi) 286 ret void 287} 288 289; Optimizing this code should produce assume. 290define void @test9_deref_or_null(i1 %X, ptr %Y) { 291; CHECK-LABEL: @test9_deref_or_null( 292; CHECK-NEXT: entry: 293; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[X:%.*]], true 294; CHECK-NEXT: call void @llvm.assume(i1 [[TMP0]]) 295; CHECK-NEXT: [[TMP1:%.*]] = call ptr @fn_nonnull_deref_or_null_arg(ptr [[Y:%.*]]) 296; CHECK-NEXT: ret void 297; 298entry: 299 br i1 %X, label %if, label %else 300 301if: 302 br label %else 303 304else: 305 %phi = phi ptr [ %Y, %entry ], [ null, %if ] 306 call ptr @fn_nonnull_deref_or_null_arg(ptr %phi) 307 ret void 308} 309 310define void @test9_undef(i1 %X, ptr %Y) { 311; CHECK-LABEL: @test9_undef( 312; CHECK-NEXT: entry: 313; CHECK-NEXT: [[TMP0:%.*]] = call ptr @fn_noundef_arg(ptr [[Y:%.*]]) 314; CHECK-NEXT: ret void 315; 316entry: 317 br i1 %X, label %if, label %else 318 319if: 320 br label %else 321 322else: 323 %phi = phi ptr [ %Y, %entry ], [ undef, %if ] 324 call ptr @fn_noundef_arg(ptr %phi) 325 ret void 326} 327 328define void @test9_undef_null_defined(i1 %X, ptr %Y) #0 { 329; CHECK-LABEL: @test9_undef_null_defined( 330; CHECK-NEXT: entry: 331; CHECK-NEXT: [[TMP0:%.*]] = call ptr @fn_noundef_arg(ptr [[Y:%.*]]) 332; CHECK-NEXT: ret void 333; 334entry: 335 br i1 %X, label %if, label %else 336 337if: 338 br label %else 339 340else: 341 %phi = phi ptr [ %Y, %entry ], [ undef, %if ] 342 call ptr @fn_noundef_arg(ptr %phi) 343 ret void 344} 345 346define void @test9_null_callsite(i1 %X, ptr %Y) { 347; CHECK-LABEL: @test9_null_callsite( 348; CHECK-NEXT: entry: 349; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[X:%.*]], true 350; CHECK-NEXT: call void @llvm.assume(i1 [[TMP0]]) 351; CHECK-NEXT: [[TMP1:%.*]] = call ptr @fn_nonnull_arg(ptr noundef nonnull [[Y:%.*]]) 352; CHECK-NEXT: ret void 353; 354entry: 355 br i1 %X, label %if, label %else 356 357if: 358 br label %else 359 360else: 361 %phi = phi ptr [ %Y, %entry ], [ null, %if ] 362 call ptr @fn_nonnull_arg(ptr nonnull noundef %phi) 363 ret void 364} 365 366define void @test9_gep_mismatch(i1 %X, ptr %Y, ptr %P) { 367; CHECK-LABEL: @test9_gep_mismatch( 368; CHECK-NEXT: entry: 369; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[X:%.*]], ptr null, ptr [[Y:%.*]] 370; CHECK-NEXT: [[TMP0:%.*]] = call ptr @fn_nonnull_noundef_arg(ptr [[P:%.*]]) 371; CHECK-NEXT: ret void 372; 373entry: 374 br i1 %X, label %if, label %else 375 376if: 377 br label %else 378 379else: 380 %phi = phi ptr [ %Y, %entry ], [ null, %if ] 381 call ptr @fn_nonnull_noundef_arg(ptr %P) 382 ret void 383} 384 385define void @test9_gep_zero(i1 %X, ptr %Y) { 386; CHECK-LABEL: @test9_gep_zero( 387; CHECK-NEXT: entry: 388; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[X:%.*]], true 389; CHECK-NEXT: call void @llvm.assume(i1 [[TMP0]]) 390; CHECK-NEXT: [[TMP1:%.*]] = call ptr @fn_nonnull_noundef_arg(ptr [[Y:%.*]]) 391; CHECK-NEXT: ret void 392; 393entry: 394 br i1 %X, label %if, label %else 395 396if: 397 br label %else 398 399else: 400 %phi = phi ptr [ %Y, %entry ], [ null, %if ] 401 call ptr @fn_nonnull_noundef_arg(ptr %phi) 402 ret void 403} 404 405define void @test9_gep_bitcast(i1 %X, ptr %Y) { 406; CHECK-LABEL: @test9_gep_bitcast( 407; CHECK-NEXT: entry: 408; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[X:%.*]], true 409; CHECK-NEXT: call void @llvm.assume(i1 [[TMP0]]) 410; CHECK-NEXT: [[TMP1:%.*]] = call ptr @fn_nonnull_noundef_arg(ptr [[Y:%.*]]) 411; CHECK-NEXT: ret void 412; 413entry: 414 br i1 %X, label %if, label %else 415 416if: 417 br label %else 418 419else: 420 %phi = phi ptr [ %Y, %entry ], [ null, %if ] 421 call ptr @fn_nonnull_noundef_arg(ptr %phi) 422 ret void 423} 424 425define void @test9_gep_nonzero(i1 %X, ptr %Y) { 426; CHECK-LABEL: @test9_gep_nonzero( 427; CHECK-NEXT: entry: 428; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[X:%.*]], ptr null, ptr [[Y:%.*]] 429; CHECK-NEXT: [[GEP:%.*]] = getelementptr i8, ptr [[SPEC_SELECT]], i64 12 430; CHECK-NEXT: [[TMP0:%.*]] = call ptr @fn_nonnull_noundef_arg(ptr [[GEP]]) 431; CHECK-NEXT: ret void 432; 433entry: 434 br i1 %X, label %if, label %else 435 436if: 437 br label %else 438 439else: 440 %phi = phi ptr [ %Y, %entry ], [ null, %if ] 441 %gep = getelementptr i8, ptr %phi, i64 12 442 call ptr @fn_nonnull_noundef_arg(ptr %gep) 443 ret void 444} 445 446define void @test9_gep_inbounds_nonzero(i1 %X, ptr %Y) { 447; CHECK-LABEL: @test9_gep_inbounds_nonzero( 448; CHECK-NEXT: entry: 449; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[X:%.*]], true 450; CHECK-NEXT: call void @llvm.assume(i1 [[TMP0]]) 451; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i8, ptr [[Y:%.*]], i64 12 452; CHECK-NEXT: [[TMP1:%.*]] = call ptr @fn_nonnull_noundef_arg(ptr [[GEP]]) 453; CHECK-NEXT: ret void 454; 455entry: 456 br i1 %X, label %if, label %else 457 458if: 459 br label %else 460 461else: 462 %phi = phi ptr [ %Y, %entry ], [ null, %if ] 463 %gep = getelementptr inbounds i8, ptr %phi, i64 12 464 call ptr @fn_nonnull_noundef_arg(ptr %gep) 465 ret void 466} 467 468define void @test9_gep_inbounds_nonzero_null_defined(i1 %X, ptr %Y) #0 { 469; CHECK-LABEL: @test9_gep_inbounds_nonzero_null_defined( 470; CHECK-NEXT: entry: 471; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[X:%.*]], ptr null, ptr [[Y:%.*]] 472; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i8, ptr [[SPEC_SELECT]], i64 12 473; CHECK-NEXT: [[TMP0:%.*]] = call ptr @fn_nonnull_noundef_arg(ptr [[GEP]]) 474; CHECK-NEXT: ret void 475; 476entry: 477 br i1 %X, label %if, label %else 478 479if: 480 br label %else 481 482else: 483 %phi = phi ptr [ %Y, %entry ], [ null, %if ] 484 %gep = getelementptr inbounds i8, ptr %phi, i64 12 485 call ptr @fn_nonnull_noundef_arg(ptr %gep) 486 ret void 487} 488 489define void @test9_gep_inbounds_unknown_null(i1 %X, ptr %Y, i64 %I) { 490; CHECK-LABEL: @test9_gep_inbounds_unknown_null( 491; CHECK-NEXT: entry: 492; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[X:%.*]], true 493; CHECK-NEXT: call void @llvm.assume(i1 [[TMP0]]) 494; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i8, ptr [[Y:%.*]], i64 [[I:%.*]] 495; CHECK-NEXT: [[TMP1:%.*]] = call ptr @fn_nonnull_noundef_arg(ptr [[GEP]]) 496; CHECK-NEXT: ret void 497; 498entry: 499 br i1 %X, label %if, label %else 500 501if: 502 br label %else 503 504else: 505 %phi = phi ptr [ %Y, %entry ], [ null, %if ] 506 %gep = getelementptr inbounds i8, ptr %phi, i64 %I 507 call ptr @fn_nonnull_noundef_arg(ptr %gep) 508 ret void 509} 510 511define void @test9_gep_inbounds_unknown_null_defined(i1 %X, ptr %Y, i64 %I) #0 { 512; CHECK-LABEL: @test9_gep_inbounds_unknown_null_defined( 513; CHECK-NEXT: entry: 514; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[X:%.*]], ptr null, ptr [[Y:%.*]] 515; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i8, ptr [[SPEC_SELECT]], i64 [[I:%.*]] 516; CHECK-NEXT: [[TMP0:%.*]] = call ptr @fn_nonnull_noundef_arg(ptr [[GEP]]) 517; CHECK-NEXT: ret void 518; 519entry: 520 br i1 %X, label %if, label %else 521 522if: 523 br label %else 524 525else: 526 %phi = phi ptr [ %Y, %entry ], [ null, %if ] 527 %gep = getelementptr inbounds i8, ptr %phi, i64 %I 528 call ptr @fn_nonnull_noundef_arg(ptr %gep) 529 ret void 530} 531 532define void @test9_gep_inbounds_unknown_null_call_noundef(i1 %X, ptr %Y, i64 %I) { 533; CHECK-LABEL: @test9_gep_inbounds_unknown_null_call_noundef( 534; CHECK-NEXT: entry: 535; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[X:%.*]], ptr null, ptr [[Y:%.*]] 536; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i8, ptr [[SPEC_SELECT]], i64 [[I:%.*]] 537; CHECK-NEXT: [[TMP0:%.*]] = call ptr @fn_noundef_arg(ptr [[GEP]]) 538; CHECK-NEXT: ret void 539; 540entry: 541 br i1 %X, label %if, label %else 542 543if: 544 br label %else 545 546else: 547 %phi = phi ptr [ %Y, %entry ], [ null, %if ] 548 %gep = getelementptr inbounds i8, ptr %phi, i64 %I 549 call ptr @fn_noundef_arg(ptr %gep) 550 ret void 551} 552 553define void @test9_gep_unknown_null(i1 %X, ptr %Y, i64 %I) { 554; CHECK-LABEL: @test9_gep_unknown_null( 555; CHECK-NEXT: entry: 556; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[X:%.*]], ptr null, ptr [[Y:%.*]] 557; CHECK-NEXT: [[GEP:%.*]] = getelementptr i8, ptr [[SPEC_SELECT]], i64 [[I:%.*]] 558; CHECK-NEXT: [[TMP0:%.*]] = call ptr @fn_nonnull_noundef_arg(ptr [[GEP]]) 559; CHECK-NEXT: ret void 560; 561entry: 562 br i1 %X, label %if, label %else 563 564if: 565 br label %else 566 567else: 568 %phi = phi ptr [ %Y, %entry ], [ null, %if ] 569 %gep = getelementptr i8, ptr %phi, i64 %I 570 call ptr @fn_nonnull_noundef_arg(ptr %gep) 571 ret void 572} 573 574define void @test9_gep_unknown_undef(i1 %X, ptr %Y, i64 %I) { 575; CHECK-LABEL: @test9_gep_unknown_undef( 576; CHECK-NEXT: entry: 577; CHECK-NEXT: [[GEP:%.*]] = getelementptr i8, ptr [[Y:%.*]], i64 [[I:%.*]] 578; CHECK-NEXT: [[TMP0:%.*]] = call ptr @fn_noundef_arg(ptr [[GEP]]) 579; CHECK-NEXT: ret void 580; 581entry: 582 br i1 %X, label %if, label %else 583 584if: 585 br label %else 586 587else: 588 %phi = phi ptr [ %Y, %entry ], [ undef, %if ] 589 %gep = getelementptr i8, ptr %phi, i64 %I 590 call ptr @fn_noundef_arg(ptr %gep) 591 ret void 592} 593 594define void @test9_missing_noundef(i1 %X, ptr %Y) { 595; CHECK-LABEL: @test9_missing_noundef( 596; CHECK-NEXT: entry: 597; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[X:%.*]], ptr null, ptr [[Y:%.*]] 598; CHECK-NEXT: [[TMP0:%.*]] = call ptr @fn_nonnull_arg(ptr [[SPEC_SELECT]]) 599; CHECK-NEXT: ret void 600; 601entry: 602 br i1 %X, label %if, label %else 603 604if: 605 br label %else 606 607else: 608 %phi = phi ptr [ %Y, %entry ], [ null, %if ] 609 call ptr @fn_nonnull_arg(ptr %phi) 610 ret void 611} 612 613define void @test9_null_defined(i1 %X, ptr %Y) #0 { 614; CHECK-LABEL: @test9_null_defined( 615; CHECK-NEXT: entry: 616; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[X:%.*]], ptr null, ptr [[Y:%.*]] 617; CHECK-NEXT: [[TMP0:%.*]] = call ptr @fn_nonnull_noundef_arg(ptr [[SPEC_SELECT]]) 618; CHECK-NEXT: ret void 619; 620entry: 621 br i1 %X, label %if, label %else 622 623if: 624 br label %else 625 626else: 627 %phi = phi ptr [ %Y, %entry ], [ null, %if ] 628 call ptr @fn_nonnull_noundef_arg(ptr %phi) 629 ret void 630} 631 632define i32 @test_assume_false(i32 %cond) { 633; CHECK-LABEL: @test_assume_false( 634; CHECK-NEXT: entry: 635; CHECK-NEXT: switch i32 [[COND:%.*]], label [[DEFAULT:%.*]] [ 636; CHECK-NEXT: i32 0, label [[EXIT:%.*]] 637; CHECK-NEXT: i32 1, label [[CASE1:%.*]] 638; CHECK-NEXT: i32 2, label [[CASE2:%.*]] 639; CHECK-NEXT: ] 640; CHECK: case1: 641; CHECK-NEXT: br label [[EXIT]] 642; CHECK: case2: 643; CHECK-NEXT: br label [[EXIT]] 644; CHECK: default: 645; CHECK-NEXT: unreachable 646; CHECK: exit: 647; CHECK-NEXT: [[RES:%.*]] = phi i32 [ 2, [[CASE1]] ], [ 3, [[CASE2]] ], [ 1, [[ENTRY:%.*]] ] 648; CHECK-NEXT: call void @llvm.assume(i1 true) 649; CHECK-NEXT: ret i32 [[RES]] 650; 651entry: 652 switch i32 %cond, label %default [ 653 i32 0, label %case0 654 i32 1, label %case1 655 i32 2, label %case2 656 ] 657 658case0: 659 br label %exit 660 661case1: 662 br label %exit 663 664case2: 665 br label %exit 666 667default: 668 br label %exit 669 670exit: 671 %bool = phi i1 [ false, %default ], [ true, %case0 ], [ true, %case1 ], [ true, %case2 ] 672 %res = phi i32 [ 0, %default ], [ 1, %case0 ], [ 2, %case1 ], [ 3, %case2 ] 673 call void @llvm.assume(i1 %bool) 674 ret i32 %res 675} 676 677define i32 @test_assume_undef(i32 %cond) { 678; CHECK-LABEL: @test_assume_undef( 679; CHECK-NEXT: entry: 680; CHECK-NEXT: switch i32 [[COND:%.*]], label [[DEFAULT:%.*]] [ 681; CHECK-NEXT: i32 0, label [[EXIT:%.*]] 682; CHECK-NEXT: i32 1, label [[CASE1:%.*]] 683; CHECK-NEXT: i32 2, label [[CASE2:%.*]] 684; CHECK-NEXT: ] 685; CHECK: case1: 686; CHECK-NEXT: br label [[EXIT]] 687; CHECK: case2: 688; CHECK-NEXT: br label [[EXIT]] 689; CHECK: default: 690; CHECK-NEXT: unreachable 691; CHECK: exit: 692; CHECK-NEXT: [[RES:%.*]] = phi i32 [ 2, [[CASE1]] ], [ 3, [[CASE2]] ], [ 1, [[ENTRY:%.*]] ] 693; CHECK-NEXT: call void @llvm.assume(i1 true) 694; CHECK-NEXT: ret i32 [[RES]] 695; 696entry: 697 switch i32 %cond, label %default [ 698 i32 0, label %case0 699 i32 1, label %case1 700 i32 2, label %case2 701 ] 702 703case0: 704 br label %exit 705 706case1: 707 br label %exit 708 709case2: 710 br label %exit 711 712default: 713 br label %exit 714 715exit: 716 %bool = phi i1 [ undef, %default ], [ true, %case0 ], [ true, %case1 ], [ true, %case2 ] 717 %res = phi i32 [ 0, %default ], [ 1, %case0 ], [ 2, %case1 ], [ 3, %case2 ] 718 call void @llvm.assume(i1 %bool) 719 ret i32 %res 720} 721 722define i32 @test_assume_var(i32 %cond, i1 %var) { 723; CHECK-LABEL: @test_assume_var( 724; CHECK-NEXT: entry: 725; CHECK-NEXT: switch i32 [[COND:%.*]], label [[DEFAULT:%.*]] [ 726; CHECK-NEXT: i32 0, label [[EXIT:%.*]] 727; CHECK-NEXT: i32 1, label [[CASE1:%.*]] 728; CHECK-NEXT: i32 2, label [[CASE2:%.*]] 729; CHECK-NEXT: ] 730; CHECK: case1: 731; CHECK-NEXT: br label [[EXIT]] 732; CHECK: case2: 733; CHECK-NEXT: br label [[EXIT]] 734; CHECK: default: 735; CHECK-NEXT: br label [[EXIT]] 736; CHECK: exit: 737; CHECK-NEXT: [[BOOL:%.*]] = phi i1 [ [[VAR:%.*]], [[DEFAULT]] ], [ true, [[CASE1]] ], [ true, [[CASE2]] ], [ true, [[ENTRY:%.*]] ] 738; CHECK-NEXT: [[RES:%.*]] = phi i32 [ 0, [[DEFAULT]] ], [ 2, [[CASE1]] ], [ 3, [[CASE2]] ], [ 1, [[ENTRY]] ] 739; CHECK-NEXT: call void @llvm.assume(i1 [[BOOL]]) 740; CHECK-NEXT: ret i32 [[RES]] 741; 742entry: 743 switch i32 %cond, label %default [ 744 i32 0, label %case0 745 i32 1, label %case1 746 i32 2, label %case2 747 ] 748 749case0: 750 br label %exit 751 752case1: 753 br label %exit 754 755case2: 756 br label %exit 757 758default: 759 br label %exit 760 761exit: 762 %bool = phi i1 [ %var, %default ], [ true, %case0 ], [ true, %case1 ], [ true, %case2 ] 763 %res = phi i32 [ 0, %default ], [ 1, %case0 ], [ 2, %case1 ], [ 3, %case2 ] 764 call void @llvm.assume(i1 %bool) 765 ret i32 %res 766} 767 768define i32 @test_assume_bundle_nonnull(i32 %cond, ptr nonnull %p) { 769; CHECK-LABEL: @test_assume_bundle_nonnull( 770; CHECK-NEXT: entry: 771; CHECK-NEXT: switch i32 [[COND:%.*]], label [[DEFAULT:%.*]] [ 772; CHECK-NEXT: i32 0, label [[EXIT:%.*]] 773; CHECK-NEXT: i32 1, label [[CASE1:%.*]] 774; CHECK-NEXT: i32 2, label [[CASE2:%.*]] 775; CHECK-NEXT: ] 776; CHECK: case1: 777; CHECK-NEXT: br label [[EXIT]] 778; CHECK: case2: 779; CHECK-NEXT: br label [[EXIT]] 780; CHECK: default: 781; CHECK-NEXT: br label [[EXIT]] 782; CHECK: exit: 783; CHECK-NEXT: [[PTR:%.*]] = phi ptr [ null, [[DEFAULT]] ], [ [[P:%.*]], [[CASE1]] ], [ [[P]], [[CASE2]] ], [ [[P]], [[ENTRY:%.*]] ] 784; CHECK-NEXT: [[RES:%.*]] = phi i32 [ 0, [[DEFAULT]] ], [ 2, [[CASE1]] ], [ 3, [[CASE2]] ], [ 1, [[ENTRY]] ] 785; CHECK-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(ptr [[PTR]]) ] 786; CHECK-NEXT: ret i32 [[RES]] 787; 788entry: 789 switch i32 %cond, label %default [ 790 i32 0, label %case0 791 i32 1, label %case1 792 i32 2, label %case2 793 ] 794 795case0: 796 br label %exit 797 798case1: 799 br label %exit 800 801case2: 802 br label %exit 803 804default: 805 br label %exit 806 807exit: 808 %ptr = phi ptr [ null, %default ], [ %p, %case0 ], [ %p, %case1 ], [ %p, %case2 ] 809 %res = phi i32 [ 0, %default ], [ 1, %case0 ], [ 2, %case1 ], [ 3, %case2 ] 810 call void @llvm.assume(i1 true) [ "nonnull"(ptr %ptr) ] 811 ret i32 %res 812} 813 814define i32 @test_assume_bundle_align(i32 %cond, ptr nonnull %p) { 815; CHECK-LABEL: @test_assume_bundle_align( 816; CHECK-NEXT: entry: 817; CHECK-NEXT: switch i32 [[COND:%.*]], label [[DEFAULT:%.*]] [ 818; CHECK-NEXT: i32 0, label [[EXIT:%.*]] 819; CHECK-NEXT: i32 1, label [[CASE1:%.*]] 820; CHECK-NEXT: i32 2, label [[CASE2:%.*]] 821; CHECK-NEXT: ] 822; CHECK: case1: 823; CHECK-NEXT: br label [[EXIT]] 824; CHECK: case2: 825; CHECK-NEXT: br label [[EXIT]] 826; CHECK: default: 827; CHECK-NEXT: br label [[EXIT]] 828; CHECK: exit: 829; CHECK-NEXT: [[PTR:%.*]] = phi ptr [ null, [[DEFAULT]] ], [ [[P:%.*]], [[CASE1]] ], [ [[P]], [[CASE2]] ], [ [[P]], [[ENTRY:%.*]] ] 830; CHECK-NEXT: [[RES:%.*]] = phi i32 [ 0, [[DEFAULT]] ], [ 2, [[CASE1]] ], [ 3, [[CASE2]] ], [ 1, [[ENTRY]] ] 831; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[PTR]], i32 8) ] 832; CHECK-NEXT: ret i32 [[RES]] 833; 834entry: 835 switch i32 %cond, label %default [ 836 i32 0, label %case0 837 i32 1, label %case1 838 i32 2, label %case2 839 ] 840 841case0: 842 br label %exit 843 844case1: 845 br label %exit 846 847case2: 848 br label %exit 849 850default: 851 br label %exit 852 853exit: 854 %ptr = phi ptr [ null, %default ], [ %p, %case0 ], [ %p, %case1 ], [ %p, %case2 ] 855 %res = phi i32 [ 0, %default ], [ 1, %case0 ], [ 2, %case1 ], [ 3, %case2 ] 856 call void @llvm.assume(i1 true) [ "align"(ptr %ptr, i32 8) ] 857 ret i32 %res 858} 859 860; From bb to bb5 is UB. 861define i32 @test9_null_user_order_1(ptr %arg, i1 %arg1, ptr %arg2) { 862; CHECK-LABEL: @test9_null_user_order_1( 863; CHECK-NEXT: bb: 864; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[ARG1:%.*]], true 865; CHECK-NEXT: call void @llvm.assume(i1 [[TMP0]]) 866; CHECK-NEXT: [[I:%.*]] = load ptr, ptr [[ARG:%.*]], align 8 867; CHECK-NEXT: [[I4:%.*]] = getelementptr inbounds i8, ptr [[I]], i64 1 868; CHECK-NEXT: store ptr [[I4]], ptr [[ARG]], align 8 869; CHECK-NEXT: [[I7:%.*]] = load i32, ptr [[I]], align 4 870; CHECK-NEXT: [[I8:%.*]] = icmp ne ptr [[I]], [[ARG2:%.*]] 871; CHECK-NEXT: call void @fn_ptr_arg(i1 [[I8]]) 872; CHECK-NEXT: ret i32 [[I7]] 873; 874bb: 875 br i1 %arg1, label %bb5, label %bb3 876 877bb3: ; preds = %bb 878 %i = load ptr, ptr %arg, align 8 879 %i4 = getelementptr inbounds i8, ptr %i, i64 1 880 store ptr %i4, ptr %arg, align 8 881 br label %bb5 882 883bb5: ; preds = %bb3, %bb 884 %i6 = phi ptr [ %i, %bb3 ], [ null, %bb ] 885 %i7 = load i32, ptr %i6, align 4 886 %i8 = icmp ne ptr %i6, %arg2 887 call void @fn_ptr_arg(i1 %i8) 888 ret i32 %i7 889} 890 891define i32 @test9_null_user_order_2(ptr %arg, i1 %arg1, ptr %arg2) { 892; CHECK-LABEL: @test9_null_user_order_2( 893; CHECK-NEXT: bb: 894; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[ARG1:%.*]], true 895; CHECK-NEXT: call void @llvm.assume(i1 [[TMP0]]) 896; CHECK-NEXT: [[I:%.*]] = load ptr, ptr [[ARG:%.*]], align 8 897; CHECK-NEXT: [[I4:%.*]] = getelementptr inbounds i8, ptr [[I]], i64 1 898; CHECK-NEXT: store ptr [[I4]], ptr [[ARG]], align 8 899; CHECK-NEXT: [[I8:%.*]] = icmp ne ptr [[I]], [[ARG2:%.*]] 900; CHECK-NEXT: call void @fn_ptr_arg_nounwind_willreturn(i1 [[I8]]) 901; CHECK-NEXT: [[I7:%.*]] = load i32, ptr [[I]], align 4 902; CHECK-NEXT: ret i32 [[I7]] 903; 904bb: 905 br i1 %arg1, label %bb5, label %bb3 906 907bb3: ; preds = %bb 908 %i = load ptr, ptr %arg, align 8 909 %i4 = getelementptr inbounds i8, ptr %i, i64 1 910 store ptr %i4, ptr %arg, align 8 911 br label %bb5 912 913bb5: ; preds = %bb3, %bb 914 %i6 = phi ptr [ %i, %bb3 ], [ null, %bb ] 915 %i8 = icmp ne ptr %i6, %arg2 916 call void @fn_ptr_arg_nounwind_willreturn(i1 %i8) 917 %i7 = load i32, ptr %i6, align 4 918 ret i32 %i7 919} 920 921declare void @side.effect() 922declare i8 @get.i8() 923 924define i8 @udiv_by_zero(i8 %x, i8 %i, i8 %v) { 925; CHECK-LABEL: @udiv_by_zero( 926; CHECK-NEXT: entry: 927; CHECK-NEXT: switch i8 [[I:%.*]], label [[SW_DEFAULT:%.*]] [ 928; CHECK-NEXT: i8 9, label [[SW_BB2:%.*]] 929; CHECK-NEXT: i8 2, label [[RETURN:%.*]] 930; CHECK-NEXT: ] 931; CHECK: sw.bb2: 932; CHECK-NEXT: br label [[RETURN]] 933; CHECK: sw.default: 934; CHECK-NEXT: br label [[RETURN]] 935; CHECK: return: 936; CHECK-NEXT: [[Y:%.*]] = phi i8 [ 9, [[SW_BB2]] ], [ [[V:%.*]], [[SW_DEFAULT]] ], [ 2, [[ENTRY:%.*]] ] 937; CHECK-NEXT: [[R:%.*]] = udiv i8 [[X:%.*]], [[Y]] 938; CHECK-NEXT: ret i8 [[R]] 939; 940entry: 941 switch i8 %i, label %sw.default [ 942 i8 0, label %sw.bb0 943 i8 2, label %sw.bb1 944 i8 9, label %sw.bb2 945 ] 946 947sw.bb0: 948 br label %return 949 950sw.bb1: 951 br label %return 952sw.bb2: 953 br label %return 954sw.default: 955 br label %return 956 957return: 958 %y = phi i8 [ 0, %sw.bb0 ], [ 2, %sw.bb1 ], [ 9, %sw.bb2 ], [ %v, %sw.default ] 959 %r = udiv i8 %x, %y 960 ret i8 %r 961} 962 963define i8 @urem_by_zero(i8 %x, i8 %i, i8 %v) { 964; CHECK-LABEL: @urem_by_zero( 965; CHECK-NEXT: entry: 966; CHECK-NEXT: switch i8 [[I:%.*]], label [[SW_DEFAULT:%.*]] [ 967; CHECK-NEXT: i8 0, label [[RETURN:%.*]] 968; CHECK-NEXT: i8 2, label [[SW_BB1:%.*]] 969; CHECK-NEXT: i8 9, label [[SW_BB2:%.*]] 970; CHECK-NEXT: ] 971; CHECK: sw.bb1: 972; CHECK-NEXT: br label [[RETURN]] 973; CHECK: sw.bb2: 974; CHECK-NEXT: br label [[RETURN]] 975; CHECK: sw.default: 976; CHECK-NEXT: unreachable 977; CHECK: return: 978; CHECK-NEXT: [[Y:%.*]] = phi i8 [ 2, [[SW_BB1]] ], [ 9, [[SW_BB2]] ], [ [[V:%.*]], [[ENTRY:%.*]] ] 979; CHECK-NEXT: [[R:%.*]] = urem i8 [[X:%.*]], [[Y]] 980; CHECK-NEXT: ret i8 [[R]] 981; 982entry: 983 switch i8 %i, label %sw.default [ 984 i8 0, label %sw.bb0 985 i8 2, label %sw.bb1 986 i8 9, label %sw.bb2 987 ] 988 989sw.bb0: 990 br label %return 991 992sw.bb1: 993 br label %return 994sw.bb2: 995 br label %return 996sw.default: 997 br label %return 998 999return: 1000 %y = phi i8 [ %v, %sw.bb0 ], [ 2, %sw.bb1 ], [ 9, %sw.bb2 ], [ 0, %sw.default ] 1001 %r = urem i8 %x, %y 1002 ret i8 %r 1003} 1004 1005define i8 @udiv_of_zero_okay(i8 %x, i8 %i, i8 %v) { 1006; CHECK-LABEL: @udiv_of_zero_okay( 1007; CHECK-NEXT: entry: 1008; CHECK-NEXT: switch i8 [[I:%.*]], label [[SW_DEFAULT:%.*]] [ 1009; CHECK-NEXT: i8 0, label [[RETURN:%.*]] 1010; CHECK-NEXT: i8 2, label [[SW_BB1:%.*]] 1011; CHECK-NEXT: i8 9, label [[SW_BB2:%.*]] 1012; CHECK-NEXT: ] 1013; CHECK: sw.bb1: 1014; CHECK-NEXT: br label [[RETURN]] 1015; CHECK: sw.bb2: 1016; CHECK-NEXT: br label [[RETURN]] 1017; CHECK: sw.default: 1018; CHECK-NEXT: br label [[RETURN]] 1019; CHECK: return: 1020; CHECK-NEXT: [[Y:%.*]] = phi i8 [ 2, [[SW_BB1]] ], [ 9, [[SW_BB2]] ], [ [[V:%.*]], [[SW_DEFAULT]] ], [ 0, [[ENTRY:%.*]] ] 1021; CHECK-NEXT: [[R:%.*]] = udiv i8 [[Y]], [[X:%.*]] 1022; CHECK-NEXT: ret i8 [[R]] 1023; 1024entry: 1025 switch i8 %i, label %sw.default [ 1026 i8 0, label %sw.bb0 1027 i8 2, label %sw.bb1 1028 i8 9, label %sw.bb2 1029 ] 1030 1031sw.bb0: 1032 br label %return 1033 1034sw.bb1: 1035 br label %return 1036sw.bb2: 1037 br label %return 1038sw.default: 1039 br label %return 1040 1041return: 1042 %y = phi i8 [ 0, %sw.bb0 ], [ 2, %sw.bb1 ], [ 9, %sw.bb2 ], [ %v, %sw.default ] 1043 %r = udiv i8 %y, %x 1044 ret i8 %r 1045} 1046 1047define i8 @srem_by_zero(i8 %x, i8 %i) { 1048; CHECK-LABEL: @srem_by_zero( 1049; CHECK-NEXT: entry: 1050; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[I:%.*]], 9 1051; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 1052; CHECK: if.then: 1053; CHECK-NEXT: call void @side.effect() 1054; CHECK-NEXT: unreachable 1055; CHECK: if.else: 1056; CHECK-NEXT: [[V:%.*]] = call i8 @get.i8() 1057; CHECK-NEXT: [[R:%.*]] = srem i8 [[X:%.*]], [[V]] 1058; CHECK-NEXT: ret i8 [[R]] 1059; 1060entry: 1061 %cmp = icmp ult i8 %i, 9 1062 br i1 %cmp, label %if.then, label %if.else 1063 1064if.then: 1065 call void @side.effect() 1066 br label %if.end 1067 1068if.else: 1069 %v = call i8 @get.i8() 1070 br label %if.end 1071 1072if.end: 1073 %y = phi i8 [ 0, %if.then ], [ %v, %if.else ] 1074 %r = srem i8 %x, %y 1075 ret i8 %r 1076} 1077 1078define i8 @srem_no_overflow_okay(i8 %i) { 1079; CHECK-LABEL: @srem_no_overflow_okay( 1080; CHECK-NEXT: entry: 1081; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[I:%.*]], 9 1082; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 1083; CHECK: if.then: 1084; CHECK-NEXT: call void @side.effect() 1085; CHECK-NEXT: br label [[IF_END:%.*]] 1086; CHECK: if.else: 1087; CHECK-NEXT: [[V:%.*]] = call i8 @get.i8() 1088; CHECK-NEXT: br label [[IF_END]] 1089; CHECK: if.end: 1090; CHECK-NEXT: [[Y:%.*]] = phi i8 [ -1, [[IF_THEN]] ], [ [[V]], [[IF_ELSE]] ] 1091; CHECK-NEXT: [[R:%.*]] = srem i8 [[Y]], -128 1092; CHECK-NEXT: ret i8 [[R]] 1093; 1094entry: 1095 %cmp = icmp ult i8 %i, 9 1096 br i1 %cmp, label %if.then, label %if.else 1097 1098if.then: 1099 call void @side.effect() 1100 br label %if.end 1101 1102if.else: 1103 %v = call i8 @get.i8() 1104 br label %if.end 1105 1106if.end: 1107 %y = phi i8 [ -1, %if.then ], [ %v, %if.else ] 1108 %r = srem i8 %y, 128 1109 ret i8 %r 1110} 1111 1112define i8 @sdiv_overflow_ub(i8 %i) { 1113; CHECK-LABEL: @sdiv_overflow_ub( 1114; CHECK-NEXT: entry: 1115; CHECK-NEXT: switch i8 [[I:%.*]], label [[SW_DEFAULT:%.*]] [ 1116; CHECK-NEXT: i8 0, label [[RETURN:%.*]] 1117; CHECK-NEXT: i8 2, label [[SW_BB1:%.*]] 1118; CHECK-NEXT: i8 9, label [[SW_BB2:%.*]] 1119; CHECK-NEXT: ] 1120; CHECK: sw.bb1: 1121; CHECK-NEXT: [[V:%.*]] = call i8 @get.i8() 1122; CHECK-NEXT: br label [[RETURN]] 1123; CHECK: sw.bb2: 1124; CHECK-NEXT: br label [[RETURN]] 1125; CHECK: sw.default: 1126; CHECK-NEXT: unreachable 1127; CHECK: return: 1128; CHECK-NEXT: [[Y:%.*]] = phi i8 [ [[V]], [[SW_BB1]] ], [ -1, [[SW_BB2]] ], [ 4, [[ENTRY:%.*]] ] 1129; CHECK-NEXT: [[R:%.*]] = sdiv i8 -128, [[Y]] 1130; CHECK-NEXT: ret i8 [[R]] 1131; 1132entry: 1133 switch i8 %i, label %sw.default [ 1134 i8 0, label %sw.bb0 1135 i8 2, label %sw.bb1 1136 i8 9, label %sw.bb2 1137 ] 1138 1139sw.bb0: 1140 br label %return 1141sw.bb1: 1142 %v = call i8 @get.i8() 1143 br label %return 1144sw.bb2: 1145 br label %return 1146sw.default: 1147 unreachable 1148 1149return: 1150 %y = phi i8 [ 4, %sw.bb0 ], [ %v, %sw.bb1 ], [ -1, %sw.bb2 ] 1151 %r = sdiv i8 128, %y 1152 ret i8 %r 1153} 1154 1155define i8 @sdiv_overflow_ub_2x(i8 %i) { 1156; CHECK-LABEL: @sdiv_overflow_ub_2x( 1157; CHECK-NEXT: entry: 1158; CHECK-NEXT: switch i8 [[I:%.*]], label [[SW_DEFAULT:%.*]] [ 1159; CHECK-NEXT: i8 9, label [[RETURN:%.*]] 1160; CHECK-NEXT: i8 2, label [[SW_BB1:%.*]] 1161; CHECK-NEXT: ] 1162; CHECK: sw.bb1: 1163; CHECK-NEXT: [[V:%.*]] = call i8 @get.i8() 1164; CHECK-NEXT: br label [[RETURN]] 1165; CHECK: sw.default: 1166; CHECK-NEXT: unreachable 1167; CHECK: return: 1168; CHECK-NEXT: [[Y:%.*]] = phi i8 [ [[V]], [[SW_BB1]] ], [ -1, [[ENTRY:%.*]] ] 1169; CHECK-NEXT: [[R:%.*]] = sdiv i8 -128, [[Y]] 1170; CHECK-NEXT: ret i8 [[R]] 1171; 1172entry: 1173 switch i8 %i, label %sw.default [ 1174 i8 0, label %sw.bb0 1175 i8 2, label %sw.bb1 1176 i8 9, label %sw.bb2 1177 ] 1178 1179sw.bb0: 1180 br label %return 1181sw.bb1: 1182 %v = call i8 @get.i8() 1183 br label %return 1184sw.bb2: 1185 br label %return 1186sw.default: 1187 unreachable 1188 1189return: 1190 %y = phi i8 [ 0, %sw.bb0 ], [ %v, %sw.bb1 ], [ -1, %sw.bb2 ] 1191 %r = sdiv i8 128, %y 1192 ret i8 %r 1193} 1194 1195attributes #0 = { null_pointer_is_valid } 1196;. 1197; CHECK: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: write) } 1198; CHECK: attributes #[[ATTR1:[0-9]+]] = { nocallback nofree nosync nounwind speculatable willreturn memory(none) } 1199; CHECK: attributes #[[ATTR2:[0-9]+]] = { null_pointer_is_valid } 1200; CHECK: attributes #[[ATTR3:[0-9]+]] = { nounwind willreturn } 1201; CHECK: attributes #[[ATTR4]] = { nounwind } 1202;. 1203