1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -passes=instcombine -S < %s | FileCheck %s 3 4define void @test_bitcast_1(i1 %c, i32* %ptr) { 5; CHECK-LABEL: @test_bitcast_1( 6; CHECK-NEXT: entry: 7; CHECK-NEXT: br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]] 8; CHECK: b0: 9; CHECK-NEXT: [[CAST_0:%.*]] = bitcast i32* [[PTR:%.*]] to i8* 10; CHECK-NEXT: call void @use(i8* [[CAST_0]]) 11; CHECK-NEXT: br label [[END:%.*]] 12; CHECK: b1: 13; CHECK-NEXT: br label [[END]] 14; CHECK: end: 15; CHECK-NEXT: [[P:%.*]] = bitcast i32* [[PTR]] to i8* 16; CHECK-NEXT: store i8 0, i8* [[P]], align 1 17; CHECK-NEXT: ret void 18; 19entry: 20 %cast.0 = bitcast i32* %ptr to i8* 21 %cast.1 = bitcast i32* %ptr to i8* 22 br i1 %c, label %b0, label %b1 23 24b0: 25 call void @use(i8* %cast.0) 26 br label %end 27 28b1: 29 br label %end 30 31end: 32 %p = phi i8* [ %cast.0, %b0 ], [ %cast.1, %b1 ] 33 store i8 0, i8* %p 34 ret void 35} 36 37define void @test_bitcast_2(i1 %c, i32* %ptr) { 38; CHECK-LABEL: @test_bitcast_2( 39; CHECK-NEXT: entry: 40; CHECK-NEXT: br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]] 41; CHECK: b0: 42; CHECK-NEXT: br label [[END:%.*]] 43; CHECK: b1: 44; CHECK-NEXT: [[CAST_1:%.*]] = bitcast i32* [[PTR:%.*]] to i8* 45; CHECK-NEXT: call void @use(i8* [[CAST_1]]) 46; CHECK-NEXT: br label [[END]] 47; CHECK: end: 48; CHECK-NEXT: [[P:%.*]] = bitcast i32* [[PTR]] to i8* 49; CHECK-NEXT: store i8 0, i8* [[P]], align 1 50; CHECK-NEXT: ret void 51; 52entry: 53 br i1 %c, label %b0, label %b1 54 55b0: 56 %cast.0 = bitcast i32* %ptr to i8* 57 br label %end 58 59b1: 60 %cast.1 = bitcast i32* %ptr to i8* 61 call void @use(i8* %cast.1) 62 br label %end 63 64end: 65 %p = phi i8* [ %cast.0, %b0 ], [ %cast.1, %b1 ] 66 store i8 0, i8* %p 67 ret void 68} 69 70 71define void @test_bitcast_3(i1 %c, i32** %ptr) { 72; CHECK-LABEL: @test_bitcast_3( 73; CHECK-NEXT: entry: 74; CHECK-NEXT: [[LOAD_PTR:%.*]] = load i32*, i32** [[PTR:%.*]], align 8 75; CHECK-NEXT: br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]] 76; CHECK: b0: 77; CHECK-NEXT: br label [[END:%.*]] 78; CHECK: b1: 79; CHECK-NEXT: [[CAST_1:%.*]] = bitcast i32* [[LOAD_PTR]] to i8* 80; CHECK-NEXT: call void @use(i8* [[CAST_1]]) 81; CHECK-NEXT: br label [[END]] 82; CHECK: end: 83; CHECK-NEXT: [[P:%.*]] = bitcast i32* [[LOAD_PTR]] to i8* 84; CHECK-NEXT: store i8 0, i8* [[P]], align 1 85; CHECK-NEXT: ret void 86; 87entry: 88 %load.ptr = load i32*, i32** %ptr 89 br i1 %c, label %b0, label %b1 90 91b0: 92 %cast.0 = bitcast i32* %load.ptr to i8* 93 br label %end 94 95b1: 96 %cast.1 = bitcast i32* %load.ptr to i8* 97 call void @use(i8* %cast.1) 98 br label %end 99 100end: 101 %p = phi i8* [ %cast.0, %b0 ], [ %cast.1, %b1 ] 102 store i8 0, i8* %p 103 ret void 104} 105 106define void @test_bitcast_loads_in_different_bbs(i1 %c, i32** %ptr.0, i32** %ptr.1) { 107; CHECK-LABEL: @test_bitcast_loads_in_different_bbs( 108; CHECK-NEXT: entry: 109; CHECK-NEXT: br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]] 110; CHECK: b0: 111; CHECK-NEXT: [[TMP0:%.*]] = bitcast i32** [[PTR_0:%.*]] to i8** 112; CHECK-NEXT: [[LOAD_PTR_02:%.*]] = load i8*, i8** [[TMP0]], align 8 113; CHECK-NEXT: call void @use(i8* [[LOAD_PTR_02]]) 114; CHECK-NEXT: br label [[END:%.*]] 115; CHECK: b1: 116; CHECK-NEXT: [[TMP1:%.*]] = bitcast i32** [[PTR_1:%.*]] to i8** 117; CHECK-NEXT: [[LOAD_PTR_11:%.*]] = load i8*, i8** [[TMP1]], align 8 118; CHECK-NEXT: br label [[END]] 119; CHECK: end: 120; CHECK-NEXT: [[P:%.*]] = phi i8* [ [[LOAD_PTR_02]], [[B0]] ], [ [[LOAD_PTR_11]], [[B1]] ] 121; CHECK-NEXT: store i8 0, i8* [[P]], align 1 122; CHECK-NEXT: ret void 123; 124entry: 125 br i1 %c, label %b0, label %b1 126 127b0: 128 %load.ptr.0 = load i32*, i32** %ptr.0 129 %cast.0 = bitcast i32* %load.ptr.0 to i8* 130 call void @use(i8* %cast.0) 131 br label %end 132 133b1: 134 %load.ptr.1 = load i32*, i32** %ptr.1 135 %cast.1 = bitcast i32* %load.ptr.1 to i8* 136 br label %end 137 138end: 139 %p = phi i8* [ %cast.0, %b0 ], [ %cast.1, %b1 ] 140 store i8 0, i8* %p 141 ret void 142} 143 144define void @test_gep_1(i1 %c, i32* %ptr) { 145; CHECK-LABEL: @test_gep_1( 146; CHECK-NEXT: entry: 147; CHECK-NEXT: br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]] 148; CHECK: b0: 149; CHECK-NEXT: call void @use.i32(i32* [[PTR:%.*]]) 150; CHECK-NEXT: br label [[END:%.*]] 151; CHECK: b1: 152; CHECK-NEXT: br label [[END]] 153; CHECK: end: 154; CHECK-NEXT: store i32 0, i32* [[PTR]], align 4 155; CHECK-NEXT: ret void 156; 157entry: 158 br i1 %c, label %b0, label %b1 159 160b0: 161 %cast.0 = getelementptr i32, i32* %ptr, i32 0 162 call void @use.i32(i32* %cast.0) 163 br label %end 164 165b1: 166 %cast.1 = getelementptr i32, i32* %ptr, i32 0 167 br label %end 168 169end: 170 %p = phi i32* [ %cast.0, %b0 ], [ %cast.1, %b1 ] 171 store i32 0, i32* %p 172 ret void 173} 174 175define void @test_bitcast_not_foldable(i1 %c, i32* %ptr.0, i32* %ptr.1) { 176; CHECK-LABEL: @test_bitcast_not_foldable( 177; CHECK-NEXT: entry: 178; CHECK-NEXT: br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]] 179; CHECK: b0: 180; CHECK-NEXT: [[CAST_0:%.*]] = bitcast i32* [[PTR_0:%.*]] to i8* 181; CHECK-NEXT: br label [[END:%.*]] 182; CHECK: b1: 183; CHECK-NEXT: [[CAST_1:%.*]] = bitcast i32* [[PTR_1:%.*]] to i8* 184; CHECK-NEXT: call void @use(i8* [[CAST_1]]) 185; CHECK-NEXT: br label [[END]] 186; CHECK: end: 187; CHECK-NEXT: [[P:%.*]] = phi i8* [ [[CAST_0]], [[B0]] ], [ [[CAST_1]], [[B1]] ] 188; CHECK-NEXT: store i8 0, i8* [[P]], align 1 189; CHECK-NEXT: ret void 190; 191entry: 192 br i1 %c, label %b0, label %b1 193 194b0: 195 %cast.0 = bitcast i32* %ptr.0 to i8* 196 br label %end 197 198b1: 199 %cast.1 = bitcast i32* %ptr.1 to i8* 200 call void @use(i8* %cast.1) 201 br label %end 202 203end: 204 %p = phi i8* [ %cast.0, %b0 ], [ %cast.1, %b1 ] 205 store i8 0, i8* %p 206 ret void 207} 208 209define void @test_bitcast_with_extra_use(i1 %c, i32* %ptr) { 210; CHECK-LABEL: @test_bitcast_with_extra_use( 211; CHECK-NEXT: entry: 212; CHECK-NEXT: br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]] 213; CHECK: b0: 214; CHECK-NEXT: [[CAST_0:%.*]] = bitcast i32* [[PTR:%.*]] to i8* 215; CHECK-NEXT: call void @use(i8* [[CAST_0]]) 216; CHECK-NEXT: br label [[END:%.*]] 217; CHECK: b1: 218; CHECK-NEXT: br label [[END]] 219; CHECK: end: 220; CHECK-NEXT: [[P:%.*]] = bitcast i32* [[PTR]] to i8* 221; CHECK-NEXT: store i8 0, i8* [[P]], align 1 222; CHECK-NEXT: ret void 223; 224entry: 225 br i1 %c, label %b0, label %b1 226 227b0: 228 %cast.0 = bitcast i32* %ptr to i8* 229 call void @use(i8* %cast.0) 230 br label %end 231 232b1: 233 %cast.1 = bitcast i32* %ptr to i8* 234 br label %end 235 236end: 237 %p = phi i8* [ %cast.0, %b0 ], [ %cast.1, %b1 ] 238 store i8 0, i8* %p 239 ret void 240} 241 242define void @test_bitcast_different_bases(i1 %c, i32* %ptr.0, i32* %ptr.1) { 243; CHECK-LABEL: @test_bitcast_different_bases( 244; CHECK-NEXT: entry: 245; CHECK-NEXT: br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]] 246; CHECK: b0: 247; CHECK-NEXT: [[CAST_0:%.*]] = bitcast i32* [[PTR_0:%.*]] to i8* 248; CHECK-NEXT: call void @use(i8* [[CAST_0]]) 249; CHECK-NEXT: br label [[END:%.*]] 250; CHECK: b1: 251; CHECK-NEXT: [[CAST_1:%.*]] = bitcast i32* [[PTR_1:%.*]] to i8* 252; CHECK-NEXT: br label [[END]] 253; CHECK: end: 254; CHECK-NEXT: [[P:%.*]] = phi i8* [ [[CAST_0]], [[B0]] ], [ [[CAST_1]], [[B1]] ] 255; CHECK-NEXT: store i8 0, i8* [[P]], align 1 256; CHECK-NEXT: ret void 257; 258entry: 259 br i1 %c, label %b0, label %b1 260 261b0: 262 %cast.0 = bitcast i32* %ptr.0 to i8* 263 call void @use(i8* %cast.0) 264 br label %end 265 266b1: 267 %cast.1 = bitcast i32* %ptr.1 to i8* 268 br label %end 269 270end: 271 %p = phi i8* [ %cast.0, %b0 ], [ %cast.1, %b1 ] 272 store i8 0, i8* %p 273 ret void 274} 275 276define void @test_bitcast_gep_chains(i1 %c, i32* %ptr) { 277; CHECK-LABEL: @test_bitcast_gep_chains( 278; CHECK-NEXT: entry: 279; CHECK-NEXT: br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]] 280; CHECK: b0: 281; CHECK-NEXT: [[CAST_0:%.*]] = bitcast i32* [[PTR:%.*]] to i8* 282; CHECK-NEXT: call void @use(i8* [[CAST_0]]) 283; CHECK-NEXT: br label [[END:%.*]] 284; CHECK: b1: 285; CHECK-NEXT: call void @use.i32(i32* [[PTR]]) 286; CHECK-NEXT: br label [[END]] 287; CHECK: end: 288; CHECK-NEXT: [[P:%.*]] = bitcast i32* [[PTR]] to i8* 289; CHECK-NEXT: store i8 0, i8* [[P]], align 1 290; CHECK-NEXT: ret void 291; 292entry: 293 %gep = getelementptr i32, i32* %ptr, i32 0 294 br i1 %c, label %b0, label %b1 295 296b0: 297 %cast.0 = bitcast i32* %gep to i8* 298 call void @use(i8* %cast.0) 299 br label %end 300 301b1: 302 %cast.1 = bitcast i32* %ptr to i8* 303 %cast.2 = bitcast i8* %cast.1 to i32* 304 call void @use.i32(i32* %cast.2) 305 %cast.3 = bitcast i32* %cast.2 to i8* 306 br label %end 307 308end: 309 %p = phi i8* [ %cast.0, %b0 ], [ %cast.3, %b1 ] 310 store i8 0, i8* %p 311 ret void 312} 313 314define void @test_4_incoming_values_different_bases_1(i32 %c, i32* %ptr.0, i32* %ptr.1) { 315; CHECK-LABEL: @test_4_incoming_values_different_bases_1( 316; CHECK-NEXT: entry: 317; CHECK-NEXT: switch i32 [[C:%.*]], label [[END_2:%.*]] [ 318; CHECK-NEXT: i32 0, label [[B0:%.*]] 319; CHECK-NEXT: i32 1, label [[B1:%.*]] 320; CHECK-NEXT: i32 2, label [[B2:%.*]] 321; CHECK-NEXT: i32 3, label [[B3:%.*]] 322; CHECK-NEXT: ] 323; CHECK: b0: 324; CHECK-NEXT: [[CAST_0:%.*]] = bitcast i32* [[PTR_0:%.*]] to i8* 325; CHECK-NEXT: call void @use(i8* [[CAST_0]]) 326; CHECK-NEXT: br label [[END:%.*]] 327; CHECK: b1: 328; CHECK-NEXT: [[CAST_3:%.*]] = bitcast i32* [[PTR_1:%.*]] to i8* 329; CHECK-NEXT: br label [[END]] 330; CHECK: b2: 331; CHECK-NEXT: [[CAST_4:%.*]] = bitcast i32* [[PTR_0]] to i8* 332; CHECK-NEXT: br label [[END]] 333; CHECK: b3: 334; CHECK-NEXT: [[CAST_5:%.*]] = bitcast i32* [[PTR_0]] to i8* 335; CHECK-NEXT: br label [[END]] 336; CHECK: end: 337; CHECK-NEXT: [[P:%.*]] = phi i8* [ [[CAST_0]], [[B0]] ], [ [[CAST_3]], [[B1]] ], [ [[CAST_4]], [[B2]] ], [ [[CAST_5]], [[B3]] ] 338; CHECK-NEXT: store i8 0, i8* [[P]], align 1 339; CHECK-NEXT: ret void 340; CHECK: end.2: 341; CHECK-NEXT: ret void 342; 343entry: 344 %gep = getelementptr i32, i32* %ptr.0, i32 0 345 switch i32 %c, label %end.2 [ i32 0, label %b0 346 i32 1, label %b1 347 i32 2, label %b2 348 i32 3, label %b3] 349 350b0: 351 %cast.0 = bitcast i32* %gep to i8* 352 call void @use(i8* %cast.0) 353 br label %end 354 355b1: 356 %cast.1 = bitcast i32* %ptr.1 to i8* 357 %cast.2 = bitcast i8* %cast.1 to i64* 358 %cast.3 = bitcast i64* %cast.2 to i8* 359 br label %end 360 361b2: 362 %cast.4 = bitcast i32* %gep to i8* 363 br label %end 364 365b3: 366 %cast.5 = bitcast i32 * %ptr.0 to i8* 367 br label %end 368 369end: 370 %p = phi i8* [ %cast.0, %b0 ], [ %cast.3, %b1 ], [ %cast.4, %b2 ], [ %cast.5, %b3] 371 store i8 0, i8* %p 372 ret void 373 374end.2: 375 ret void 376} 377 378define void @test_4_incoming_values_different_bases_2(i32 %c, i32* %ptr.0, i32* %ptr.1) { 379; CHECK-LABEL: @test_4_incoming_values_different_bases_2( 380; CHECK-NEXT: entry: 381; CHECK-NEXT: switch i32 [[C:%.*]], label [[END_2:%.*]] [ 382; CHECK-NEXT: i32 0, label [[B0:%.*]] 383; CHECK-NEXT: i32 1, label [[B1:%.*]] 384; CHECK-NEXT: i32 2, label [[B2:%.*]] 385; CHECK-NEXT: i32 3, label [[B3:%.*]] 386; CHECK-NEXT: ] 387; CHECK: b0: 388; CHECK-NEXT: br label [[END:%.*]] 389; CHECK: b1: 390; CHECK-NEXT: [[CAST_1:%.*]] = bitcast i32* [[PTR_0:%.*]] to i8* 391; CHECK-NEXT: call void @use(i8* [[CAST_1]]) 392; CHECK-NEXT: br label [[END]] 393; CHECK: b2: 394; CHECK-NEXT: br label [[END]] 395; CHECK: b3: 396; CHECK-NEXT: br label [[END]] 397; CHECK: end: 398; CHECK-NEXT: [[P_IN:%.*]] = phi i32* [ [[PTR_1:%.*]], [[B0]] ], [ [[PTR_0]], [[B1]] ], [ [[PTR_0]], [[B2]] ], [ [[PTR_0]], [[B3]] ] 399; CHECK-NEXT: [[P:%.*]] = bitcast i32* [[P_IN]] to i8* 400; CHECK-NEXT: store i8 0, i8* [[P]], align 1 401; CHECK-NEXT: ret void 402; CHECK: end.2: 403; CHECK-NEXT: ret void 404; 405entry: 406 %gep = getelementptr i32, i32* %ptr.0, i32 0 407 switch i32 %c, label %end.2 [ i32 0, label %b0 408 i32 1, label %b1 409 i32 2, label %b2 410 i32 3, label %b3] 411 412b0: 413 %cast.0 = bitcast i32* %ptr.1 to i8* 414 br label %end 415 416b1: 417 %cast.1 = bitcast i32* %ptr.0 to i8* 418 call void @use(i8* %cast.1) 419 %cast.2 = bitcast i8* %cast.1 to i64* 420 %cast.3 = bitcast i64* %cast.2 to i8* 421 br label %end 422 423b2: 424 %cast.4 = bitcast i32* %gep to i8* 425 br label %end 426 427b3: 428 %cast.5 = bitcast i32 * %ptr.0 to i8* 429 br label %end 430 431end: 432 %p = phi i8* [ %cast.0, %b0 ], [ %cast.3, %b1 ], [ %cast.4, %b2 ], [ %cast.5, %b3] 433 store i8 0, i8* %p 434 ret void 435 436end.2: 437 ret void 438} 439 440define void @test_4_incoming_values_different_bases_3(i32 %c, i32* %ptr.0, i32* %ptr.1) { 441; CHECK-LABEL: @test_4_incoming_values_different_bases_3( 442; CHECK-NEXT: entry: 443; CHECK-NEXT: switch i32 [[C:%.*]], label [[END_2:%.*]] [ 444; CHECK-NEXT: i32 0, label [[B0:%.*]] 445; CHECK-NEXT: i32 1, label [[B1:%.*]] 446; CHECK-NEXT: i32 2, label [[B2:%.*]] 447; CHECK-NEXT: i32 3, label [[B3:%.*]] 448; CHECK-NEXT: ] 449; CHECK: b0: 450; CHECK-NEXT: [[CAST_0:%.*]] = bitcast i32* [[PTR_0:%.*]] to i8* 451; CHECK-NEXT: br label [[END:%.*]] 452; CHECK: b1: 453; CHECK-NEXT: [[CAST_3:%.*]] = bitcast i32* [[PTR_0]] to i8* 454; CHECK-NEXT: br label [[END]] 455; CHECK: b2: 456; CHECK-NEXT: [[CAST_4:%.*]] = bitcast i32* [[PTR_0]] to i8* 457; CHECK-NEXT: call void @use(i8* [[CAST_4]]) 458; CHECK-NEXT: br label [[END]] 459; CHECK: b3: 460; CHECK-NEXT: [[CAST_5:%.*]] = bitcast i32* [[PTR_1:%.*]] to i8* 461; CHECK-NEXT: br label [[END]] 462; CHECK: end: 463; CHECK-NEXT: [[P:%.*]] = phi i8* [ [[CAST_0]], [[B0]] ], [ [[CAST_3]], [[B1]] ], [ [[CAST_4]], [[B2]] ], [ [[CAST_5]], [[B3]] ] 464; CHECK-NEXT: store i8 0, i8* [[P]], align 1 465; CHECK-NEXT: ret void 466; CHECK: end.2: 467; CHECK-NEXT: ret void 468; 469entry: 470 %gep = getelementptr i32, i32* %ptr.0, i32 0 471 switch i32 %c, label %end.2 [ i32 0, label %b0 472 i32 1, label %b1 473 i32 2, label %b2 474 i32 3, label %b3] 475 476b0: 477 %cast.0 = bitcast i32* %ptr.0 to i8* 478 br label %end 479 480b1: 481 %cast.1 = bitcast i32* %ptr.0 to i8* 482 %cast.2 = bitcast i8* %cast.1 to i64* 483 %cast.3 = bitcast i64* %cast.2 to i8* 484 br label %end 485 486b2: 487 %cast.4 = bitcast i32* %gep to i8* 488 call void @use(i8* %cast.4) 489 br label %end 490 491b3: 492 %cast.5 = bitcast i32 * %ptr.1 to i8* 493 br label %end 494 495end: 496 %p = phi i8* [ %cast.0, %b0 ], [ %cast.3, %b1 ], [ %cast.4, %b2 ], [ %cast.5, %b3] 497 store i8 0, i8* %p 498 ret void 499 500end.2: 501 ret void 502} 503 504define void @test_addrspacecast_1(i1 %c, i32* %ptr) { 505; CHECK-LABEL: @test_addrspacecast_1( 506; CHECK-NEXT: entry: 507; CHECK-NEXT: br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]] 508; CHECK: b0: 509; CHECK-NEXT: br label [[END:%.*]] 510; CHECK: b1: 511; CHECK-NEXT: [[TMP0:%.*]] = bitcast i32* [[PTR:%.*]] to i8* 512; CHECK-NEXT: [[CAST_1:%.*]] = addrspacecast i8* [[TMP0]] to i8 addrspace(1)* 513; CHECK-NEXT: call void @use.i8.addrspace1(i8 addrspace(1)* [[CAST_1]]) 514; CHECK-NEXT: br label [[END]] 515; CHECK: end: 516; CHECK-NEXT: [[TMP1:%.*]] = bitcast i32* [[PTR]] to i8* 517; CHECK-NEXT: [[P:%.*]] = addrspacecast i8* [[TMP1]] to i8 addrspace(1)* 518; CHECK-NEXT: store i8 0, i8 addrspace(1)* [[P]], align 1 519; CHECK-NEXT: ret void 520; 521entry: 522 %cast.0 = addrspacecast i32* %ptr to i8 addrspace(1)* 523 %cast.1 = addrspacecast i32* %ptr to i8 addrspace(1)* 524 br i1 %c, label %b0, label %b1 525 526b0: 527 br label %end 528 529b1: 530 call void @use.i8.addrspace1(i8 addrspace(1)* %cast.1) 531 br label %end 532 533end: 534 %p = phi i8 addrspace(1)* [ %cast.0, %b0 ], [ %cast.1, %b1 ] 535 store i8 0, i8 addrspace(1)* %p 536 ret void 537} 538 539declare void @use(i8*) 540declare void @use.i32(i32*) 541declare void @use.i8.addrspace1(i8 addrspace(1)*) 542