1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=instcombine -S | FileCheck %s 3 4define void @idom_sign_bit_check_edge_dominates(i64 %a) { 5; CHECK-LABEL: @idom_sign_bit_check_edge_dominates( 6; CHECK-NEXT: entry: 7; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[A:%.*]], 0 8; CHECK-NEXT: br i1 [[CMP]], label [[LAND_LHS_TRUE:%.*]], label [[LOR_RHS:%.*]] 9; CHECK: land.lhs.true: 10; CHECK-NEXT: br label [[LOR_END:%.*]] 11; CHECK: lor.rhs: 12; CHECK-NEXT: [[CMP2_NOT:%.*]] = icmp eq i64 [[A]], 0 13; CHECK-NEXT: br i1 [[CMP2_NOT]], label [[LOR_END]], label [[LAND_RHS:%.*]] 14; CHECK: land.rhs: 15; CHECK-NEXT: br label [[LOR_END]] 16; CHECK: lor.end: 17; CHECK-NEXT: ret void 18; 19entry: 20 %cmp = icmp slt i64 %a, 0 21 br i1 %cmp, label %land.lhs.true, label %lor.rhs 22 23land.lhs.true: 24 br label %lor.end 25 26lor.rhs: 27 %cmp2 = icmp sgt i64 %a, 0 28 br i1 %cmp2, label %land.rhs, label %lor.end 29 30land.rhs: 31 br label %lor.end 32 33lor.end: 34 ret void 35} 36 37define void @idom_sign_bit_check_edge_not_dominates(i64 %a, i1 %c1) { 38; CHECK-LABEL: @idom_sign_bit_check_edge_not_dominates( 39; CHECK-NEXT: entry: 40; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[A:%.*]], 0 41; CHECK-NEXT: br i1 [[CMP]], label [[LAND_LHS_TRUE:%.*]], label [[LOR_RHS:%.*]] 42; CHECK: land.lhs.true: 43; CHECK-NEXT: br i1 [[C1:%.*]], label [[LOR_END:%.*]], label [[LOR_RHS]] 44; CHECK: lor.rhs: 45; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i64 [[A]], 0 46; CHECK-NEXT: br i1 [[CMP2]], label [[LAND_RHS:%.*]], label [[LOR_END]] 47; CHECK: land.rhs: 48; CHECK-NEXT: br label [[LOR_END]] 49; CHECK: lor.end: 50; CHECK-NEXT: ret void 51; 52entry: 53 %cmp = icmp slt i64 %a, 0 54 br i1 %cmp, label %land.lhs.true, label %lor.rhs 55 56land.lhs.true: 57 br i1 %c1, label %lor.end, label %lor.rhs 58 59lor.rhs: 60 %cmp2 = icmp sgt i64 %a, 0 61 br i1 %cmp2, label %land.rhs, label %lor.end 62 63land.rhs: 64 br label %lor.end 65 66lor.end: 67 ret void 68} 69 70define void @idom_sign_bit_check_edge_dominates_select(i64 %a, i64 %b) { 71; CHECK-LABEL: @idom_sign_bit_check_edge_dominates_select( 72; CHECK-NEXT: entry: 73; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[A:%.*]], 5 74; CHECK-NEXT: br i1 [[CMP]], label [[LAND_LHS_TRUE:%.*]], label [[LOR_RHS:%.*]] 75; CHECK: land.lhs.true: 76; CHECK-NEXT: br label [[LOR_END:%.*]] 77; CHECK: lor.rhs: 78; CHECK-NEXT: [[CMP3_NOT:%.*]] = icmp eq i64 [[A]], [[B:%.*]] 79; CHECK-NEXT: br i1 [[CMP3_NOT]], label [[LOR_END]], label [[LAND_RHS:%.*]] 80; CHECK: land.rhs: 81; CHECK-NEXT: br label [[LOR_END]] 82; CHECK: lor.end: 83; CHECK-NEXT: ret void 84; 85entry: 86 %cmp = icmp slt i64 %a, 5 87 br i1 %cmp, label %land.lhs.true, label %lor.rhs 88 89land.lhs.true: 90 br label %lor.end 91 92lor.rhs: 93 %cmp2 = icmp sgt i64 %a, 5 94 %select = select i1 %cmp2, i64 %a, i64 5 95 %cmp3 = icmp ne i64 %select, %b 96 br i1 %cmp3, label %land.rhs, label %lor.end 97 98land.rhs: 99 br label %lor.end 100 101lor.end: 102 ret void 103} 104 105define void @idom_zbranch(i64 %a) { 106; CHECK-LABEL: @idom_zbranch( 107; CHECK-NEXT: entry: 108; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i64 [[A:%.*]], 0 109; CHECK-NEXT: br i1 [[CMP]], label [[LOR_END:%.*]], label [[LOR_RHS:%.*]] 110; CHECK: lor.rhs: 111; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i64 [[A]], 0 112; CHECK-NEXT: br i1 [[CMP2]], label [[LAND_RHS:%.*]], label [[LOR_END]] 113; CHECK: land.rhs: 114; CHECK-NEXT: br label [[LOR_END]] 115; CHECK: lor.end: 116; CHECK-NEXT: ret void 117; 118entry: 119 %cmp = icmp sgt i64 %a, 0 120 br i1 %cmp, label %lor.end, label %lor.rhs 121 122lor.rhs: 123 %cmp2 = icmp slt i64 %a, 0 124 br i1 %cmp2, label %land.rhs, label %lor.end 125 126land.rhs: 127 br label %lor.end 128 129lor.end: 130 ret void 131} 132 133define void @idom_not_zbranch(i32 %a, i32 %b) { 134; CHECK-LABEL: @idom_not_zbranch( 135; CHECK-NEXT: entry: 136; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A:%.*]], 0 137; CHECK-NEXT: br i1 [[CMP]], label [[RETURN:%.*]], label [[IF_END:%.*]] 138; CHECK: if.end: 139; CHECK-NEXT: [[CMP2_NOT:%.*]] = icmp eq i32 [[A]], [[B:%.*]] 140; CHECK-NEXT: br i1 [[CMP2_NOT]], label [[RETURN]], label [[IF_THEN3:%.*]] 141; CHECK: if.then3: 142; CHECK-NEXT: br label [[RETURN]] 143; CHECK: return: 144; CHECK-NEXT: ret void 145; 146entry: 147 %cmp = icmp sgt i32 %a, 0 148 br i1 %cmp, label %return, label %if.end 149 150if.end: 151 %cmp1 = icmp slt i32 %a, 0 152 %a. = select i1 %cmp1, i32 %a, i32 0 153 %cmp2 = icmp ne i32 %a., %b 154 br i1 %cmp2, label %if.then3, label %return 155 156if.then3: 157 br label %return 158 159return: 160 ret void 161} 162 163define void @trueblock_cmp_eq(i32 %a, i32 %b) { 164; CHECK-LABEL: @trueblock_cmp_eq( 165; CHECK-NEXT: entry: 166; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A:%.*]], 0 167; CHECK-NEXT: br i1 [[CMP]], label [[IF_END:%.*]], label [[RETURN:%.*]] 168; CHECK: if.end: 169; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[A]], 1 170; CHECK-NEXT: br i1 [[CMP1]], label [[IF_THEN3:%.*]], label [[RETURN]] 171; CHECK: if.then3: 172; CHECK-NEXT: br label [[RETURN]] 173; CHECK: return: 174; CHECK-NEXT: ret void 175; 176entry: 177 %cmp = icmp sgt i32 %a, 0 178 br i1 %cmp, label %if.end, label %return 179 180if.end: 181 %cmp1 = icmp slt i32 %a, 2 182 br i1 %cmp1, label %if.then3, label %return 183 184if.then3: 185 br label %return 186 187return: 188 ret void 189} 190 191define i1 @trueblock_cmp_is_false(i32 %x, i32 %y) { 192; CHECK-LABEL: @trueblock_cmp_is_false( 193; CHECK-NEXT: entry: 194; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]] 195; CHECK-NEXT: br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]] 196; CHECK: t: 197; CHECK-NEXT: ret i1 false 198; CHECK: f: 199; CHECK-NEXT: ret i1 false 200; 201entry: 202 %cmp = icmp sgt i32 %x, %y 203 br i1 %cmp, label %t, label %f 204t: 205 %cmp2 = icmp slt i32 %x, %y 206 ret i1 %cmp2 207f: 208 ret i1 %cmp 209} 210 211define i1 @trueblock_cmp_is_false_commute(i32 %x, i32 %y) { 212; CHECK-LABEL: @trueblock_cmp_is_false_commute( 213; CHECK-NEXT: entry: 214; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]] 215; CHECK-NEXT: br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]] 216; CHECK: t: 217; CHECK-NEXT: ret i1 false 218; CHECK: f: 219; CHECK-NEXT: ret i1 false 220; 221entry: 222 %cmp = icmp eq i32 %x, %y 223 br i1 %cmp, label %t, label %f 224t: 225 %cmp2 = icmp sgt i32 %y, %x 226 ret i1 %cmp2 227f: 228 ret i1 %cmp 229} 230 231define i1 @trueblock_cmp_is_true(i32 %x, i32 %y) { 232; CHECK-LABEL: @trueblock_cmp_is_true( 233; CHECK-NEXT: entry: 234; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]] 235; CHECK-NEXT: br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]] 236; CHECK: t: 237; CHECK-NEXT: ret i1 true 238; CHECK: f: 239; CHECK-NEXT: ret i1 false 240; 241entry: 242 %cmp = icmp ult i32 %x, %y 243 br i1 %cmp, label %t, label %f 244t: 245 %cmp2 = icmp ne i32 %x, %y 246 ret i1 %cmp2 247f: 248 ret i1 %cmp 249} 250 251define i1 @trueblock_cmp_is_true_commute(i32 %x, i32 %y) { 252; CHECK-LABEL: @trueblock_cmp_is_true_commute( 253; CHECK-NEXT: entry: 254; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[X:%.*]], [[Y:%.*]] 255; CHECK-NEXT: br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]] 256; CHECK: t: 257; CHECK-NEXT: ret i1 true 258; CHECK: f: 259; CHECK-NEXT: ret i1 false 260; 261entry: 262 %cmp = icmp ugt i32 %x, %y 263 br i1 %cmp, label %t, label %f 264t: 265 %cmp2 = icmp ne i32 %y, %x 266 ret i1 %cmp2 267f: 268 ret i1 %cmp 269} 270 271define i1 @falseblock_cmp_is_false(i32 %x, i32 %y) { 272; CHECK-LABEL: @falseblock_cmp_is_false( 273; CHECK-NEXT: entry: 274; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]] 275; CHECK-NEXT: br i1 [[CMP_NOT]], label [[F:%.*]], label [[T:%.*]] 276; CHECK: t: 277; CHECK-NEXT: ret i1 true 278; CHECK: f: 279; CHECK-NEXT: ret i1 false 280; 281entry: 282 %cmp = icmp sle i32 %x, %y 283 br i1 %cmp, label %t, label %f 284t: 285 ret i1 %cmp 286f: 287 %cmp2 = icmp slt i32 %x, %y 288 ret i1 %cmp2 289} 290 291define i1 @falseblock_cmp_is_false_commute(i32 %x, i32 %y) { 292; CHECK-LABEL: @falseblock_cmp_is_false_commute( 293; CHECK-NEXT: entry: 294; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]] 295; CHECK-NEXT: br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]] 296; CHECK: t: 297; CHECK-NEXT: ret i1 true 298; CHECK: f: 299; CHECK-NEXT: ret i1 false 300; 301entry: 302 %cmp = icmp eq i32 %x, %y 303 br i1 %cmp, label %t, label %f 304t: 305 ret i1 %cmp 306f: 307 %cmp2 = icmp eq i32 %y, %x 308 ret i1 %cmp2 309} 310 311define i1 @falseblock_cmp_is_true(i32 %x, i32 %y) { 312; CHECK-LABEL: @falseblock_cmp_is_true( 313; CHECK-NEXT: entry: 314; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]] 315; CHECK-NEXT: br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]] 316; CHECK: t: 317; CHECK-NEXT: ret i1 true 318; CHECK: f: 319; CHECK-NEXT: ret i1 true 320; 321entry: 322 %cmp = icmp ult i32 %x, %y 323 br i1 %cmp, label %t, label %f 324t: 325 ret i1 %cmp 326f: 327 %cmp2 = icmp uge i32 %x, %y 328 ret i1 %cmp2 329} 330 331define i1 @falseblock_cmp_is_true_commute(i32 %x, i32 %y) { 332; CHECK-LABEL: @falseblock_cmp_is_true_commute( 333; CHECK-NEXT: entry: 334; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]] 335; CHECK-NEXT: br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]] 336; CHECK: t: 337; CHECK-NEXT: ret i1 true 338; CHECK: f: 339; CHECK-NEXT: ret i1 true 340; 341entry: 342 %cmp = icmp sgt i32 %x, %y 343 br i1 %cmp, label %t, label %f 344t: 345 ret i1 %cmp 346f: 347 %cmp2 = icmp sge i32 %y, %x 348 ret i1 %cmp2 349} 350 351; This used to infinite loop because of a conflict 352; with min/max canonicalization. 353 354define i32 @PR48900(i32 %i, ptr %p) { 355; CHECK-LABEL: @PR48900( 356; CHECK-NEXT: [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[I:%.*]], i32 1) 357; CHECK-NEXT: [[I4:%.*]] = icmp sgt i32 [[UMAX]], 0 358; CHECK-NEXT: br i1 [[I4]], label [[TRUELABEL:%.*]], label [[FALSELABEL:%.*]] 359; CHECK: truelabel: 360; CHECK-NEXT: [[SMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[UMAX]], i32 2) 361; CHECK-NEXT: ret i32 [[SMIN]] 362; CHECK: falselabel: 363; CHECK-NEXT: ret i32 0 364; 365 %maxcmp = icmp ugt i32 %i, 1 366 %umax = select i1 %maxcmp, i32 %i, i32 1 367 %i4 = icmp sgt i32 %umax, 0 368 br i1 %i4, label %truelabel, label %falselabel 369 370truelabel: 371 %mincmp = icmp ult i32 %umax, 2 372 %smin = select i1 %mincmp, i32 %umax, i32 2 373 ret i32 %smin 374 375falselabel: 376 ret i32 0 377} 378 379; This used to infinite loop because of a conflict 380; with min/max canonicalization. 381 382define i8 @PR48900_alt(i8 %i, ptr %p) { 383; CHECK-LABEL: @PR48900_alt( 384; CHECK-NEXT: [[SMAX:%.*]] = call i8 @llvm.smax.i8(i8 [[I:%.*]], i8 -127) 385; CHECK-NEXT: [[I4:%.*]] = icmp ugt i8 [[SMAX]], -128 386; CHECK-NEXT: br i1 [[I4]], label [[TRUELABEL:%.*]], label [[FALSELABEL:%.*]] 387; CHECK: truelabel: 388; CHECK-NEXT: [[UMIN:%.*]] = call i8 @llvm.smin.i8(i8 [[SMAX]], i8 -126) 389; CHECK-NEXT: ret i8 [[UMIN]] 390; CHECK: falselabel: 391; CHECK-NEXT: ret i8 0 392; 393 %maxcmp = icmp sgt i8 %i, -127 394 %smax = select i1 %maxcmp, i8 %i, i8 -127 395 %i4 = icmp ugt i8 %smax, 128 396 br i1 %i4, label %truelabel, label %falselabel 397 398truelabel: 399 %mincmp = icmp slt i8 %smax, -126 400 %umin = select i1 %mincmp, i8 %smax, i8 -126 401 ret i8 %umin 402 403falselabel: 404 ret i8 0 405} 406 407define i1 @and_mask1_eq(i32 %conv) { 408; CHECK-LABEL: @and_mask1_eq( 409; CHECK-NEXT: entry: 410; CHECK-NEXT: [[AND:%.*]] = and i32 [[CONV:%.*]], 1 411; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0 412; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]] 413; CHECK: then: 414; CHECK-NEXT: ret i1 false 415; CHECK: else: 416; CHECK-NEXT: ret i1 false 417; 418entry: 419 %and = and i32 %conv, 1 420 %cmp = icmp eq i32 %and, 0 421 br i1 %cmp, label %then, label %else 422 423then: 424 ret i1 0 425 426else: 427 %and1 = and i32 %conv, 3 428 %cmp1 = icmp eq i32 %and1, 0 429 ret i1 %cmp1 430} 431 432define i1 @and_mask1_ne(i32 %conv) { 433; CHECK-LABEL: @and_mask1_ne( 434; CHECK-NEXT: entry: 435; CHECK-NEXT: [[AND:%.*]] = and i32 [[CONV:%.*]], 1 436; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0 437; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]] 438; CHECK: then: 439; CHECK-NEXT: ret i1 false 440; CHECK: else: 441; CHECK-NEXT: ret i1 true 442; 443entry: 444 %and = and i32 %conv, 1 445 %cmp = icmp eq i32 %and, 0 446 br i1 %cmp, label %then, label %else 447 448then: 449 ret i1 0 450 451else: 452 %and1 = and i32 %conv, 3 453 %cmp1 = icmp ne i32 %and1, 0 454 ret i1 %cmp1 455} 456 457define i1 @and_mask2(i32 %conv) { 458; CHECK-LABEL: @and_mask2( 459; CHECK-NEXT: entry: 460; CHECK-NEXT: [[AND:%.*]] = and i32 [[CONV:%.*]], 4 461; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0 462; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]] 463; CHECK: then: 464; CHECK-NEXT: ret i1 false 465; CHECK: else: 466; CHECK-NEXT: [[AND1:%.*]] = and i32 [[CONV]], 3 467; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[AND1]], 0 468; CHECK-NEXT: ret i1 [[CMP1]] 469; 470entry: 471 %and = and i32 %conv, 4 472 %cmp = icmp eq i32 %and, 0 473 br i1 %cmp, label %then, label %else 474 475then: 476 ret i1 0 477 478else: 479 %and1 = and i32 %conv, 3 480 %cmp1 = icmp eq i32 %and1, 0 481 ret i1 %cmp1 482} 483 484; TODO: %cmp1 can be folded into false. 485 486define i1 @and_mask3(i32 %conv) { 487; CHECK-LABEL: @and_mask3( 488; CHECK-NEXT: entry: 489; CHECK-NEXT: [[AND:%.*]] = and i32 [[CONV:%.*]], 3 490; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0 491; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]] 492; CHECK: then: 493; CHECK-NEXT: ret i1 false 494; CHECK: else: 495; CHECK-NEXT: [[AND1:%.*]] = and i32 [[CONV]], 7 496; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[AND1]], 0 497; CHECK-NEXT: ret i1 [[CMP1]] 498; 499entry: 500 %and = and i32 %conv, 3 501 %cmp = icmp eq i32 %and, 0 502 br i1 %cmp, label %then, label %else 503 504then: 505 ret i1 0 506 507else: 508 %and1 = and i32 %conv, 7 509 %cmp1 = icmp eq i32 %and1, 0 510 ret i1 %cmp1 511} 512 513define i1 @and_mask4(i32 %conv) { 514; CHECK-LABEL: @and_mask4( 515; CHECK-NEXT: entry: 516; CHECK-NEXT: [[AND:%.*]] = and i32 [[CONV:%.*]], 4 517; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0 518; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]] 519; CHECK: then: 520; CHECK-NEXT: ret i1 false 521; CHECK: else: 522; CHECK-NEXT: ret i1 false 523; 524entry: 525 %and = and i32 %conv, 4 526 %cmp = icmp eq i32 %and, 0 527 br i1 %cmp, label %then, label %else 528 529then: 530 ret i1 0 531 532else: 533 %and1 = and i32 %conv, 7 534 %cmp1 = icmp eq i32 %and1, 0 535 ret i1 %cmp1 536} 537