1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -passes=instcombine < %s -S | FileCheck %s 3 4define i8 @phi_ugt_high_bits(i8 %x) { 5; CHECK-LABEL: @phi_ugt_high_bits( 6; CHECK-NEXT: entry: 7; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[X:%.*]], -65 8; CHECK-NEXT: br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]] 9; CHECK: T: 10; CHECK-NEXT: ret i8 64 11; CHECK: F: 12; CHECK-NEXT: br label [[T]] 13; 14entry: 15 %cmp = icmp ugt i8 %x, 191 16 br i1 %cmp, label %T, label %F 17T: 18 %v = phi i8 [ %x, %entry], [-1, %F] 19 %r = and i8 %v, 64 20 ret i8 %r 21F: 22 br label %T 23} 24 25define i8 @phi_ult_low_bits(i8 %x) { 26; CHECK-LABEL: @phi_ult_low_bits( 27; CHECK-NEXT: entry: 28; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[X:%.*]], -64 29; CHECK-NEXT: br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]] 30; CHECK: T: 31; CHECK-NEXT: br label [[F]] 32; CHECK: F: 33; CHECK-NEXT: ret i8 64 34; 35entry: 36 %cmp = icmp ult i8 %x, 192 37 br i1 %cmp, label %T, label %F 38T: 39 br label %F 40F: 41 %v = phi i8 [ %x, %entry], [-1, %T] 42 %r = and i8 %v, 64 43 ret i8 %r 44} 45 46define i8 @phi_ugt_high_bits_fail(i8 %x) { 47; CHECK-LABEL: @phi_ugt_high_bits_fail( 48; CHECK-NEXT: entry: 49; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[X:%.*]], -66 50; CHECK-NEXT: br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]] 51; CHECK: T: 52; CHECK-NEXT: [[V:%.*]] = phi i8 [ [[X]], [[ENTRY:%.*]] ], [ -1, [[F]] ] 53; CHECK-NEXT: [[R:%.*]] = and i8 [[V]], 64 54; CHECK-NEXT: ret i8 [[R]] 55; CHECK: F: 56; CHECK-NEXT: br label [[T]] 57; 58entry: 59 %cmp = icmp ugt i8 %x, 190 60 br i1 %cmp, label %T, label %F 61T: 62 %v = phi i8 [ %x, %entry], [-1, %F] 63 %r = and i8 %v, 64 64 ret i8 %r 65F: 66 br label %T 67} 68 69define i8 @phi_uge_high_bits(i8 %x) { 70; CHECK-LABEL: @phi_uge_high_bits( 71; CHECK-NEXT: entry: 72; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[X:%.*]], -65 73; CHECK-NEXT: br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]] 74; CHECK: T: 75; CHECK-NEXT: ret i8 64 76; CHECK: F: 77; CHECK-NEXT: br label [[T]] 78; 79entry: 80 %cmp = icmp uge i8 %x, 192 81 br i1 %cmp, label %T, label %F 82T: 83 %v = phi i8 [ %x, %entry], [-1, %F] 84 %r = and i8 %v, 64 85 ret i8 %r 86F: 87 br label %T 88} 89 90define i8 @phi_uge_high_bits_fail(i8 %x) { 91; CHECK-LABEL: @phi_uge_high_bits_fail( 92; CHECK-NEXT: entry: 93; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[X:%.*]], 5 94; CHECK-NEXT: br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]] 95; CHECK: T: 96; CHECK-NEXT: [[V:%.*]] = phi i8 [ [[X]], [[ENTRY:%.*]] ], [ -1, [[F]] ] 97; CHECK-NEXT: [[R:%.*]] = and i8 [[V]], 1 98; CHECK-NEXT: ret i8 [[R]] 99; CHECK: F: 100; CHECK-NEXT: br label [[T]] 101; 102entry: 103 %cmp = icmp ugt i8 %x, 5 104 br i1 %cmp, label %T, label %F 105T: 106 %v = phi i8 [ %x, %entry], [-1, %F] 107 %r = and i8 %v, 1 108 ret i8 %r 109F: 110 br label %T 111} 112 113define i8 @phi_sge_high_bits(i8 %x) { 114; CHECK-LABEL: @phi_sge_high_bits( 115; CHECK-NEXT: entry: 116; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[X:%.*]], 95 117; CHECK-NEXT: br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]] 118; CHECK: T: 119; CHECK-NEXT: ret i8 96 120; CHECK: F: 121; CHECK-NEXT: br label [[T]] 122; 123entry: 124 %cmp = icmp sge i8 %x, 96 125 br i1 %cmp, label %T, label %F 126T: 127 %v = phi i8 [ %x, %entry], [-1, %F] 128 %r = and i8 %v, 96 129 ret i8 %r 130F: 131 br label %T 132} 133 134define i8 @phi_sge_high_bits_fail(i8 %x) { 135; CHECK-LABEL: @phi_sge_high_bits_fail( 136; CHECK-NEXT: entry: 137; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[X:%.*]], -2 138; CHECK-NEXT: br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]] 139; CHECK: T: 140; CHECK-NEXT: [[V:%.*]] = phi i8 [ [[X]], [[ENTRY:%.*]] ], [ -1, [[F]] ] 141; CHECK-NEXT: [[R:%.*]] = and i8 [[V]], 1 142; CHECK-NEXT: ret i8 [[R]] 143; CHECK: F: 144; CHECK-NEXT: br label [[T]] 145; 146entry: 147 %cmp = icmp sge i8 %x, -1 148 br i1 %cmp, label %T, label %F 149T: 150 %v = phi i8 [ %x, %entry], [-1, %F] 151 %r = and i8 %v, 1 152 ret i8 %r 153F: 154 br label %T 155} 156 157define i8 @phi_sgt_high_bits(i8 %x) { 158; CHECK-LABEL: @phi_sgt_high_bits( 159; CHECK-NEXT: entry: 160; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[X:%.*]], -1 161; CHECK-NEXT: br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]] 162; CHECK: T: 163; CHECK-NEXT: ret i8 0 164; CHECK: F: 165; CHECK-NEXT: br label [[T]] 166; 167entry: 168 %cmp = icmp sgt i8 %x, -1 169 br i1 %cmp, label %T, label %F 170T: 171 %v = phi i8 [ %x, %entry], [0, %F] 172 %r = and i8 %v, 128 173 ret i8 %r 174F: 175 br label %T 176} 177 178define i8 @phi_sgt_high_bits2(i8 %x) { 179; CHECK-LABEL: @phi_sgt_high_bits2( 180; CHECK-NEXT: entry: 181; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[X:%.*]], 63 182; CHECK-NEXT: br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]] 183; CHECK: T: 184; CHECK-NEXT: ret i8 64 185; CHECK: F: 186; CHECK-NEXT: br label [[T]] 187; 188entry: 189 %cmp = icmp sgt i8 %x, 63 190 br i1 %cmp, label %T, label %F 191T: 192 %v = phi i8 [ %x, %entry], [-1, %F] 193 %r = and i8 %v, 64 194 ret i8 %r 195F: 196 br label %T 197} 198 199define i8 @phi_sgt_high_bits_fail(i8 %x) { 200; CHECK-LABEL: @phi_sgt_high_bits_fail( 201; CHECK-NEXT: entry: 202; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[X:%.*]], 62 203; CHECK-NEXT: br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]] 204; CHECK: T: 205; CHECK-NEXT: [[V:%.*]] = phi i8 [ [[X]], [[ENTRY:%.*]] ], [ -1, [[F]] ] 206; CHECK-NEXT: [[R:%.*]] = and i8 [[V]], 64 207; CHECK-NEXT: ret i8 [[R]] 208; CHECK: F: 209; CHECK-NEXT: br label [[T]] 210; 211entry: 212 %cmp = icmp sgt i8 %x, 62 213 br i1 %cmp, label %T, label %F 214T: 215 %v = phi i8 [ %x, %entry], [-1, %F] 216 %r = and i8 %v, 64 217 ret i8 %r 218F: 219 br label %T 220} 221 222define i8 @phi_slt_high_bits(i8 %x) { 223; CHECK-LABEL: @phi_slt_high_bits( 224; CHECK-NEXT: entry: 225; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[X:%.*]], 0 226; CHECK-NEXT: br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]] 227; CHECK: T: 228; CHECK-NEXT: ret i8 -128 229; CHECK: F: 230; CHECK-NEXT: br label [[T]] 231; 232entry: 233 %cmp = icmp slt i8 %x, 0 234 br i1 %cmp, label %T, label %F 235T: 236 %v = phi i8 [ %x, %entry], [-1, %F] 237 %r = and i8 %v, 128 238 ret i8 %r 239F: 240 br label %T 241} 242 243define i8 @phi_slt_high_bits2(i8 %x) { 244; CHECK-LABEL: @phi_slt_high_bits2( 245; CHECK-NEXT: entry: 246; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[X:%.*]], -64 247; CHECK-NEXT: br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]] 248; CHECK: T: 249; CHECK-NEXT: ret i8 0 250; CHECK: F: 251; CHECK-NEXT: br label [[T]] 252; 253entry: 254 %cmp = icmp slt i8 %x, -64 255 br i1 %cmp, label %T, label %F 256T: 257 %v = phi i8 [ %x, %entry], [0, %F] 258 %r = and i8 %v, 64 259 ret i8 %r 260F: 261 br label %T 262} 263 264define i8 @phi_slt_high_bits_fail(i8 %x) { 265; CHECK-LABEL: @phi_slt_high_bits_fail( 266; CHECK-NEXT: entry: 267; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[X:%.*]], -63 268; CHECK-NEXT: br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]] 269; CHECK: T: 270; CHECK-NEXT: [[V:%.*]] = phi i8 [ [[X]], [[ENTRY:%.*]] ], [ 0, [[F]] ] 271; CHECK-NEXT: [[R:%.*]] = and i8 [[V]], 64 272; CHECK-NEXT: ret i8 [[R]] 273; CHECK: F: 274; CHECK-NEXT: br label [[T]] 275; 276entry: 277 %cmp = icmp slt i8 %x, -63 278 br i1 %cmp, label %T, label %F 279T: 280 %v = phi i8 [ %x, %entry], [0, %F] 281 %r = and i8 %v, 64 282 ret i8 %r 283F: 284 br label %T 285} 286 287define i8 @phi_sle_high_bits(i8 %x) { 288; CHECK-LABEL: @phi_sle_high_bits( 289; CHECK-NEXT: entry: 290; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[X:%.*]], -64 291; CHECK-NEXT: br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]] 292; CHECK: T: 293; CHECK-NEXT: ret i8 0 294; CHECK: F: 295; CHECK-NEXT: br label [[T]] 296; 297entry: 298 %cmp = icmp sle i8 %x, -65 299 br i1 %cmp, label %T, label %F 300T: 301 %v = phi i8 [ %x, %entry], [0, %F] 302 %r = and i8 %v, 64 303 ret i8 %r 304F: 305 br label %T 306} 307 308define i8 @phi_sle_low_bits(i8 %x) { 309; CHECK-LABEL: @phi_sle_low_bits( 310; CHECK-NEXT: entry: 311; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[X:%.*]], 65 312; CHECK-NEXT: br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]] 313; CHECK: T: 314; CHECK-NEXT: br label [[F]] 315; CHECK: F: 316; CHECK-NEXT: ret i8 64 317; 318entry: 319 %cmp = icmp sle i8 %x, 64 320 br i1 %cmp, label %T, label %F 321T: 322 br label %F 323F: 324 %v = phi i8 [ %x, %entry], [-1, %T] 325 %r = and i8 %v, 64 326 ret i8 %r 327} 328 329define i8 @phi_sle_high_bits_fail(i8 %x) { 330; CHECK-LABEL: @phi_sle_high_bits_fail( 331; CHECK-NEXT: entry: 332; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[X:%.*]], 1 333; CHECK-NEXT: br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]] 334; CHECK: T: 335; CHECK-NEXT: [[V:%.*]] = phi i8 [ [[X]], [[ENTRY:%.*]] ], [ -1, [[F]] ] 336; CHECK-NEXT: [[R:%.*]] = and i8 [[V]], -128 337; CHECK-NEXT: ret i8 [[R]] 338; CHECK: F: 339; CHECK-NEXT: br label [[T]] 340; 341entry: 342 %cmp = icmp sle i8 %x, 0 343 br i1 %cmp, label %T, label %F 344T: 345 %v = phi i8 [ %x, %entry], [-1, %F] 346 %r = and i8 %v, 128 347 ret i8 %r 348F: 349 br label %T 350} 351 352define i8 @phi_sle_high_bits_fail2(i8 %x) { 353; CHECK-LABEL: @phi_sle_high_bits_fail2( 354; CHECK-NEXT: entry: 355; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[X:%.*]], -63 356; CHECK-NEXT: br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]] 357; CHECK: T: 358; CHECK-NEXT: [[V:%.*]] = phi i8 [ [[X]], [[ENTRY:%.*]] ], [ -1, [[F]] ] 359; CHECK-NEXT: [[R:%.*]] = and i8 [[V]], 64 360; CHECK-NEXT: ret i8 [[R]] 361; CHECK: F: 362; CHECK-NEXT: br label [[T]] 363; 364entry: 365 %cmp = icmp sle i8 %x, -64 366 br i1 %cmp, label %T, label %F 367T: 368 %v = phi i8 [ %x, %entry], [-1, %F] 369 %r = and i8 %v, 64 370 ret i8 %r 371F: 372 br label %T 373} 374 375define i8 @phi_ugt_high_bits_and_known(i8 %xx) { 376; CHECK-LABEL: @phi_ugt_high_bits_and_known( 377; CHECK-NEXT: entry: 378; CHECK-NEXT: [[X:%.*]] = or i8 [[XX:%.*]], 1 379; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[XX]], -65 380; CHECK-NEXT: br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]] 381; CHECK: T: 382; CHECK-NEXT: [[V:%.*]] = phi i8 [ [[X]], [[ENTRY:%.*]] ], [ -1, [[F]] ] 383; CHECK-NEXT: [[R:%.*]] = and i8 [[V]], 65 384; CHECK-NEXT: ret i8 [[R]] 385; CHECK: F: 386; CHECK-NEXT: br label [[T]] 387; 388entry: 389 %x = or i8 %xx, 1 390 %cmp = icmp ugt i8 %x, 191 391 br i1 %cmp, label %T, label %F 392T: 393 %v = phi i8 [ %x, %entry], [-1, %F] 394 %r = and i8 %v, 65 395 ret i8 %r 396F: 397 br label %T 398} 399 400define i8 @phi_ugt_high_bits_and_known_todo_high_depths(i8 %xx, i8 %y, i8 %z) { 401; CHECK-LABEL: @phi_ugt_high_bits_and_known_todo_high_depths( 402; CHECK-NEXT: entry: 403; CHECK-NEXT: [[YY:%.*]] = and i8 [[Y:%.*]], -2 404; CHECK-NEXT: [[XXX:%.*]] = and i8 [[XX:%.*]], [[YY]] 405; CHECK-NEXT: [[ZZ:%.*]] = or i8 [[Z:%.*]], 1 406; CHECK-NEXT: [[X:%.*]] = add i8 [[XXX]], [[ZZ]] 407; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[X]], -65 408; CHECK-NEXT: br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]] 409; CHECK: T: 410; CHECK-NEXT: [[V:%.*]] = phi i8 [ [[X]], [[ENTRY:%.*]] ], [ -1, [[F]] ] 411; CHECK-NEXT: [[R:%.*]] = and i8 [[V]], 65 412; CHECK-NEXT: ret i8 [[R]] 413; CHECK: F: 414; CHECK-NEXT: br label [[T]] 415; 416entry: 417 %yy = and i8 %y, -2 418 %xxx = and i8 %xx, %yy 419 %zz = or i8 %z, 1 420 %x = add i8 %xxx, %zz 421 %cmp = icmp ugt i8 %x, 191 422 br i1 %cmp, label %T, label %F 423T: 424 %v = phi i8 [ %x, %entry], [-1, %F] 425 %r = and i8 %v, 65 426 ret i8 %r 427F: 428 br label %T 429} 430 431;Illustrate if 2 pointers are non-equal when one of them is a recursive GEP. 432;Cases which folds to a canonical icmp(ptr1, ptr2) 433define i1 @recursiveGEP_withPtrSub1(ptr %val1) { 434; CHECK-LABEL: @recursiveGEP_withPtrSub1( 435; CHECK-NEXT: entry: 436; CHECK-NEXT: br label [[WHILE_COND_I:%.*]] 437; CHECK: while.cond.i: 438; CHECK-NEXT: [[A_PN_I:%.*]] = phi ptr [ [[TEST_0_I:%.*]], [[WHILE_COND_I]] ], [ [[VAL1:%.*]], [[ENTRY:%.*]] ] 439; CHECK-NEXT: [[TEST_0_I]] = getelementptr inbounds nuw i8, ptr [[A_PN_I]], i64 1 440; CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[TEST_0_I]], align 2 441; CHECK-NEXT: [[CMP3_NOT_I:%.*]] = icmp eq i8 [[TMP0]], 0 442; CHECK-NEXT: br i1 [[CMP3_NOT_I]], label [[WHILE_END_I:%.*]], label [[WHILE_COND_I]] 443; CHECK: while.end.i: 444; CHECK-NEXT: ret i1 false 445; 446entry: 447 br label %while.cond.i 448 449while.cond.i: 450 %a.pn.i = phi ptr [ %test.0.i, %while.cond.i ], [ %val1, %entry ] 451 %test.0.i = getelementptr inbounds i8, ptr %a.pn.i, i64 1 452 %0 = load i8, ptr %test.0.i, align 2 453 %cmp3.not.i = icmp eq i8 %0, 0 454 br i1 %cmp3.not.i, label %while.end.i, label %while.cond.i 455 456while.end.i: 457 %sub.ptr.lhs.cast.i = ptrtoint ptr %test.0.i to i64 458 %sub.ptr.rhs.cast.i = ptrtoint ptr %val1 to i64 459 %sub.ptr.sub.i = sub i64 %sub.ptr.lhs.cast.i, %sub.ptr.rhs.cast.i 460 %bool = icmp eq i64 %sub.ptr.sub.i, 0 461 ret i1 %bool 462} 463 464define i1 @recursiveGEP_withPtrSub1_PhiOperandsCommuted(ptr %val1) { 465; CHECK-LABEL: @recursiveGEP_withPtrSub1_PhiOperandsCommuted( 466; CHECK-NEXT: entry: 467; CHECK-NEXT: br label [[WHILE_COND_I:%.*]] 468; CHECK: while.cond.i: 469; CHECK-NEXT: [[A_PN_I:%.*]] = phi ptr [ [[VAL1:%.*]], [[ENTRY:%.*]] ], [ [[TEST_0_I:%.*]], [[WHILE_COND_I]] ] 470; CHECK-NEXT: [[TEST_0_I]] = getelementptr inbounds nuw i8, ptr [[A_PN_I]], i64 1 471; CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[TEST_0_I]], align 2 472; CHECK-NEXT: [[CMP3_NOT_I:%.*]] = icmp eq i8 [[TMP0]], 0 473; CHECK-NEXT: br i1 [[CMP3_NOT_I]], label [[WHILE_END_I:%.*]], label [[WHILE_COND_I]] 474; CHECK: while.end.i: 475; CHECK-NEXT: ret i1 false 476; 477entry: 478 br label %while.cond.i 479 480while.cond.i: 481 %a.pn.i = phi ptr [ %val1, %entry ], [ %test.0.i, %while.cond.i ] 482 %test.0.i = getelementptr inbounds i8, ptr %a.pn.i, i64 1 483 %0 = load i8, ptr %test.0.i, align 2 484 %cmp3.not.i = icmp eq i8 %0, 0 485 br i1 %cmp3.not.i, label %while.end.i, label %while.cond.i 486 487while.end.i: 488 %sub.ptr.lhs.cast.i = ptrtoint ptr %test.0.i to i64 489 %sub.ptr.rhs.cast.i = ptrtoint ptr %val1 to i64 490 %sub.ptr.sub.i = sub i64 %sub.ptr.lhs.cast.i, %sub.ptr.rhs.cast.i 491 %bool = icmp eq i64 %sub.ptr.sub.i, 0 492 ret i1 %bool 493} 494 495define i1 @recursiveGEP_withPtrSub1_SubOperandsCommuted(ptr %val1) { 496; CHECK-LABEL: @recursiveGEP_withPtrSub1_SubOperandsCommuted( 497; CHECK-NEXT: entry: 498; CHECK-NEXT: br label [[WHILE_COND_I:%.*]] 499; CHECK: while.cond.i: 500; CHECK-NEXT: [[A_PN_I:%.*]] = phi ptr [ [[TEST_0_I:%.*]], [[WHILE_COND_I]] ], [ [[VAL1:%.*]], [[ENTRY:%.*]] ] 501; CHECK-NEXT: [[TEST_0_I]] = getelementptr inbounds nuw i8, ptr [[A_PN_I]], i64 1 502; CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[TEST_0_I]], align 2 503; CHECK-NEXT: [[CMP3_NOT_I:%.*]] = icmp eq i8 [[TMP0]], 0 504; CHECK-NEXT: br i1 [[CMP3_NOT_I]], label [[WHILE_END_I:%.*]], label [[WHILE_COND_I]] 505; CHECK: while.end.i: 506; CHECK-NEXT: ret i1 false 507; 508entry: 509 br label %while.cond.i 510 511while.cond.i: 512 %a.pn.i = phi ptr [ %test.0.i, %while.cond.i ], [ %val1, %entry ] 513 %test.0.i = getelementptr inbounds i8, ptr %a.pn.i, i64 1 514 %0 = load i8, ptr %test.0.i, align 2 515 %cmp3.not.i = icmp eq i8 %0, 0 516 br i1 %cmp3.not.i, label %while.end.i, label %while.cond.i 517 518while.end.i: 519 %sub.ptr.lhs.cast.i = ptrtoint ptr %test.0.i to i64 520 %sub.ptr.rhs.cast.i = ptrtoint ptr %val1 to i64 521 %sub.ptr.sub.i = sub i64 %sub.ptr.rhs.cast.i, %sub.ptr.lhs.cast.i 522 %bool = icmp eq i64 %sub.ptr.sub.i, 0 523 ret i1 %bool 524} 525 526define i1 @recursiveGEP_withPtrSub2(ptr %val1) { 527; CHECK-LABEL: @recursiveGEP_withPtrSub2( 528; CHECK-NEXT: entry: 529; CHECK-NEXT: br label [[WHILE_COND_I:%.*]] 530; CHECK: while.cond.i: 531; CHECK-NEXT: [[A_PN_I:%.*]] = phi ptr [ [[TEST_0_I:%.*]], [[WHILE_COND_I]] ], [ [[VAL1:%.*]], [[ENTRY:%.*]] ] 532; CHECK-NEXT: [[TEST_0_I]] = getelementptr inbounds i8, ptr [[A_PN_I]], i64 -1 533; CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[TEST_0_I]], align 2 534; CHECK-NEXT: [[CMP3_NOT_I:%.*]] = icmp eq i8 [[TMP0]], 0 535; CHECK-NEXT: br i1 [[CMP3_NOT_I]], label [[WHILE_END_I:%.*]], label [[WHILE_COND_I]] 536; CHECK: while.end.i: 537; CHECK-NEXT: ret i1 false 538; 539entry: 540 br label %while.cond.i 541 542while.cond.i: 543 %a.pn.i = phi ptr [ %test.0.i, %while.cond.i ], [ %val1, %entry ] 544 %test.0.i = getelementptr inbounds i8, ptr %a.pn.i, i64 -1 545 %0 = load i8, ptr %test.0.i, align 2 546 %cmp3.not.i = icmp eq i8 %0, 0 547 br i1 %cmp3.not.i, label %while.end.i, label %while.cond.i 548 549while.end.i: 550 %sub.ptr.lhs.cast.i = ptrtoint ptr %test.0.i to i64 551 %sub.ptr.rhs.cast.i = ptrtoint ptr %val1 to i64 552 %sub.ptr.sub.i = sub i64 %sub.ptr.lhs.cast.i, %sub.ptr.rhs.cast.i 553 %bool = icmp eq i64 %sub.ptr.sub.i, 0 554 ret i1 %bool 555} 556 557define i1 @recursiveGEP_withPtrSub3(ptr %val1) { 558; CHECK-LABEL: @recursiveGEP_withPtrSub3( 559; CHECK-NEXT: entry: 560; CHECK-NEXT: [[TEST_VAL1:%.*]] = getelementptr inbounds nuw i8, ptr [[VAL1:%.*]], i64 7 561; CHECK-NEXT: br label [[WHILE_COND_I:%.*]] 562; CHECK: while.cond.i: 563; CHECK-NEXT: [[A_PN_I:%.*]] = phi ptr [ [[TEST_0_I:%.*]], [[WHILE_COND_I]] ], [ [[TEST_VAL1]], [[ENTRY:%.*]] ] 564; CHECK-NEXT: [[TEST_0_I]] = getelementptr inbounds nuw i8, ptr [[A_PN_I]], i64 1 565; CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[TEST_0_I]], align 2 566; CHECK-NEXT: [[CMP3_NOT_I:%.*]] = icmp eq i8 [[TMP0]], 0 567; CHECK-NEXT: br i1 [[CMP3_NOT_I]], label [[WHILE_END_I:%.*]], label [[WHILE_COND_I]] 568; CHECK: while.end.i: 569; CHECK-NEXT: ret i1 false 570; 571entry: 572 %test.val1 = getelementptr inbounds i8, ptr %val1, i64 7 573 br label %while.cond.i 574 575while.cond.i: 576 %a.pn.i = phi ptr [ %test.0.i, %while.cond.i ], [ %test.val1, %entry ] 577 %test.0.i = getelementptr inbounds i8, ptr %a.pn.i, i64 1 578 %0 = load i8, ptr %test.0.i, align 2 579 %cmp3.not.i = icmp eq i8 %0, 0 580 br i1 %cmp3.not.i, label %while.end.i, label %while.cond.i 581 582while.end.i: 583 %sub.ptr.lhs.cast.i = ptrtoint ptr %test.0.i to i64 584 %1 = getelementptr inbounds i8, ptr %val1, i64 5 585 %sub.ptr.rhs.cast.i = ptrtoint ptr %1 to i64 586 %sub.ptr.sub.i = sub i64 %sub.ptr.lhs.cast.i, %sub.ptr.rhs.cast.i 587 %bool = icmp eq i64 %sub.ptr.sub.i, 0 588 ret i1 %bool 589} 590 591define i1 @recursiveGEP_withPtrSub1_notKnownNonEqual1(ptr %val1, i64 %val2) { 592; CHECK-LABEL: @recursiveGEP_withPtrSub1_notKnownNonEqual1( 593; CHECK-NEXT: entry: 594; CHECK-NEXT: br label [[WHILE_COND_I:%.*]] 595; CHECK: while.cond.i: 596; CHECK-NEXT: [[A_PN_I:%.*]] = phi ptr [ [[TEST_0_I:%.*]], [[WHILE_COND_I]] ], [ [[VAL1:%.*]], [[ENTRY:%.*]] ] 597; CHECK-NEXT: [[TEST_0_I]] = getelementptr inbounds nuw i8, ptr [[A_PN_I]], i64 1 598; CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[TEST_0_I]], align 2 599; CHECK-NEXT: [[CMP3_NOT_I:%.*]] = icmp eq i8 [[TMP0]], 0 600; CHECK-NEXT: br i1 [[CMP3_NOT_I]], label [[WHILE_END_I:%.*]], label [[WHILE_COND_I]] 601; CHECK: while.end.i: 602; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[VAL1]], i64 [[VAL2:%.*]] 603; CHECK-NEXT: [[BOOL:%.*]] = icmp eq ptr [[TEST_0_I]], [[TMP1]] 604; CHECK-NEXT: ret i1 [[BOOL]] 605; 606entry: 607 br label %while.cond.i 608 609while.cond.i: 610 %a.pn.i = phi ptr [ %test.0.i, %while.cond.i ], [ %val1, %entry ] 611 %test.0.i = getelementptr inbounds i8, ptr %a.pn.i, i64 1 612 %0 = load i8, ptr %test.0.i, align 2 613 %cmp3.not.i = icmp eq i8 %0, 0 614 br i1 %cmp3.not.i, label %while.end.i, label %while.cond.i 615 616while.end.i: 617 %sub.ptr.lhs.cast.i = ptrtoint ptr %test.0.i to i64 618 %1 = getelementptr inbounds i8, ptr %val1, i64 %val2 619 %sub.ptr.rhs.cast.i = ptrtoint ptr %1 to i64 620 %sub.ptr.sub.i = sub i64 %sub.ptr.lhs.cast.i, %sub.ptr.rhs.cast.i 621 %bool = icmp eq i64 %sub.ptr.sub.i, 0 622 ret i1 %bool 623} 624 625define i1 @recursiveGEP_withPtrSub1_notKnownNonEqual2(ptr %val1) { 626; CHECK-LABEL: @recursiveGEP_withPtrSub1_notKnownNonEqual2( 627; CHECK-NEXT: entry: 628; CHECK-NEXT: [[TEST_VAL1:%.*]] = getelementptr inbounds i8, ptr [[VAL1:%.*]], i64 -1 629; CHECK-NEXT: br label [[WHILE_COND_I:%.*]] 630; CHECK: while.cond.i: 631; CHECK-NEXT: [[A_PN_I:%.*]] = phi ptr [ [[TEST_0_I:%.*]], [[WHILE_COND_I]] ], [ [[TEST_VAL1]], [[ENTRY:%.*]] ] 632; CHECK-NEXT: [[TEST_0_I]] = getelementptr inbounds nuw i8, ptr [[A_PN_I]], i64 1 633; CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[TEST_0_I]], align 2 634; CHECK-NEXT: [[CMP3_NOT_I:%.*]] = icmp eq i8 [[TMP0]], 0 635; CHECK-NEXT: br i1 [[CMP3_NOT_I]], label [[WHILE_END_I:%.*]], label [[WHILE_COND_I]] 636; CHECK: while.end.i: 637; CHECK-NEXT: [[BOOL:%.*]] = icmp eq ptr [[TEST_0_I]], [[VAL1]] 638; CHECK-NEXT: ret i1 [[BOOL]] 639; 640entry: 641 %test.val1 = getelementptr inbounds i8, ptr %val1, i64 -1 642 br label %while.cond.i 643 644while.cond.i: 645 %a.pn.i = phi ptr [ %test.0.i, %while.cond.i ], [ %test.val1, %entry ] 646 %test.0.i = getelementptr inbounds i8, ptr %a.pn.i, i64 1 647 %0 = load i8, ptr %test.0.i, align 2 648 %cmp3.not.i = icmp eq i8 %0, 0 649 br i1 %cmp3.not.i, label %while.end.i, label %while.cond.i 650 651while.end.i: 652 %sub.ptr.lhs.cast.i = ptrtoint ptr %test.0.i to i64 653 %sub.ptr.rhs.cast.i = ptrtoint ptr %val1 to i64 654 %sub.ptr.sub.i = sub i64 %sub.ptr.lhs.cast.i, %sub.ptr.rhs.cast.i 655 %bool = icmp eq i64 %sub.ptr.sub.i, 0 656 ret i1 %bool 657} 658 659define i1 @recursiveGEP_withPtrSub1_notKnownNonEqual3(ptr %val1) { 660; CHECK-LABEL: @recursiveGEP_withPtrSub1_notKnownNonEqual3( 661; CHECK-NEXT: entry: 662; CHECK-NEXT: [[TEST_VAL1:%.*]] = getelementptr inbounds nuw i8, ptr [[VAL1:%.*]], i64 5 663; CHECK-NEXT: br label [[WHILE_COND_I:%.*]] 664; CHECK: while.cond.i: 665; CHECK-NEXT: [[A_PN_I:%.*]] = phi ptr [ [[TEST_0_I:%.*]], [[WHILE_COND_I]] ], [ [[TEST_VAL1]], [[ENTRY:%.*]] ] 666; CHECK-NEXT: [[TEST_0_I]] = getelementptr inbounds i8, ptr [[A_PN_I]], i64 -1 667; CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[TEST_0_I]], align 2 668; CHECK-NEXT: [[CMP3_NOT_I:%.*]] = icmp eq i8 [[TMP0]], 0 669; CHECK-NEXT: br i1 [[CMP3_NOT_I]], label [[WHILE_END_I:%.*]], label [[WHILE_COND_I]] 670; CHECK: while.end.i: 671; CHECK-NEXT: [[BOOL:%.*]] = icmp eq ptr [[TEST_0_I]], [[VAL1]] 672; CHECK-NEXT: ret i1 [[BOOL]] 673; 674entry: 675 %test.val1 = getelementptr inbounds i8, ptr %val1, i64 5 676 br label %while.cond.i 677 678while.cond.i: 679 %a.pn.i = phi ptr [ %test.0.i, %while.cond.i ], [ %test.val1, %entry ] 680 %test.0.i = getelementptr inbounds i8, ptr %a.pn.i, i64 -1 681 %0 = load i8, ptr %test.0.i, align 2 682 %cmp3.not.i = icmp eq i8 %0, 0 683 br i1 %cmp3.not.i, label %while.end.i, label %while.cond.i 684 685while.end.i: 686 %sub.ptr.lhs.cast.i = ptrtoint ptr %test.0.i to i64 687 %sub.ptr.rhs.cast.i = ptrtoint ptr %val1 to i64 688 %sub.ptr.sub.i = sub i64 %sub.ptr.lhs.cast.i, %sub.ptr.rhs.cast.i 689 %bool = icmp eq i64 %sub.ptr.sub.i, 0 690 ret i1 %bool 691} 692 693define i1 @recursiveGEP_withPtrSub_maybeZero(ptr %val1) { 694; CHECK-LABEL: @recursiveGEP_withPtrSub_maybeZero( 695; CHECK-NEXT: entry: 696; CHECK-NEXT: br label [[WHILE_COND_I:%.*]] 697; CHECK: while.cond.i: 698; CHECK-NEXT: [[A_PN_I:%.*]] = phi ptr [ [[TEST_0_I:%.*]], [[WHILE_COND_I]] ], [ [[VAL1:%.*]], [[ENTRY:%.*]] ] 699; CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[A_PN_I]], align 2 700; CHECK-NEXT: [[TEST_0_I]] = getelementptr inbounds nuw i8, ptr [[A_PN_I]], i64 1 701; CHECK-NEXT: [[CMP3_NOT_I:%.*]] = icmp eq i8 [[TMP0]], 0 702; CHECK-NEXT: br i1 [[CMP3_NOT_I]], label [[WHILE_END_I:%.*]], label [[WHILE_COND_I]] 703; CHECK: while.end.i: 704; CHECK-NEXT: [[BOOL:%.*]] = icmp eq ptr [[A_PN_I]], [[VAL1]] 705; CHECK-NEXT: ret i1 [[BOOL]] 706; 707entry: 708 br label %while.cond.i 709 710while.cond.i: 711 %a.pn.i = phi ptr [ %test.0.i, %while.cond.i ], [ %val1, %entry ] 712 %0 = load i8, ptr %a.pn.i, align 2 713 %test.0.i = getelementptr inbounds i8, ptr %a.pn.i, i64 1 714 %cmp3.not.i = icmp eq i8 %0, 0 715 br i1 %cmp3.not.i, label %while.end.i, label %while.cond.i 716 717while.end.i: 718 %sub.ptr.lhs.cast.i = ptrtoint ptr %a.pn.i to i64 719 %sub.ptr.rhs.cast.i = ptrtoint ptr %val1 to i64 720 %sub.ptr.sub.i = sub i64 %sub.ptr.lhs.cast.i, %sub.ptr.rhs.cast.i 721 %bool = icmp eq i64 %sub.ptr.sub.i, 0 722 ret i1 %bool 723} 724 725;Non-inbounds test. 726;Test where Step is non-inbound. 727define i1 @recursiveGEP_withPtrSub_noninboundStep1(ptr %val1) { 728; CHECK-LABEL: @recursiveGEP_withPtrSub_noninboundStep1( 729; CHECK-NEXT: entry: 730; CHECK-NEXT: br label [[WHILE_COND_I:%.*]] 731; CHECK: while.cond.i: 732; CHECK-NEXT: [[A_PN_I:%.*]] = phi ptr [ [[TEST_0_I:%.*]], [[WHILE_COND_I]] ], [ [[VAL1:%.*]], [[ENTRY:%.*]] ] 733; CHECK-NEXT: [[TEST_0_I]] = getelementptr i8, ptr [[A_PN_I]], i64 1 734; CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[TEST_0_I]], align 2 735; CHECK-NEXT: [[CMP3_NOT_I:%.*]] = icmp eq i8 [[TMP0]], 0 736; CHECK-NEXT: br i1 [[CMP3_NOT_I]], label [[WHILE_END_I:%.*]], label [[WHILE_COND_I]] 737; CHECK: while.end.i: 738; CHECK-NEXT: [[BOOL:%.*]] = icmp eq ptr [[TEST_0_I]], [[VAL1]] 739; CHECK-NEXT: ret i1 [[BOOL]] 740; 741entry: 742 br label %while.cond.i 743 744while.cond.i: 745 %a.pn.i = phi ptr [ %test.0.i, %while.cond.i ], [ %val1, %entry ] 746 %test.0.i = getelementptr i8, ptr %a.pn.i, i64 1 747 %0 = load i8, ptr %test.0.i, align 2 748 %cmp3.not.i = icmp eq i8 %0, 0 749 br i1 %cmp3.not.i, label %while.end.i, label %while.cond.i 750 751while.end.i: 752 %sub.ptr.lhs.cast.i = ptrtoint ptr %test.0.i to i64 753 %sub.ptr.rhs.cast.i = ptrtoint ptr %val1 to i64 754 %sub.ptr.sub.i = sub i64 %sub.ptr.lhs.cast.i, %sub.ptr.rhs.cast.i 755 %bool = icmp eq i64 %sub.ptr.sub.i, 0 756 ret i1 %bool 757} 758 759define i1 @recursiveGEP_withPtrSub_noninboundStep2(ptr %val1) { 760; CHECK-LABEL: @recursiveGEP_withPtrSub_noninboundStep2( 761; CHECK-NEXT: entry: 762; CHECK-NEXT: br label [[WHILE_COND_I:%.*]] 763; CHECK: while.cond.i: 764; CHECK-NEXT: [[A_PN_I:%.*]] = phi ptr [ [[TEST_0_I:%.*]], [[WHILE_COND_I]] ], [ [[VAL1:%.*]], [[ENTRY:%.*]] ] 765; CHECK-NEXT: [[TEST_0_I]] = getelementptr i8, ptr [[A_PN_I]], i64 -1 766; CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[TEST_0_I]], align 2 767; CHECK-NEXT: [[CMP3_NOT_I:%.*]] = icmp eq i8 [[TMP0]], 0 768; CHECK-NEXT: br i1 [[CMP3_NOT_I]], label [[WHILE_END_I:%.*]], label [[WHILE_COND_I]] 769; CHECK: while.end.i: 770; CHECK-NEXT: [[BOOL:%.*]] = icmp eq ptr [[TEST_0_I]], [[VAL1]] 771; CHECK-NEXT: ret i1 [[BOOL]] 772; 773entry: 774 br label %while.cond.i 775 776while.cond.i: 777 %a.pn.i = phi ptr [ %test.0.i, %while.cond.i ], [ %val1, %entry ] 778 %test.0.i = getelementptr i8, ptr %a.pn.i, i64 -1 779 %0 = load i8, ptr %test.0.i, align 2 780 %cmp3.not.i = icmp eq i8 %0, 0 781 br i1 %cmp3.not.i, label %while.end.i, label %while.cond.i 782 783while.end.i: 784 %sub.ptr.lhs.cast.i = ptrtoint ptr %test.0.i to i64 785 %sub.ptr.rhs.cast.i = ptrtoint ptr %val1 to i64 786 %sub.ptr.sub.i = sub i64 %sub.ptr.lhs.cast.i, %sub.ptr.rhs.cast.i 787 %bool = icmp eq i64 %sub.ptr.sub.i, 0 788 ret i1 %bool 789} 790 791;Test where Step and GEP B are non-inbound. 792define i1 @recursiveGEP_withPtrSub_noninboundStepAndB(ptr %val1) { 793; CHECK-LABEL: @recursiveGEP_withPtrSub_noninboundStepAndB( 794; CHECK-NEXT: entry: 795; CHECK-NEXT: [[TEST:%.*]] = getelementptr inbounds nuw i8, ptr [[VAL1:%.*]], i64 2 796; CHECK-NEXT: br label [[WHILE_COND_I:%.*]] 797; CHECK: while.cond.i: 798; CHECK-NEXT: [[A_PN_I:%.*]] = phi ptr [ [[TEST_0_I:%.*]], [[WHILE_COND_I]] ], [ [[TEST]], [[ENTRY:%.*]] ] 799; CHECK-NEXT: [[TEST_0_I]] = getelementptr i8, ptr [[A_PN_I]], i64 1 800; CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[TEST_0_I]], align 2 801; CHECK-NEXT: [[CMP3_NOT_I:%.*]] = icmp eq i8 [[TMP0]], 0 802; CHECK-NEXT: br i1 [[CMP3_NOT_I]], label [[WHILE_END_I:%.*]], label [[WHILE_COND_I]] 803; CHECK: while.end.i: 804; CHECK-NEXT: [[BOOL:%.*]] = icmp eq ptr [[A_PN_I]], [[VAL1]] 805; CHECK-NEXT: ret i1 [[BOOL]] 806; 807entry: 808 %test = getelementptr inbounds i8, ptr %val1, i64 2 809 br label %while.cond.i 810 811while.cond.i: 812 %a.pn.i = phi ptr [ %test.0.i, %while.cond.i ], [ %test, %entry ] 813 %test.0.i = getelementptr i8, ptr %a.pn.i, i64 1 814 %0 = load i8, ptr %test.0.i, align 2 815 %cmp3.not.i = icmp eq i8 %0, 0 816 br i1 %cmp3.not.i, label %while.end.i, label %while.cond.i 817 818while.end.i: 819 %sub.ptr.lhs.cast.i = ptrtoint ptr %test.0.i to i64 820 %test.1.i = getelementptr i8, ptr %val1, i64 1 821 %sub.ptr.rhs.cast.i = ptrtoint ptr %test.1.i to i64 822 %sub.ptr.sub.i = sub i64 %sub.ptr.lhs.cast.i, %sub.ptr.rhs.cast.i 823 %bool = icmp eq i64 %sub.ptr.sub.i, 0 824 ret i1 %bool 825} 826 827;Test where Start and Step are non-inbound. 828define i1 @recursiveGEP_withPtrSub_noninboundStartAndStep(ptr %val1) { 829; CHECK-LABEL: @recursiveGEP_withPtrSub_noninboundStartAndStep( 830; CHECK-NEXT: entry: 831; CHECK-NEXT: [[TEST:%.*]] = getelementptr i8, ptr [[VAL1:%.*]], i64 1 832; CHECK-NEXT: br label [[WHILE_COND_I:%.*]] 833; CHECK: while.cond.i: 834; CHECK-NEXT: [[A_PN_I:%.*]] = phi ptr [ [[TEST_0_I:%.*]], [[WHILE_COND_I]] ], [ [[TEST]], [[ENTRY:%.*]] ] 835; CHECK-NEXT: [[TEST_0_I]] = getelementptr i8, ptr [[A_PN_I]], i64 1 836; CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[TEST_0_I]], align 2 837; CHECK-NEXT: [[CMP3_NOT_I:%.*]] = icmp eq i8 [[TMP0]], 0 838; CHECK-NEXT: br i1 [[CMP3_NOT_I]], label [[WHILE_END_I:%.*]], label [[WHILE_COND_I]] 839; CHECK: while.end.i: 840; CHECK-NEXT: [[BOOL:%.*]] = icmp eq ptr [[TEST_0_I]], [[VAL1]] 841; CHECK-NEXT: ret i1 [[BOOL]] 842; 843entry: 844 %test = getelementptr i8, ptr %val1, i64 1 845 br label %while.cond.i 846 847while.cond.i: 848 %a.pn.i = phi ptr [ %test.0.i, %while.cond.i ], [ %test, %entry ] 849 %test.0.i = getelementptr i8, ptr %a.pn.i, i64 1 850 %0 = load i8, ptr %test.0.i, align 2 851 %cmp3.not.i = icmp eq i8 %0, 0 852 br i1 %cmp3.not.i, label %while.end.i, label %while.cond.i 853 854while.end.i: 855 %sub.ptr.lhs.cast.i = ptrtoint ptr %test.0.i to i64 856 %sub.ptr.rhs.cast.i = ptrtoint ptr %val1 to i64 857 %sub.ptr.sub.i = sub i64 %sub.ptr.lhs.cast.i, %sub.ptr.rhs.cast.i 858 %bool = icmp eq i64 %sub.ptr.sub.i, 0 859 ret i1 %bool 860} 861 862;Test where Start and GEP B are non-inbounds pointer with same definition. 863define i1 @recursiveGEP_withPtrSub_noninboundSameDefStartAndB(ptr %val1) { 864; CHECK-LABEL: @recursiveGEP_withPtrSub_noninboundSameDefStartAndB( 865; CHECK-NEXT: entry: 866; CHECK-NEXT: [[TEST:%.*]] = getelementptr i8, ptr [[VAL1:%.*]], i64 1 867; CHECK-NEXT: br label [[WHILE_COND_I:%.*]] 868; CHECK: while.cond.i: 869; CHECK-NEXT: [[A_PN_I:%.*]] = phi ptr [ [[TEST_0_I:%.*]], [[WHILE_COND_I]] ], [ [[TEST]], [[ENTRY:%.*]] ] 870; CHECK-NEXT: [[TEST_0_I]] = getelementptr inbounds nuw i8, ptr [[A_PN_I]], i64 1 871; CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[TEST_0_I]], align 2 872; CHECK-NEXT: [[CMP3_NOT_I:%.*]] = icmp eq i8 [[TMP0]], 0 873; CHECK-NEXT: br i1 [[CMP3_NOT_I]], label [[WHILE_END_I:%.*]], label [[WHILE_COND_I]] 874; CHECK: while.end.i: 875; CHECK-NEXT: [[BOOL:%.*]] = icmp eq ptr [[A_PN_I]], [[VAL1]] 876; CHECK-NEXT: ret i1 [[BOOL]] 877; 878entry: 879 %test = getelementptr i8, ptr %val1, i64 1 880 br label %while.cond.i 881 882while.cond.i: 883 %a.pn.i = phi ptr [ %test.0.i, %while.cond.i ], [ %test, %entry ] 884 %test.0.i = getelementptr inbounds i8, ptr %a.pn.i, i64 1 885 %0 = load i8, ptr %test.0.i, align 2 886 %cmp3.not.i = icmp eq i8 %0, 0 887 br i1 %cmp3.not.i, label %while.end.i, label %while.cond.i 888 889while.end.i: 890 %sub.ptr.lhs.cast.i = ptrtoint ptr %test.0.i to i64 891 %test2 = getelementptr i8, ptr %val1, i64 1 892 %sub.ptr.rhs.cast.i = ptrtoint ptr %test2 to i64 893 %sub.ptr.sub.i = sub i64 %sub.ptr.lhs.cast.i, %sub.ptr.rhs.cast.i 894 %bool = icmp eq i64 %sub.ptr.sub.i, 0 895 ret i1 %bool 896} 897 898;Test where Start and GEP B are non-inbounds and exactly same pointers. 899define i1 @recursiveGEP_withPtrSub_noninboundSameStartAndB(ptr %val1) { 900; CHECK-LABEL: @recursiveGEP_withPtrSub_noninboundSameStartAndB( 901; CHECK-NEXT: entry: 902; CHECK-NEXT: [[TEST:%.*]] = getelementptr i8, ptr [[VAL1:%.*]], i64 1 903; CHECK-NEXT: br label [[WHILE_COND_I:%.*]] 904; CHECK: while.cond.i: 905; CHECK-NEXT: [[A_PN_I:%.*]] = phi ptr [ [[TEST_0_I:%.*]], [[WHILE_COND_I]] ], [ [[TEST]], [[ENTRY:%.*]] ] 906; CHECK-NEXT: [[TEST_0_I]] = getelementptr inbounds nuw i8, ptr [[A_PN_I]], i64 1 907; CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[TEST_0_I]], align 2 908; CHECK-NEXT: [[CMP3_NOT_I:%.*]] = icmp eq i8 [[TMP0]], 0 909; CHECK-NEXT: br i1 [[CMP3_NOT_I]], label [[WHILE_END_I:%.*]], label [[WHILE_COND_I]] 910; CHECK: while.end.i: 911; CHECK-NEXT: ret i1 false 912; 913entry: 914 %test = getelementptr i8, ptr %val1, i64 1 915 br label %while.cond.i 916 917while.cond.i: 918 %a.pn.i = phi ptr [ %test.0.i, %while.cond.i ], [ %test, %entry ] 919 %test.0.i = getelementptr inbounds i8, ptr %a.pn.i, i64 1 920 %0 = load i8, ptr %test.0.i, align 2 921 %cmp3.not.i = icmp eq i8 %0, 0 922 br i1 %cmp3.not.i, label %while.end.i, label %while.cond.i 923 924while.end.i: 925 %sub.ptr.lhs.cast.i = ptrtoint ptr %test.0.i to i64 926 %sub.ptr.rhs.cast.i = ptrtoint ptr %test to i64 927 %sub.ptr.sub.i = sub i64 %sub.ptr.lhs.cast.i, %sub.ptr.rhs.cast.i 928 %bool = icmp eq i64 %sub.ptr.sub.i, 0 929 ret i1 %bool 930} 931 932define i1 @recursiveGEP_withPtrSub_scalableGEP(ptr %val1) { 933; CHECK-LABEL: @recursiveGEP_withPtrSub_scalableGEP( 934; CHECK-NEXT: entry: 935; CHECK-NEXT: br label [[WHILE_COND_I:%.*]] 936; CHECK: while.cond.i: 937; CHECK-NEXT: [[A_PN_I:%.*]] = phi ptr [ [[TEST_0_I:%.*]], [[WHILE_COND_I]] ], [ [[VAL1:%.*]], [[ENTRY:%.*]] ] 938; CHECK-NEXT: [[TMP0:%.*]] = call i64 @llvm.vscale.i64() 939; CHECK-NEXT: [[TMP1:%.*]] = shl i64 [[TMP0]], 4 940; CHECK-NEXT: [[TEST_0_I]] = getelementptr i8, ptr [[A_PN_I]], i64 [[TMP1]] 941; CHECK-NEXT: [[TMP2:%.*]] = load i8, ptr [[TEST_0_I]], align 1 942; CHECK-NEXT: [[CMP3_NOT_I:%.*]] = icmp eq i8 [[TMP2]], 0 943; CHECK-NEXT: br i1 [[CMP3_NOT_I]], label [[WHILE_END_I:%.*]], label [[WHILE_COND_I]] 944; CHECK: while.end.i: 945; CHECK-NEXT: [[BOOL:%.*]] = icmp eq ptr [[TEST_0_I]], [[VAL1]] 946; CHECK-NEXT: ret i1 [[BOOL]] 947; 948entry: 949 br label %while.cond.i 950 951while.cond.i: 952 %a.pn.i = phi ptr [ %test.0.i, %while.cond.i ], [ %val1, %entry ] 953 %test.0.i = getelementptr <vscale x 16 x i8>, ptr %a.pn.i, i64 1 954 %0 = load i8, ptr %test.0.i, align 1 955 %cmp3.not.i = icmp eq i8 %0, 0 956 br i1 %cmp3.not.i, label %while.end.i, label %while.cond.i 957 958while.end.i: 959 %sub.ptr.lhs.cast.i = ptrtoint ptr %test.0.i to i64 960 %sub.ptr.rhs.cast.i = ptrtoint ptr %val1 to i64 961 %sub.ptr.sub.i = sub i64 %sub.ptr.lhs.cast.i, %sub.ptr.rhs.cast.i 962 %bool = icmp eq i64 %sub.ptr.sub.i, 0 963 ret i1 %bool 964} 965 966define i1 @recursiveGEP_withPtrSub_scalableGEP_inbounds(ptr %val1) { 967; CHECK-LABEL: @recursiveGEP_withPtrSub_scalableGEP_inbounds( 968; CHECK-NEXT: entry: 969; CHECK-NEXT: br label [[WHILE_COND_I:%.*]] 970; CHECK: while.cond.i: 971; CHECK-NEXT: [[A_PN_I:%.*]] = phi ptr [ [[TEST_0_I:%.*]], [[WHILE_COND_I]] ], [ [[VAL1:%.*]], [[ENTRY:%.*]] ] 972; CHECK-NEXT: [[TMP0:%.*]] = call i64 @llvm.vscale.i64() 973; CHECK-NEXT: [[TMP1:%.*]] = shl i64 [[TMP0]], 4 974; CHECK-NEXT: [[TEST_0_I]] = getelementptr inbounds i8, ptr [[A_PN_I]], i64 [[TMP1]] 975; CHECK-NEXT: [[TMP2:%.*]] = load i8, ptr [[TEST_0_I]], align 1 976; CHECK-NEXT: [[CMP3_NOT_I:%.*]] = icmp eq i8 [[TMP2]], 0 977; CHECK-NEXT: br i1 [[CMP3_NOT_I]], label [[WHILE_END_I:%.*]], label [[WHILE_COND_I]] 978; CHECK: while.end.i: 979; CHECK-NEXT: [[BOOL:%.*]] = icmp eq ptr [[TEST_0_I]], [[VAL1]] 980; CHECK-NEXT: ret i1 [[BOOL]] 981; 982entry: 983 br label %while.cond.i 984 985while.cond.i: 986 %a.pn.i = phi ptr [ %test.0.i, %while.cond.i ], [ %val1, %entry ] 987 %test.0.i = getelementptr inbounds <vscale x 16 x i8>, ptr %a.pn.i, i64 1 988 %0 = load i8, ptr %test.0.i, align 1 989 %cmp3.not.i = icmp eq i8 %0, 0 990 br i1 %cmp3.not.i, label %while.end.i, label %while.cond.i 991 992while.end.i: 993 %sub.ptr.lhs.cast.i = ptrtoint ptr %test.0.i to i64 994 %sub.ptr.rhs.cast.i = ptrtoint ptr %val1 to i64 995 %sub.ptr.sub.i = sub i64 %sub.ptr.lhs.cast.i, %sub.ptr.rhs.cast.i 996 %bool = icmp eq i64 %sub.ptr.sub.i, 0 997 ret i1 %bool 998} 999 1000; Test cmp(or), where one of argument to OR is a SUB of ptr2int with a recursive GEP. 1001define i1 @recursiveGEP_orcmp(ptr %val1, i64 %val2) { 1002; CHECK-LABEL: @recursiveGEP_orcmp( 1003; CHECK-NEXT: entry: 1004; CHECK-NEXT: br label [[WHILE_COND_I:%.*]] 1005; CHECK: while.cond.i: 1006; CHECK-NEXT: [[A_PN_I:%.*]] = phi ptr [ [[TEST_0_I:%.*]], [[WHILE_COND_I]] ], [ [[VAL1:%.*]], [[ENTRY:%.*]] ] 1007; CHECK-NEXT: [[TEST_0_I]] = getelementptr inbounds nuw i8, ptr [[A_PN_I]], i64 1 1008; CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[TEST_0_I]], align 2 1009; CHECK-NEXT: [[CMP3_NOT_I:%.*]] = icmp eq i8 [[TMP0]], 0 1010; CHECK-NEXT: br i1 [[CMP3_NOT_I]], label [[WHILE_END_I:%.*]], label [[WHILE_COND_I]] 1011; CHECK: while.end.i: 1012; CHECK-NEXT: ret i1 false 1013; 1014entry: 1015 br label %while.cond.i 1016 1017while.cond.i: 1018 %a.pn.i = phi ptr [ %test.0.i, %while.cond.i ], [ %val1, %entry ] 1019 %test.0.i = getelementptr inbounds i8, ptr %a.pn.i, i64 1 1020 %0 = load i8, ptr %test.0.i, align 2 1021 %cmp3.not.i = icmp eq i8 %0, 0 1022 br i1 %cmp3.not.i, label %while.end.i, label %while.cond.i 1023 1024while.end.i: 1025 %sub.ptr.lhs.cast.i = ptrtoint ptr %test.0.i to i64 1026 %sub.ptr.rhs.cast.i = ptrtoint ptr %val1 to i64 1027 %sub.ptr.sub.i = sub i64 %sub.ptr.lhs.cast.i, %sub.ptr.rhs.cast.i 1028 %orval = or i64 %sub.ptr.sub.i, %val2 1029 %bool = icmp eq i64 %orval, 0 1030 ret i1 %bool 1031} 1032 1033define i1 @recursiveGEP_orcmp_orOperandsCommuted(ptr %val1, i64 %val2) { 1034; CHECK-LABEL: @recursiveGEP_orcmp_orOperandsCommuted( 1035; CHECK-NEXT: entry: 1036; CHECK-NEXT: br label [[WHILE_COND_I:%.*]] 1037; CHECK: while.cond.i: 1038; CHECK-NEXT: [[A_PN_I:%.*]] = phi ptr [ [[TEST_0_I:%.*]], [[WHILE_COND_I]] ], [ [[VAL1:%.*]], [[ENTRY:%.*]] ] 1039; CHECK-NEXT: [[TEST_0_I]] = getelementptr inbounds nuw i8, ptr [[A_PN_I]], i64 1 1040; CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[TEST_0_I]], align 2 1041; CHECK-NEXT: [[CMP3_NOT_I:%.*]] = icmp eq i8 [[TMP0]], 0 1042; CHECK-NEXT: br i1 [[CMP3_NOT_I]], label [[WHILE_END_I:%.*]], label [[WHILE_COND_I]] 1043; CHECK: while.end.i: 1044; CHECK-NEXT: ret i1 false 1045; 1046entry: 1047 br label %while.cond.i 1048 1049while.cond.i: 1050 %a.pn.i = phi ptr [ %test.0.i, %while.cond.i ], [ %val1, %entry ] 1051 %test.0.i = getelementptr inbounds i8, ptr %a.pn.i, i64 1 1052 %0 = load i8, ptr %test.0.i, align 2 1053 %cmp3.not.i = icmp eq i8 %0, 0 1054 br i1 %cmp3.not.i, label %while.end.i, label %while.cond.i 1055 1056while.end.i: 1057 %sub.ptr.lhs.cast.i = ptrtoint ptr %test.0.i to i64 1058 %sub.ptr.rhs.cast.i = ptrtoint ptr %val1 to i64 1059 %sub.ptr.sub.i = sub i64 %sub.ptr.lhs.cast.i, %sub.ptr.rhs.cast.i 1060 %orval = or i64 %val2, %sub.ptr.sub.i 1061 %bool = icmp eq i64 %orval, 0 1062 ret i1 %bool 1063} 1064 1065; Test one of the argument to SUB is a ptr2int of a recursive GEP, with multiple use of SUB. 1066define i1 @recursiveGEP_orcmpMultiUse(ptr %val1, i64 %val2, ptr %dv1, ptr %dv2) { 1067; CHECK-LABEL: @recursiveGEP_orcmpMultiUse( 1068; CHECK-NEXT: entry: 1069; CHECK-NEXT: br label [[WHILE_COND_I:%.*]] 1070; CHECK: while.cond.i: 1071; CHECK-NEXT: [[A_PN_I:%.*]] = phi ptr [ [[TEST_0_I:%.*]], [[WHILE_COND_I]] ], [ [[VAL1:%.*]], [[ENTRY:%.*]] ] 1072; CHECK-NEXT: [[TEST_0_I]] = getelementptr inbounds nuw i8, ptr [[A_PN_I]], i64 1 1073; CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[TEST_0_I]], align 2 1074; CHECK-NEXT: [[CMP3_NOT_I:%.*]] = icmp eq i8 [[TMP0]], 0 1075; CHECK-NEXT: br i1 [[CMP3_NOT_I]], label [[WHILE_END_I:%.*]], label [[WHILE_COND_I]] 1076; CHECK: while.end.i: 1077; CHECK-NEXT: br i1 false, label [[IF_THEN:%.*]], label [[IF_END4:%.*]] 1078; CHECK: if.then: 1079; CHECK-NEXT: br label [[CLEANUP:%.*]] 1080; CHECK: if.end4: 1081; CHECK-NEXT: br label [[CLEANUP]] 1082; CHECK: cleanup: 1083; CHECK-NEXT: ret i1 true 1084; 1085entry: 1086 br label %while.cond.i 1087 1088while.cond.i: 1089 %a.pn.i = phi ptr [ %test.0.i, %while.cond.i ], [ %val1, %entry ] 1090 %test.0.i = getelementptr inbounds i8, ptr %a.pn.i, i64 1 1091 %0 = load i8, ptr %test.0.i, align 2 1092 %cmp3.not.i = icmp eq i8 %0, 0 1093 br i1 %cmp3.not.i, label %while.end.i, label %while.cond.i 1094 1095while.end.i: 1096 %sub.ptr.lhs.cast.i = ptrtoint ptr %test.0.i to i64 1097 %sub.ptr.rhs.cast.i = ptrtoint ptr %val1 to i64 1098 %sub.ptr.sub.i = sub i64 %sub.ptr.lhs.cast.i, %sub.ptr.rhs.cast.i 1099 %orval = or i64 %sub.ptr.sub.i, %val2 1100 %or.cond = icmp eq i64 %orval, 0 1101 br i1 %or.cond, label %if.then, label %if.end4 1102 1103if.then: 1104 %cmp = icmp eq ptr %dv1, %dv2 1105 br label %cleanup 1106 1107if.end4: 1108 %tobool = icmp ne i64 %sub.ptr.sub.i, 0 1109 br label %cleanup 1110 1111cleanup: 1112 %retval.0 = phi i1 [ %cmp, %if.then ], [ %tobool, %if.end4 ] 1113 ret i1 %retval.0 1114} 1115 1116 1117define i32 @issue_124275_wrong_br_direction(i32 noundef %inp) { 1118; CHECK-LABEL: @issue_124275_wrong_br_direction( 1119; CHECK-NEXT: entry: 1120; CHECK-NEXT: [[TMP0:%.*]] = xor i32 [[INP:%.*]], -2 1121; CHECK-NEXT: [[XOR_INP_NEG:%.*]] = add i32 [[TMP0]], 1 1122; CHECK-NEXT: [[CMP_NE_NOT:%.*]] = icmp eq i32 [[XOR_INP_NEG]], 0 1123; CHECK-NEXT: br i1 [[CMP_NE_NOT]], label [[B1:%.*]], label [[B0:%.*]] 1124; CHECK: B0: 1125; CHECK-NEXT: [[PHI_B0:%.*]] = phi i32 [ [[PHI_B1:%.*]], [[B1]] ], [ [[XOR_INP_NEG]], [[ENTRY:%.*]] ] 1126; CHECK-NEXT: br label [[B1]] 1127; CHECK: B1: 1128; CHECK-NEXT: [[PHI_B1]] = phi i32 [ [[PHI_B0]], [[B0]] ], [ 0, [[ENTRY]] ] 1129; CHECK-NEXT: [[CMP_NE_B1_NOT:%.*]] = icmp eq i32 [[PHI_B1]], 0 1130; CHECK-NEXT: br i1 [[CMP_NE_B1_NOT]], label [[B0]], label [[END:%.*]] 1131; CHECK: end: 1132; CHECK-NEXT: ret i32 0 1133; 1134entry: 1135 %xor_inp = xor i32 %inp, 1 1136 %sub = sub i32 0, %xor_inp 1137 %cmp_ne = icmp ne i32 %sub, 0 1138 br i1 %cmp_ne, label %B0, label %B1 1139 1140B0: 1141 %phi_B0 = phi i32 [ %phi_B1, %B1 ], [ %sub, %entry ] 1142 br label %B1 1143 1144B1: 1145 %phi_B1 = phi i32 [ %phi_B0, %B0 ], [ 0, %entry ] 1146 %cmp_ne_B1 = icmp ne i32 %phi_B1, 0 1147 %cmp_eq_B1 = xor i1 %cmp_ne_B1, true 1148 br i1 %cmp_eq_B1, label %B0, label %end 1149 1150end: 1151 ret i32 0 1152} 1153