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