1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -passes='require<domtree>,loop(loop-simplifycfg),gvn' -S %s | FileCheck %s 3 4define i32 @test_pointer_phi_select_simp_1(ptr %a, ptr %b, i1 %cond) { 5; CHECK-LABEL: @test_pointer_phi_select_simp_1( 6; CHECK-NEXT: entry: 7; CHECK-NEXT: br i1 [[COND:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]] 8; CHECK: then: 9; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[A:%.*]], align 4 10; CHECK-NEXT: [[L_2:%.*]] = load i32, ptr [[B:%.*]], align 4 11; CHECK-NEXT: [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]] 12; CHECK-NEXT: [[TMP0:%.*]] = select i1 [[CMP_I_I_I]], i32 [[L_1]], i32 [[L_2]] 13; CHECK-NEXT: [[MIN_SELECT:%.*]] = select i1 [[CMP_I_I_I]], ptr [[A]], ptr [[B]] 14; CHECK-NEXT: br label [[EXIT:%.*]] 15; CHECK: else: 16; CHECK-NEXT: [[RES_2_PRE:%.*]] = load i32, ptr [[A]], align 4 17; CHECK-NEXT: br label [[EXIT]] 18; CHECK: exit: 19; CHECK-NEXT: [[RES_2:%.*]] = phi i32 [ [[TMP0]], [[THEN]] ], [ [[RES_2_PRE]], [[ELSE]] ] 20; CHECK-NEXT: [[P:%.*]] = phi ptr [ [[MIN_SELECT]], [[THEN]] ], [ [[A]], [[ELSE]] ] 21; CHECK-NEXT: ret i32 [[RES_2]] 22; 23entry: 24 br i1 %cond, label %then, label %else 25 26then: 27 %l.1 = load i32, ptr %a, align 4 28 %l.2 = load i32, ptr %b, align 4 29 %cmp.i.i.i = icmp ult i32 %l.1, %l.2 30 %min.select = select i1 %cmp.i.i.i, ptr %a, ptr %b 31 br label %exit 32 33else: 34 br label %exit 35 36exit: 37 %p = phi ptr [ %min.select, %then ], [ %a, %else ] 38 %res.2 = load i32, ptr %p, align 4 39 ret i32 %res.2 40} 41 42define i32 @test_pointer_phi_select_simp_non_local(ptr %a, ptr %b, ptr %c) { 43; CHECK-LABEL: @test_pointer_phi_select_simp_non_local( 44; CHECK-NEXT: entry: 45; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[A:%.*]], align 4 46; CHECK-NEXT: [[COND:%.*]] = icmp sgt i32 [[L_1]], 0 47; CHECK-NEXT: br i1 [[COND]], label [[THEN:%.*]], label [[ELSE:%.*]] 48; CHECK: then: 49; CHECK-NEXT: [[L_2:%.*]] = load i32, ptr [[B:%.*]], align 4 50; CHECK-NEXT: [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]] 51; CHECK-NEXT: [[TMP0:%.*]] = select i1 [[CMP_I_I_I]], i32 [[L_1]], i32 [[L_2]] 52; CHECK-NEXT: [[MIN_SELECT:%.*]] = select i1 [[CMP_I_I_I]], ptr [[A]], ptr [[B]] 53; CHECK-NEXT: br label [[EXIT:%.*]] 54; CHECK: else: 55; CHECK-NEXT: [[RES_2_PRE:%.*]] = load i32, ptr [[C:%.*]], align 4 56; CHECK-NEXT: br label [[EXIT]] 57; CHECK: exit: 58; CHECK-NEXT: [[RES_2:%.*]] = phi i32 [ [[TMP0]], [[THEN]] ], [ [[RES_2_PRE]], [[ELSE]] ] 59; CHECK-NEXT: [[P:%.*]] = phi ptr [ [[MIN_SELECT]], [[THEN]] ], [ [[C]], [[ELSE]] ] 60; CHECK-NEXT: ret i32 [[RES_2]] 61; 62entry: 63 %l.1 = load i32, ptr %a, align 4 64 %cond = icmp sgt i32 %l.1, 0 65 br i1 %cond, label %then, label %else 66 67then: 68 %l.2 = load i32, ptr %b, align 4 69 %cmp.i.i.i = icmp ult i32 %l.1, %l.2 70 %min.select = select i1 %cmp.i.i.i, ptr %a, ptr %b 71 br label %exit 72 73else: 74 br label %exit 75 76exit: 77 %p = phi ptr [ %min.select, %then ], [ %c, %else ] 78 %res.2 = load i32, ptr %p, align 4 79 ret i32 %res.2 80} 81 82define i32 @test_pointer_phi_select_simp_non_local_mismatched_type(ptr %a, ptr %b, ptr %c) { 83; CHECK-LABEL: @test_pointer_phi_select_simp_non_local_mismatched_type( 84; CHECK-NEXT: entry: 85; CHECK-NEXT: [[L_1:%.*]] = load float, ptr [[A:%.*]], align 4 86; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[L_1]] to i32 87; CHECK-NEXT: [[COND:%.*]] = icmp sgt i32 [[CONV]], 0 88; CHECK-NEXT: br i1 [[COND]], label [[THEN:%.*]], label [[ELSE:%.*]] 89; CHECK: then: 90; CHECK-NEXT: [[L_2:%.*]] = load i32, ptr [[B:%.*]], align 4 91; CHECK-NEXT: [[CMP_I_I_I:%.*]] = icmp ult i32 [[CONV]], [[L_2]] 92; CHECK-NEXT: [[MIN_SELECT:%.*]] = select i1 [[CMP_I_I_I]], ptr [[A]], ptr [[B]] 93; CHECK-NEXT: br label [[EXIT:%.*]] 94; CHECK: else: 95; CHECK-NEXT: br label [[EXIT]] 96; CHECK: exit: 97; CHECK-NEXT: [[P:%.*]] = phi ptr [ [[MIN_SELECT]], [[THEN]] ], [ [[C:%.*]], [[ELSE]] ] 98; CHECK-NEXT: [[RES_2:%.*]] = load i32, ptr [[P]], align 4 99; CHECK-NEXT: ret i32 [[RES_2]] 100; 101entry: 102 %l.1 = load float, ptr %a, align 4 103 %conv = fptosi float %l.1 to i32 104 %cond = icmp sgt i32 %conv, 0 105 br i1 %cond, label %then, label %else 106 107then: 108 %l.2 = load i32, ptr %b, align 4 109 %cmp.i.i.i = icmp ult i32 %conv, %l.2 110 %min.select = select i1 %cmp.i.i.i, ptr %a, ptr %b 111 br label %exit 112 113else: 114 br label %exit 115 116exit: 117 %p = phi ptr [ %min.select, %then ], [ %c, %else ] 118 %res.2 = load i32, ptr %p, align 4 119 ret i32 %res.2 120} 121 122define i32 @test_pointer_phi_select_simp_no_load_for_select_op_1(ptr %a, ptr %b, ptr %c, i1 %cond) { 123; CHECK-LABEL: @test_pointer_phi_select_simp_no_load_for_select_op_1( 124; CHECK-NEXT: entry: 125; CHECK-NEXT: br i1 [[COND:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]] 126; CHECK: then: 127; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[C:%.*]], align 4 128; CHECK-NEXT: [[L_2:%.*]] = load i32, ptr [[B:%.*]], align 4 129; CHECK-NEXT: [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]] 130; CHECK-NEXT: [[MIN_SELECT:%.*]] = select i1 [[CMP_I_I_I]], ptr [[A:%.*]], ptr [[B]] 131; CHECK-NEXT: br label [[EXIT:%.*]] 132; CHECK: else: 133; CHECK-NEXT: br label [[EXIT]] 134; CHECK: exit: 135; CHECK-NEXT: [[P:%.*]] = phi ptr [ [[MIN_SELECT]], [[THEN]] ], [ [[A]], [[ELSE]] ] 136; CHECK-NEXT: [[RES_2:%.*]] = load i32, ptr [[P]], align 4 137; CHECK-NEXT: ret i32 [[RES_2]] 138; 139entry: 140 br i1 %cond, label %then, label %else 141 142then: 143 %l.1 = load i32, ptr %c, align 4 144 %l.2 = load i32, ptr %b, align 4 145 %cmp.i.i.i = icmp ult i32 %l.1, %l.2 146 %min.select = select i1 %cmp.i.i.i, ptr %a, ptr %b 147 br label %exit 148 149else: 150 br label %exit 151 152exit: 153 %p = phi ptr [ %min.select, %then ], [ %a, %else ] 154 %res.2 = load i32, ptr %p, align 4 155 ret i32 %res.2 156} 157 158define i32 @test_pointer_phi_select_simp_no_load_for_select_op_2(ptr %a, ptr %b, ptr %c, i1 %cond) { 159; CHECK-LABEL: @test_pointer_phi_select_simp_no_load_for_select_op_2( 160; CHECK-NEXT: entry: 161; CHECK-NEXT: br i1 [[COND:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]] 162; CHECK: then: 163; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[A:%.*]], align 4 164; CHECK-NEXT: [[L_2:%.*]] = load i32, ptr [[C:%.*]], align 4 165; CHECK-NEXT: [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]] 166; CHECK-NEXT: [[MIN_SELECT:%.*]] = select i1 [[CMP_I_I_I]], ptr [[A]], ptr [[B:%.*]] 167; CHECK-NEXT: br label [[EXIT:%.*]] 168; CHECK: else: 169; CHECK-NEXT: br label [[EXIT]] 170; CHECK: exit: 171; CHECK-NEXT: [[P:%.*]] = phi ptr [ [[MIN_SELECT]], [[THEN]] ], [ [[A]], [[ELSE]] ] 172; CHECK-NEXT: [[RES_2:%.*]] = load i32, ptr [[P]], align 4 173; CHECK-NEXT: ret i32 [[RES_2]] 174; 175entry: 176 br i1 %cond, label %then, label %else 177 178then: 179 %l.1 = load i32, ptr %a, align 4 180 %l.2 = load i32, ptr %c, align 4 181 %cmp.i.i.i = icmp ult i32 %l.1, %l.2 182 %min.select = select i1 %cmp.i.i.i, ptr %a, ptr %b 183 br label %exit 184 185else: 186 br label %exit 187 188exit: 189 %p = phi ptr [ %min.select, %then ], [ %a, %else ] 190 %res.2 = load i32, ptr %p, align 4 191 ret i32 %res.2 192} 193 194define i32 @test_pointer_phi_select_simp_store_noclobber(ptr %a, ptr %b, ptr noalias %c, i1 %cond) { 195; CHECK-LABEL: @test_pointer_phi_select_simp_store_noclobber( 196; CHECK-NEXT: entry: 197; CHECK-NEXT: br i1 [[COND:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]] 198; CHECK: then: 199; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[A:%.*]], align 4 200; CHECK-NEXT: [[L_2:%.*]] = load i32, ptr [[B:%.*]], align 4 201; CHECK-NEXT: store i32 99, ptr [[C:%.*]], align 4 202; CHECK-NEXT: [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]] 203; CHECK-NEXT: [[TMP0:%.*]] = select i1 [[CMP_I_I_I]], i32 [[L_1]], i32 [[L_2]] 204; CHECK-NEXT: [[MIN_SELECT:%.*]] = select i1 [[CMP_I_I_I]], ptr [[A]], ptr [[B]] 205; CHECK-NEXT: br label [[EXIT:%.*]] 206; CHECK: else: 207; CHECK-NEXT: [[RES_2_PRE:%.*]] = load i32, ptr [[A]], align 4 208; CHECK-NEXT: br label [[EXIT]] 209; CHECK: exit: 210; CHECK-NEXT: [[RES_2:%.*]] = phi i32 [ [[TMP0]], [[THEN]] ], [ [[RES_2_PRE]], [[ELSE]] ] 211; CHECK-NEXT: [[P:%.*]] = phi ptr [ [[MIN_SELECT]], [[THEN]] ], [ [[A]], [[ELSE]] ] 212; CHECK-NEXT: ret i32 [[RES_2]] 213; 214entry: 215 br i1 %cond, label %then, label %else 216 217then: 218 %l.1 = load i32, ptr %a, align 4 219 %l.2 = load i32, ptr %b, align 4 220 store i32 99, ptr %c 221 %cmp.i.i.i = icmp ult i32 %l.1, %l.2 222 %min.select = select i1 %cmp.i.i.i, ptr %a, ptr %b 223 br label %exit 224 225else: 226 br label %exit 227 228exit: 229 %p = phi ptr [ %min.select, %then ], [ %a, %else ] 230 %res.2 = load i32, ptr %p, align 4 231 ret i32 %res.2 232} 233 234define i32 @test_pointer_phi_select_simp_store_clobber_1(ptr %a, ptr %b, ptr %c, i1 %cond) { 235; CHECK-LABEL: @test_pointer_phi_select_simp_store_clobber_1( 236; CHECK-NEXT: entry: 237; CHECK-NEXT: br i1 [[COND:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]] 238; CHECK: then: 239; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[A:%.*]], align 4 240; CHECK-NEXT: [[L_2:%.*]] = load i32, ptr [[B:%.*]], align 4 241; CHECK-NEXT: store i32 99, ptr [[C:%.*]], align 4 242; CHECK-NEXT: [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]] 243; CHECK-NEXT: [[MIN_SELECT:%.*]] = select i1 [[CMP_I_I_I]], ptr [[A]], ptr [[B]] 244; CHECK-NEXT: br label [[EXIT:%.*]] 245; CHECK: else: 246; CHECK-NEXT: br label [[EXIT]] 247; CHECK: exit: 248; CHECK-NEXT: [[P:%.*]] = phi ptr [ [[MIN_SELECT]], [[THEN]] ], [ [[A]], [[ELSE]] ] 249; CHECK-NEXT: [[RES_2:%.*]] = load i32, ptr [[P]], align 4 250; CHECK-NEXT: ret i32 [[RES_2]] 251; 252entry: 253 br i1 %cond, label %then, label %else 254 255then: 256 %l.1 = load i32, ptr %a, align 4 257 %l.2 = load i32, ptr %b, align 4 258 store i32 99, ptr %c 259 %cmp.i.i.i = icmp ult i32 %l.1, %l.2 260 %min.select = select i1 %cmp.i.i.i, ptr %a, ptr %b 261 br label %exit 262 263else: 264 br label %exit 265 266exit: 267 %p = phi ptr [ %min.select, %then ], [ %a, %else ] 268 %res.2 = load i32, ptr %p, align 4 269 ret i32 %res.2 270} 271 272define i32 @test_pointer_phi_select_simp_store_clobber_2(ptr %a, ptr %b, ptr %c, i1 %cond) { 273; CHECK-LABEL: @test_pointer_phi_select_simp_store_clobber_2( 274; CHECK-NEXT: entry: 275; CHECK-NEXT: br i1 [[COND:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]] 276; CHECK: then: 277; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[A:%.*]], align 4 278; CHECK-NEXT: store i32 99, ptr [[C:%.*]], align 4 279; CHECK-NEXT: [[L_2:%.*]] = load i32, ptr [[B:%.*]], align 4 280; CHECK-NEXT: [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]] 281; CHECK-NEXT: [[MIN_SELECT:%.*]] = select i1 [[CMP_I_I_I]], ptr [[A]], ptr [[B]] 282; CHECK-NEXT: br label [[EXIT:%.*]] 283; CHECK: else: 284; CHECK-NEXT: br label [[EXIT]] 285; CHECK: exit: 286; CHECK-NEXT: [[P:%.*]] = phi ptr [ [[MIN_SELECT]], [[THEN]] ], [ [[A]], [[ELSE]] ] 287; CHECK-NEXT: [[RES_2:%.*]] = load i32, ptr [[P]], align 4 288; CHECK-NEXT: ret i32 [[RES_2]] 289; 290entry: 291 br i1 %cond, label %then, label %else 292 293then: 294 %l.1 = load i32, ptr %a, align 4 295 store i32 99, ptr %c 296 %l.2 = load i32, ptr %b, align 4 297 %cmp.i.i.i = icmp ult i32 %l.1, %l.2 298 %min.select = select i1 %cmp.i.i.i, ptr %a, ptr %b 299 br label %exit 300 301else: 302 br label %exit 303 304exit: 305 %p = phi ptr [ %min.select, %then ], [ %a, %else ] 306 %res.2 = load i32, ptr %p, align 4 307 ret i32 %res.2 308} 309 310define i32 @test_pointer_phi_select_simp_store_clobber_3(ptr %a, ptr %b, ptr %c, i1 %cond) { 311; CHECK-LABEL: @test_pointer_phi_select_simp_store_clobber_3( 312; CHECK-NEXT: entry: 313; CHECK-NEXT: br i1 [[COND:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]] 314; CHECK: then: 315; CHECK-NEXT: store i32 99, ptr [[C:%.*]], align 4 316; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[A:%.*]], align 4 317; CHECK-NEXT: [[L_2:%.*]] = load i32, ptr [[B:%.*]], align 4 318; CHECK-NEXT: [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]] 319; CHECK-NEXT: [[TMP0:%.*]] = select i1 [[CMP_I_I_I]], i32 [[L_1]], i32 [[L_2]] 320; CHECK-NEXT: [[MIN_SELECT:%.*]] = select i1 [[CMP_I_I_I]], ptr [[A]], ptr [[B]] 321; CHECK-NEXT: br label [[EXIT:%.*]] 322; CHECK: else: 323; CHECK-NEXT: [[RES_2_PRE:%.*]] = load i32, ptr [[A]], align 4 324; CHECK-NEXT: br label [[EXIT]] 325; CHECK: exit: 326; CHECK-NEXT: [[RES_2:%.*]] = phi i32 [ [[TMP0]], [[THEN]] ], [ [[RES_2_PRE]], [[ELSE]] ] 327; CHECK-NEXT: [[P:%.*]] = phi ptr [ [[MIN_SELECT]], [[THEN]] ], [ [[A]], [[ELSE]] ] 328; CHECK-NEXT: ret i32 [[RES_2]] 329; 330entry: 331 br i1 %cond, label %then, label %else 332 333then: 334 store i32 99, ptr %c 335 %l.1 = load i32, ptr %a, align 4 336 %l.2 = load i32, ptr %b, align 4 337 %cmp.i.i.i = icmp ult i32 %l.1, %l.2 338 %min.select = select i1 %cmp.i.i.i, ptr %a, ptr %b 339 br label %exit 340 341else: 342 br label %exit 343 344exit: 345 %p = phi ptr [ %min.select, %then ], [ %a, %else ] 346 %res.2 = load i32, ptr %p, align 4 347 ret i32 %res.2 348} 349 350define i32 @test_pointer_phi_select_simp_store_clobber_4(ptr %a, ptr %b, ptr %c, i1 %cond) { 351; CHECK-LABEL: @test_pointer_phi_select_simp_store_clobber_4( 352; CHECK-NEXT: entry: 353; CHECK-NEXT: br i1 [[COND:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]] 354; CHECK: then: 355; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[A:%.*]], align 4 356; CHECK-NEXT: [[L_2:%.*]] = load i32, ptr [[B:%.*]], align 4 357; CHECK-NEXT: [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]] 358; CHECK-NEXT: [[MIN_SELECT:%.*]] = select i1 [[CMP_I_I_I]], ptr [[A]], ptr [[B]] 359; CHECK-NEXT: store i32 99, ptr [[C:%.*]], align 4 360; CHECK-NEXT: br label [[EXIT:%.*]] 361; CHECK: else: 362; CHECK-NEXT: br label [[EXIT]] 363; CHECK: exit: 364; CHECK-NEXT: [[P:%.*]] = phi ptr [ [[MIN_SELECT]], [[THEN]] ], [ [[A]], [[ELSE]] ] 365; CHECK-NEXT: [[RES_2:%.*]] = load i32, ptr [[P]], align 4 366; CHECK-NEXT: ret i32 [[RES_2]] 367; 368entry: 369 br i1 %cond, label %then, label %else 370 371then: 372 %l.1 = load i32, ptr %a, align 4 373 %l.2 = load i32, ptr %b, align 4 374 %cmp.i.i.i = icmp ult i32 %l.1, %l.2 375 %min.select = select i1 %cmp.i.i.i, ptr %a, ptr %b 376 store i32 99, ptr %c 377 br label %exit 378 379else: 380 br label %exit 381 382exit: 383 %p = phi ptr [ %min.select, %then ], [ %a, %else ] 384 %res.2 = load i32, ptr %p, align 4 385 ret i32 %res.2 386} 387 388define i32 @test_pointer_phi_select_simp_store_clobber_5(ptr %a, ptr %b, ptr %c, i1 %cond) { 389; CHECK-LABEL: @test_pointer_phi_select_simp_store_clobber_5( 390; CHECK-NEXT: entry: 391; CHECK-NEXT: br i1 [[COND:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]] 392; CHECK: then: 393; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[A:%.*]], align 4 394; CHECK-NEXT: [[L_2:%.*]] = load i32, ptr [[B:%.*]], align 4 395; CHECK-NEXT: [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]] 396; CHECK-NEXT: [[MIN_SELECT:%.*]] = select i1 [[CMP_I_I_I]], ptr [[A]], ptr [[B]] 397; CHECK-NEXT: br label [[EXIT:%.*]] 398; CHECK: else: 399; CHECK-NEXT: br label [[EXIT]] 400; CHECK: exit: 401; CHECK-NEXT: [[P:%.*]] = phi ptr [ [[MIN_SELECT]], [[THEN]] ], [ [[A]], [[ELSE]] ] 402; CHECK-NEXT: store i32 99, ptr [[C:%.*]], align 4 403; CHECK-NEXT: [[RES_2:%.*]] = load i32, ptr [[P]], align 4 404; CHECK-NEXT: ret i32 [[RES_2]] 405; 406entry: 407 br i1 %cond, label %then, label %else 408 409then: 410 %l.1 = load i32, ptr %a, align 4 411 %l.2 = load i32, ptr %b, align 4 412 %cmp.i.i.i = icmp ult i32 %l.1, %l.2 413 %min.select = select i1 %cmp.i.i.i, ptr %a, ptr %b 414 br label %exit 415 416else: 417 br label %exit 418 419exit: 420 %p = phi ptr [ %min.select, %then ], [ %a, %else ] 421 store i32 99, ptr %c 422 %res.2 = load i32, ptr %p, align 4 423 ret i32 %res.2 424} 425 426define i32 @test_pointer_phi_select_simp_store_clobber_6(ptr %a, ptr %b, ptr %c, i1 %cond) { 427; CHECK-LABEL: @test_pointer_phi_select_simp_store_clobber_6( 428; CHECK-NEXT: entry: 429; CHECK-NEXT: br i1 [[COND:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]] 430; CHECK: then: 431; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[A:%.*]], align 4 432; CHECK-NEXT: [[L_2:%.*]] = load i32, ptr [[B:%.*]], align 4 433; CHECK-NEXT: store i32 99, ptr [[C:%.*]], align 4 434; CHECK-NEXT: [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]] 435; CHECK-NEXT: [[MIN_SELECT:%.*]] = select i1 [[CMP_I_I_I]], ptr [[A]], ptr [[B]] 436; CHECK-NEXT: [[RES_0:%.*]] = load i32, ptr [[MIN_SELECT]], align 4 437; CHECK-NEXT: br label [[EXIT:%.*]] 438; CHECK: else: 439; CHECK-NEXT: [[RES_2_PRE:%.*]] = load i32, ptr [[A]], align 4 440; CHECK-NEXT: br label [[EXIT]] 441; CHECK: exit: 442; CHECK-NEXT: [[RES_2:%.*]] = phi i32 [ [[RES_0]], [[THEN]] ], [ [[RES_2_PRE]], [[ELSE]] ] 443; CHECK-NEXT: [[P:%.*]] = phi ptr [ [[MIN_SELECT]], [[THEN]] ], [ [[A]], [[ELSE]] ] 444; CHECK-NEXT: [[V:%.*]] = phi i32 [ [[RES_0]], [[THEN]] ], [ 10, [[ELSE]] ] 445; CHECK-NEXT: [[ADD:%.*]] = add i32 [[RES_2]], [[V]] 446; CHECK-NEXT: ret i32 [[RES_2]] 447; 448entry: 449 br i1 %cond, label %then, label %else 450 451then: 452 %l.1 = load i32, ptr %a, align 4 453 %l.2 = load i32, ptr %b, align 4 454 store i32 99, ptr %c 455 %cmp.i.i.i = icmp ult i32 %l.1, %l.2 456 %min.select = select i1 %cmp.i.i.i, ptr %a, ptr %b 457 %res.0 = load i32, ptr %min.select, align 4 458 br label %exit 459 460else: 461 br label %exit 462 463exit: 464 %p = phi ptr [ %min.select, %then ], [ %a, %else ] 465 %v = phi i32 [ %res.0, %then ], [ 10, %else ] 466 %res.2 = load i32, ptr %p, align 4 467 %add = add i32 %res.2, %v 468 ret i32 %res.2 469} 470 471define i32 @test_pointer_phi_select_simp_store_clobber_7(ptr %a, ptr %b, ptr %c, i1 %cond) { 472; CHECK-LABEL: @test_pointer_phi_select_simp_store_clobber_7( 473; CHECK-NEXT: entry: 474; CHECK-NEXT: br i1 [[COND:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]] 475; CHECK: then: 476; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[A:%.*]], align 4 477; CHECK-NEXT: [[L_2:%.*]] = load i32, ptr [[B:%.*]], align 4 478; CHECK-NEXT: store i32 99, ptr [[C:%.*]], align 4 479; CHECK-NEXT: [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]] 480; CHECK-NEXT: [[MIN_SELECT:%.*]] = select i1 [[CMP_I_I_I]], ptr [[A]], ptr [[B]] 481; CHECK-NEXT: [[RES_0:%.*]] = load i32, ptr [[A]], align 4 482; CHECK-NEXT: br label [[EXIT:%.*]] 483; CHECK: else: 484; CHECK-NEXT: br label [[EXIT]] 485; CHECK: exit: 486; CHECK-NEXT: [[P:%.*]] = phi ptr [ [[MIN_SELECT]], [[THEN]] ], [ [[A]], [[ELSE]] ] 487; CHECK-NEXT: [[V:%.*]] = phi i32 [ [[RES_0]], [[THEN]] ], [ 10, [[ELSE]] ] 488; CHECK-NEXT: [[RES_2:%.*]] = load i32, ptr [[P]], align 4 489; CHECK-NEXT: [[ADD:%.*]] = add i32 [[RES_2]], [[V]] 490; CHECK-NEXT: ret i32 [[RES_2]] 491; 492entry: 493 br i1 %cond, label %then, label %else 494 495then: 496 %l.1 = load i32, ptr %a, align 4 497 %l.2 = load i32, ptr %b, align 4 498 store i32 99, ptr %c 499 %cmp.i.i.i = icmp ult i32 %l.1, %l.2 500 %min.select = select i1 %cmp.i.i.i, ptr %a, ptr %b 501 %res.0 = load i32, ptr %a, align 4 502 br label %exit 503 504else: 505 br label %exit 506 507exit: 508 %p = phi ptr [ %min.select, %then ], [ %a, %else ] 509 %v = phi i32 [ %res.0, %then ], [ 10, %else ] 510 %res.2 = load i32, ptr %p, align 4 511 %add = add i32 %res.2, %v 512 ret i32 %res.2 513} 514 515define i32 @test_pointer_phi_select_simp_store_clobber_8(ptr %a, ptr %b, ptr %c, i1 %cond) { 516; CHECK-LABEL: @test_pointer_phi_select_simp_store_clobber_8( 517; CHECK-NEXT: entry: 518; CHECK-NEXT: br i1 [[COND:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]] 519; CHECK: then: 520; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[A:%.*]], align 4 521; CHECK-NEXT: [[L_2:%.*]] = load i32, ptr [[B:%.*]], align 4 522; CHECK-NEXT: store i32 99, ptr [[C:%.*]], align 4 523; CHECK-NEXT: [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]] 524; CHECK-NEXT: [[MIN_SELECT:%.*]] = select i1 [[CMP_I_I_I]], ptr [[A]], ptr [[B]] 525; CHECK-NEXT: [[RES_0:%.*]] = load i32, ptr [[B]], align 4 526; CHECK-NEXT: br label [[EXIT:%.*]] 527; CHECK: else: 528; CHECK-NEXT: br label [[EXIT]] 529; CHECK: exit: 530; CHECK-NEXT: [[P:%.*]] = phi ptr [ [[MIN_SELECT]], [[THEN]] ], [ [[A]], [[ELSE]] ] 531; CHECK-NEXT: [[V:%.*]] = phi i32 [ [[RES_0]], [[THEN]] ], [ 10, [[ELSE]] ] 532; CHECK-NEXT: [[RES_2:%.*]] = load i32, ptr [[P]], align 4 533; CHECK-NEXT: [[ADD:%.*]] = add i32 [[RES_2]], [[V]] 534; CHECK-NEXT: ret i32 [[RES_2]] 535; 536entry: 537 br i1 %cond, label %then, label %else 538 539then: 540 %l.1 = load i32, ptr %a, align 4 541 %l.2 = load i32, ptr %b, align 4 542 store i32 99, ptr %c 543 %cmp.i.i.i = icmp ult i32 %l.1, %l.2 544 %min.select = select i1 %cmp.i.i.i, ptr %a, ptr %b 545 %res.0 = load i32, ptr %b, align 4 546 br label %exit 547 548else: 549 br label %exit 550 551exit: 552 %p = phi ptr [ %min.select, %then ], [ %a, %else ] 553 %v = phi i32 [ %res.0, %then ], [ 10, %else ] 554 %res.2 = load i32, ptr %p, align 4 555 %add = add i32 %res.2, %v 556 ret i32 %res.2 557} 558 559define i32 @test_pointer_phi_select_simp_store_clobber_9(ptr %a, ptr %b, i1 %cond) { 560; CHECK-LABEL: @test_pointer_phi_select_simp_store_clobber_9( 561; CHECK-NEXT: entry: 562; CHECK-NEXT: br i1 [[COND:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]] 563; CHECK: then: 564; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[A:%.*]], align 4 565; CHECK-NEXT: [[L_2:%.*]] = load i32, ptr [[B:%.*]], align 4 566; CHECK-NEXT: store i32 99, ptr [[A]], align 4 567; CHECK-NEXT: [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]] 568; CHECK-NEXT: [[MIN_SELECT:%.*]] = select i1 [[CMP_I_I_I]], ptr [[A]], ptr [[B]] 569; CHECK-NEXT: [[RES_0:%.*]] = load i32, ptr [[B]], align 4 570; CHECK-NEXT: br label [[EXIT:%.*]] 571; CHECK: else: 572; CHECK-NEXT: br label [[EXIT]] 573; CHECK: exit: 574; CHECK-NEXT: [[P:%.*]] = phi ptr [ [[MIN_SELECT]], [[THEN]] ], [ [[A]], [[ELSE]] ] 575; CHECK-NEXT: [[V:%.*]] = phi i32 [ [[RES_0]], [[THEN]] ], [ 10, [[ELSE]] ] 576; CHECK-NEXT: [[RES_2:%.*]] = load i32, ptr [[P]], align 4 577; CHECK-NEXT: [[ADD:%.*]] = add i32 [[RES_2]], [[V]] 578; CHECK-NEXT: ret i32 [[RES_2]] 579; 580entry: 581 br i1 %cond, label %then, label %else 582 583then: 584 %l.1 = load i32, ptr %a, align 4 585 %l.2 = load i32, ptr %b, align 4 586 store i32 99, ptr %a 587 %cmp.i.i.i = icmp ult i32 %l.1, %l.2 588 %min.select = select i1 %cmp.i.i.i, ptr %a, ptr %b 589 %res.0 = load i32, ptr %b, align 4 590 br label %exit 591 592else: 593 br label %exit 594 595exit: 596 %p = phi ptr [ %min.select, %then ], [ %a, %else ] 597 %v = phi i32 [ %res.0, %then ], [ 10, %else ] 598 %res.2 = load i32, ptr %p, align 4 599 %add = add i32 %res.2, %v 600 ret i32 %res.2 601} 602 603define i32 @test_pointer_phi_select_simp_store_clobber_10(ptr %a, ptr %b, i1 %cond) { 604; CHECK-LABEL: @test_pointer_phi_select_simp_store_clobber_10( 605; CHECK-NEXT: entry: 606; CHECK-NEXT: br i1 [[COND:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]] 607; CHECK: then: 608; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[A:%.*]], align 4 609; CHECK-NEXT: store i32 99, ptr [[A]], align 4 610; CHECK-NEXT: [[L_2:%.*]] = load i32, ptr [[B:%.*]], align 4 611; CHECK-NEXT: [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]] 612; CHECK-NEXT: [[MIN_SELECT:%.*]] = select i1 [[CMP_I_I_I]], ptr [[A]], ptr [[B]] 613; CHECK-NEXT: br label [[EXIT:%.*]] 614; CHECK: else: 615; CHECK-NEXT: br label [[EXIT]] 616; CHECK: exit: 617; CHECK-NEXT: [[P:%.*]] = phi ptr [ [[MIN_SELECT]], [[THEN]] ], [ [[A]], [[ELSE]] ] 618; CHECK-NEXT: [[V:%.*]] = phi i32 [ [[L_2]], [[THEN]] ], [ 10, [[ELSE]] ] 619; CHECK-NEXT: [[RES_2:%.*]] = load i32, ptr [[P]], align 4 620; CHECK-NEXT: [[ADD:%.*]] = add i32 [[RES_2]], [[V]] 621; CHECK-NEXT: ret i32 [[RES_2]] 622; 623entry: 624 br i1 %cond, label %then, label %else 625 626then: 627 %l.1 = load i32, ptr %a, align 4 628 store i32 99, ptr %a 629 %l.2 = load i32, ptr %b, align 4 630 %cmp.i.i.i = icmp ult i32 %l.1, %l.2 631 %min.select = select i1 %cmp.i.i.i, ptr %a, ptr %b 632 %res.0 = load i32, ptr %b, align 4 633 br label %exit 634 635else: 636 br label %exit 637 638exit: 639 %p = phi ptr [ %min.select, %then ], [ %a, %else ] 640 %v = phi i32 [ %res.0, %then ], [ 10, %else ] 641 %res.2 = load i32, ptr %p, align 4 642 %add = add i32 %res.2, %v 643 ret i32 %res.2 644} 645 646define i32 @test_pointer_phi_select_simp_store_clobber_11(ptr %a, ptr %b, i1 %cond) { 647; CHECK-LABEL: @test_pointer_phi_select_simp_store_clobber_11( 648; CHECK-NEXT: entry: 649; CHECK-NEXT: br i1 [[COND:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]] 650; CHECK: then: 651; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[A:%.*]], align 4 652; CHECK-NEXT: [[L_2:%.*]] = load i32, ptr [[B:%.*]], align 4 653; CHECK-NEXT: store i32 99, ptr [[B]], align 4 654; CHECK-NEXT: [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]] 655; CHECK-NEXT: [[MIN_SELECT:%.*]] = select i1 [[CMP_I_I_I]], ptr [[A]], ptr [[B]] 656; CHECK-NEXT: br label [[EXIT:%.*]] 657; CHECK: else: 658; CHECK-NEXT: br label [[EXIT]] 659; CHECK: exit: 660; CHECK-NEXT: [[P:%.*]] = phi ptr [ [[MIN_SELECT]], [[THEN]] ], [ [[A]], [[ELSE]] ] 661; CHECK-NEXT: [[V:%.*]] = phi i32 [ 99, [[THEN]] ], [ 10, [[ELSE]] ] 662; CHECK-NEXT: [[RES_2:%.*]] = load i32, ptr [[P]], align 4 663; CHECK-NEXT: [[ADD:%.*]] = add i32 [[RES_2]], [[V]] 664; CHECK-NEXT: ret i32 [[RES_2]] 665; 666entry: 667 br i1 %cond, label %then, label %else 668 669then: 670 %l.1 = load i32, ptr %a, align 4 671 %l.2 = load i32, ptr %b, align 4 672 store i32 99, ptr %b 673 %cmp.i.i.i = icmp ult i32 %l.1, %l.2 674 %min.select = select i1 %cmp.i.i.i, ptr %a, ptr %b 675 %res.0 = load i32, ptr %b, align 4 676 br label %exit 677 678else: 679 br label %exit 680 681exit: 682 %p = phi ptr [ %min.select, %then ], [ %a, %else ] 683 %v = phi i32 [ %res.0, %then ], [ 10, %else ] 684 %res.2 = load i32, ptr %p, align 4 685 %add = add i32 %res.2, %v 686 ret i32 %res.2 687} 688 689define i32 @test_pointer_phi_select_simp_store_clobber_12(ptr %a, ptr %b, i1 %cond) { 690; CHECK-LABEL: @test_pointer_phi_select_simp_store_clobber_12( 691; CHECK-NEXT: entry: 692; CHECK-NEXT: br i1 [[COND:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]] 693; CHECK: then: 694; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[A:%.*]], align 4 695; CHECK-NEXT: store i32 99, ptr [[B:%.*]], align 4 696; CHECK-NEXT: [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], 99 697; CHECK-NEXT: [[MIN_SELECT:%.*]] = select i1 [[CMP_I_I_I]], ptr [[A]], ptr [[B]] 698; CHECK-NEXT: br label [[EXIT:%.*]] 699; CHECK: else: 700; CHECK-NEXT: br label [[EXIT]] 701; CHECK: exit: 702; CHECK-NEXT: [[P:%.*]] = phi ptr [ [[MIN_SELECT]], [[THEN]] ], [ [[A]], [[ELSE]] ] 703; CHECK-NEXT: [[V:%.*]] = phi i32 [ 99, [[THEN]] ], [ 10, [[ELSE]] ] 704; CHECK-NEXT: [[RES_2:%.*]] = load i32, ptr [[P]], align 4 705; CHECK-NEXT: [[ADD:%.*]] = add i32 [[RES_2]], [[V]] 706; CHECK-NEXT: ret i32 [[RES_2]] 707; 708entry: 709 br i1 %cond, label %then, label %else 710 711then: 712 %l.1 = load i32, ptr %a, align 4 713 store i32 99, ptr %b 714 %l.2 = load i32, ptr %b, align 4 715 %cmp.i.i.i = icmp ult i32 %l.1, %l.2 716 %min.select = select i1 %cmp.i.i.i, ptr %a, ptr %b 717 %res.0 = load i32, ptr %b, align 4 718 br label %exit 719 720else: 721 br label %exit 722 723exit: 724 %p = phi ptr [ %min.select, %then ], [ %a, %else ] 725 %v = phi i32 [ %res.0, %then ], [ 10, %else ] 726 %res.2 = load i32, ptr %p, align 4 727 %add = add i32 %res.2, %v 728 ret i32 %res.2 729} 730 731define i32 @test_pointer_phi_select_single_block_store(ptr %a, ptr %b) { 732; CHECK-LABEL: @test_pointer_phi_select_single_block_store( 733; CHECK-NEXT: entry: 734; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[A:%.*]], align 4 735; CHECK-NEXT: [[L_2:%.*]] = load i32, ptr [[B:%.*]], align 4 736; CHECK-NEXT: [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]] 737; CHECK-NEXT: [[TMP0:%.*]] = select i1 [[CMP_I_I_I]], i32 [[L_1]], i32 [[L_2]] 738; CHECK-NEXT: [[MIN_SELECT:%.*]] = select i1 [[CMP_I_I_I]], ptr [[A]], ptr [[B]] 739; CHECK-NEXT: ret i32 [[TMP0]] 740; 741entry: 742 %l.1 = load i32, ptr %a, align 4 743 %l.2 = load i32, ptr %b, align 4 744 %cmp.i.i.i = icmp ult i32 %l.1, %l.2 745 %min.select = select i1 %cmp.i.i.i, ptr %a, ptr %b 746 %res.0 = load i32, ptr %min.select, align 4 747 ret i32 %res.0 748} 749 750define i32 @test_pointer_phi_select_single_block_store_clobber_1(ptr %a, ptr %b, ptr %c) { 751; CHECK-LABEL: @test_pointer_phi_select_single_block_store_clobber_1( 752; CHECK-NEXT: entry: 753; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[A:%.*]], align 4 754; CHECK-NEXT: [[L_2:%.*]] = load i32, ptr [[B:%.*]], align 4 755; CHECK-NEXT: store i32 99, ptr [[C:%.*]], align 4 756; CHECK-NEXT: [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]] 757; CHECK-NEXT: [[MIN_SELECT:%.*]] = select i1 [[CMP_I_I_I]], ptr [[A]], ptr [[B]] 758; CHECK-NEXT: [[RES_0:%.*]] = load i32, ptr [[MIN_SELECT]], align 4 759; CHECK-NEXT: ret i32 [[RES_0]] 760; 761entry: 762 %l.1 = load i32, ptr %a, align 4 763 %l.2 = load i32, ptr %b, align 4 764 store i32 99, ptr %c 765 %cmp.i.i.i = icmp ult i32 %l.1, %l.2 766 %min.select = select i1 %cmp.i.i.i, ptr %a, ptr %b 767 %res.0 = load i32, ptr %min.select, align 4 768 ret i32 %res.0 769} 770 771define i32 @test_pointer_phi_select_single_block_store_clobber_2(ptr %a, ptr %b, ptr %c) { 772; CHECK-LABEL: @test_pointer_phi_select_single_block_store_clobber_2( 773; CHECK-NEXT: entry: 774; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[A:%.*]], align 4 775; CHECK-NEXT: [[L_2:%.*]] = load i32, ptr [[B:%.*]], align 4 776; CHECK-NEXT: [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]] 777; CHECK-NEXT: [[MIN_SELECT:%.*]] = select i1 [[CMP_I_I_I]], ptr [[A]], ptr [[B]] 778; CHECK-NEXT: store i32 99, ptr [[C:%.*]], align 4 779; CHECK-NEXT: [[RES_0:%.*]] = load i32, ptr [[MIN_SELECT]], align 4 780; CHECK-NEXT: ret i32 [[RES_0]] 781; 782entry: 783 %l.1 = load i32, ptr %a, align 4 784 %l.2 = load i32, ptr %b, align 4 785 %cmp.i.i.i = icmp ult i32 %l.1, %l.2 786 %min.select = select i1 %cmp.i.i.i, ptr %a, ptr %b 787 store i32 99, ptr %c 788 %res.0 = load i32, ptr %min.select, align 4 789 ret i32 %res.0 790} 791 792define i32 @test_pointer_phi_select_single_block_store_clobber_3(ptr %a, ptr %b, ptr %c) { 793; CHECK-LABEL: @test_pointer_phi_select_single_block_store_clobber_3( 794; CHECK-NEXT: entry: 795; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[A:%.*]], align 4 796; CHECK-NEXT: store i32 99, ptr [[C:%.*]], align 4 797; CHECK-NEXT: [[L_2:%.*]] = load i32, ptr [[B:%.*]], align 4 798; CHECK-NEXT: [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]] 799; CHECK-NEXT: [[MIN_SELECT:%.*]] = select i1 [[CMP_I_I_I]], ptr [[A]], ptr [[B]] 800; CHECK-NEXT: [[RES_0:%.*]] = load i32, ptr [[MIN_SELECT]], align 4 801; CHECK-NEXT: ret i32 [[RES_0]] 802; 803entry: 804 %l.1 = load i32, ptr %a, align 4 805 store i32 99, ptr %c 806 %l.2 = load i32, ptr %b, align 4 807 %cmp.i.i.i = icmp ult i32 %l.1, %l.2 808 %min.select = select i1 %cmp.i.i.i, ptr %a, ptr %b 809 %res.0 = load i32, ptr %min.select, align 4 810 ret i32 %res.0 811} 812 813define i32 @test_pointer_phi_select_single_block_store_after(ptr %a, ptr %b, ptr %c) { 814; CHECK-LABEL: @test_pointer_phi_select_single_block_store_after( 815; CHECK-NEXT: entry: 816; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[A:%.*]], align 4 817; CHECK-NEXT: [[L_2:%.*]] = load i32, ptr [[B:%.*]], align 4 818; CHECK-NEXT: [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]] 819; CHECK-NEXT: [[TMP0:%.*]] = select i1 [[CMP_I_I_I]], i32 [[L_1]], i32 [[L_2]] 820; CHECK-NEXT: [[MIN_SELECT:%.*]] = select i1 [[CMP_I_I_I]], ptr [[A]], ptr [[B]] 821; CHECK-NEXT: store i32 99, ptr [[C:%.*]], align 4 822; CHECK-NEXT: ret i32 [[TMP0]] 823; 824entry: 825 %l.1 = load i32, ptr %a, align 4 826 %l.2 = load i32, ptr %b, align 4 827 %cmp.i.i.i = icmp ult i32 %l.1, %l.2 828 %min.select = select i1 %cmp.i.i.i, ptr %a, ptr %b 829 %res.0 = load i32, ptr %min.select, align 4 830 store i32 99, ptr %c 831 ret i32 %res.0 832} 833 834define i32 @test_phi_select_index_non_local(ptr %A, i32 %N, i32 %i) { 835; CHECK-LABEL: @test_phi_select_index_non_local( 836; CHECK-NEXT: entry: 837; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[I:%.*]], [[N:%.*]] 838; CHECK-NEXT: br i1 [[CMP]], label [[LAND_LHS_TRUE:%.*]], label [[IF_END:%.*]] 839; CHECK: land.lhs.true: 840; CHECK-NEXT: [[IDXPROM:%.*]] = sext i32 [[I]] to i64 841; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[IDXPROM]] 842; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX]], align 4 843; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[I]], 1 844; CHECK-NEXT: [[IDXPROM1:%.*]] = sext i32 [[ADD]] to i64 845; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[IDXPROM1]] 846; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX2]], align 4 847; CHECK-NEXT: [[CMP3:%.*]] = icmp slt i32 [[TMP0]], [[TMP1]] 848; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[CMP3]], i32 [[ADD]], i32 [[I]] 849; CHECK-NEXT: br label [[IF_END]] 850; CHECK: if.end: 851; CHECK-NEXT: [[I_ADDR_0:%.*]] = phi i32 [ [[I]], [[ENTRY:%.*]] ], [ [[SPEC_SELECT]], [[LAND_LHS_TRUE]] ] 852; CHECK-NEXT: [[IDXPROM5:%.*]] = sext i32 [[I_ADDR_0]] to i64 853; CHECK-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[IDXPROM5]] 854; CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX6]], align 4 855; CHECK-NEXT: ret i32 [[TMP2]] 856; 857entry: 858 %cmp = icmp slt i32 %i, %N 859 br i1 %cmp, label %land.lhs.true, label %if.end 860 861land.lhs.true: 862 %idxprom = sext i32 %i to i64 863 %arrayidx = getelementptr inbounds i32, ptr %A, i64 %idxprom 864 %0 = load i32, ptr %arrayidx, align 4 865 %add = add nsw i32 %i, 1 866 %idxprom1 = sext i32 %add to i64 867 %arrayidx2 = getelementptr inbounds i32, ptr %A, i64 %idxprom1 868 %1 = load i32, ptr %arrayidx2, align 4 869 %cmp3 = icmp slt i32 %0, %1 870 %spec.select = select i1 %cmp3, i32 %add, i32 %i 871 br label %if.end 872 873if.end: 874 %i.addr.0 = phi i32 [ %i, %entry ], [ %spec.select, %land.lhs.true ] 875 %idxprom5 = sext i32 %i.addr.0 to i64 876 %arrayidx6 = getelementptr inbounds i32, ptr %A, i64 %idxprom5 877 %2 = load i32, ptr %arrayidx6, align 4 878 ret i32 %2 879} 880 881define i32 @test_phi_select_index_loop(ptr %A, i32 %N) { 882; CHECK-LABEL: @test_phi_select_index_loop( 883; CHECK-NEXT: entry: 884; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[N:%.*]], 1 885; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_COND_CLEANUP:%.*]] 886; CHECK: for.body.preheader: 887; CHECK-NEXT: br label [[FOR_BODY:%.*]] 888; CHECK: for.body: 889; CHECK-NEXT: [[IDX:%.*]] = phi i32 [ [[IDX_NEXT:%.*]], [[FOR_BODY]] ], [ 1, [[FOR_BODY_PREHEADER]] ] 890; CHECK-NEXT: [[RES:%.*]] = phi i32 [ [[SPEC_SELECT:%.*]], [[FOR_BODY]] ], [ 0, [[FOR_BODY_PREHEADER]] ] 891; CHECK-NEXT: [[IDXPROM:%.*]] = sext i32 [[IDX]] to i64 892; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[IDXPROM]] 893; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX]], align 4 894; CHECK-NEXT: [[IDXPROM1:%.*]] = sext i32 [[RES]] to i64 895; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[IDXPROM1]] 896; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX1]], align 4 897; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[TMP0]], [[TMP1]] 898; CHECK-NEXT: [[SPEC_SELECT]] = select i1 [[CMP1]], i32 [[IDX]], i32 [[RES]] 899; CHECK-NEXT: [[IDX_NEXT]] = add nsw i32 [[IDX]], 1 900; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i32 [[IDX_NEXT]], [[N]] 901; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]], label [[FOR_BODY]] 902; CHECK: for.cond.cleanup.loopexit: 903; CHECK-NEXT: br label [[FOR_COND_CLEANUP]] 904; CHECK: for.cond.cleanup: 905; CHECK-NEXT: [[RES_0_LCSSA:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[SPEC_SELECT]], [[FOR_COND_CLEANUP_LOOPEXIT]] ] 906; CHECK-NEXT: ret i32 [[RES_0_LCSSA]] 907; 908entry: 909 %cmp = icmp sgt i32 %N, 1 910 br i1 %cmp, label %for.body, label %for.cond.cleanup 911 912for.body: 913 %idx = phi i32 [ 1, %entry ], [ %idx.next, %for.body ] 914 %res = phi i32 [ 0, %entry ], [ %spec.select, %for.body ] 915 %idxprom = sext i32 %idx to i64 916 %arrayidx = getelementptr inbounds i32, ptr %A, i64 %idxprom 917 %0 = load i32, ptr %arrayidx, align 4 918 %idxprom1 = sext i32 %res to i64 919 %arrayidx1 = getelementptr inbounds i32, ptr %A, i64 %idxprom1 920 %1 = load i32, ptr %arrayidx1, align 4 921 %cmp1 = icmp slt i32 %0, %1 922 %spec.select = select i1 %cmp1, i32 %idx, i32 %res 923 %idx.next = add nsw i32 %idx, 1 924 %exitcond.not = icmp eq i32 %idx.next, %N 925 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body 926 927 for.cond.cleanup: 928 %res.0.lcssa = phi i32 [ 0, %entry ], [ %spec.select, %for.body ] 929 ret i32 %res.0.lcssa 930} 931