1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s 3 4define i1 @test_second_and_condition_implied_by_first(i8 %x) { 5; CHECK-LABEL: @test_second_and_condition_implied_by_first( 6; CHECK-NEXT: entry: 7; CHECK-NEXT: [[C_1:%.*]] = icmp ugt i8 [[X:%.*]], 10 8; CHECK-NEXT: [[T_1:%.*]] = icmp ugt i8 [[X]], 5 9; CHECK-NEXT: [[AND:%.*]] = and i1 [[C_1]], true 10; CHECK-NEXT: br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]] 11; CHECK: then: 12; CHECK-NEXT: ret i1 false 13; CHECK: else: 14; CHECK-NEXT: ret i1 true 15; 16entry: 17 %c.1 = icmp ugt i8 %x, 10 18 %t.1 = icmp ugt i8 %x, 5 19 %and = and i1 %c.1, %t.1 20 br i1 %and, label %then, label %else 21 22then: 23 ret i1 0 24 25else: 26 ret i1 1 27} 28 29define i1 @test_first_and_condition_implied_by_second_ops(i8 %x) { 30; CHECK-LABEL: @test_first_and_condition_implied_by_second_ops( 31; CHECK-NEXT: entry: 32; CHECK-NEXT: [[C_1:%.*]] = icmp ugt i8 [[X:%.*]], 10 33; CHECK-NEXT: [[T_1:%.*]] = icmp ugt i8 [[X]], 5 34; CHECK-NEXT: [[AND:%.*]] = and i1 true, [[C_1]] 35; CHECK-NEXT: br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]] 36; CHECK: then: 37; CHECK-NEXT: ret i1 false 38; CHECK: else: 39; CHECK-NEXT: ret i1 true 40; 41entry: 42 %c.1 = icmp ugt i8 %x, 10 43 %t.1 = icmp ugt i8 %x, 5 44 %and = and i1 %t.1, %c.1 45 br i1 %and, label %then, label %else 46 47then: 48 ret i1 0 49 50else: 51 ret i1 1 52} 53 54define i1 @test_second_and_condition_implied_by_first_select_form(i8 %x) { 55; CHECK-LABEL: @test_second_and_condition_implied_by_first_select_form( 56; CHECK-NEXT: entry: 57; CHECK-NEXT: [[C_1:%.*]] = icmp ugt i8 [[X:%.*]], 10 58; CHECK-NEXT: [[T_1:%.*]] = icmp ugt i8 [[X]], 5 59; CHECK-NEXT: [[AND:%.*]] = select i1 [[C_1]], i1 true, i1 false 60; CHECK-NEXT: br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]] 61; CHECK: then: 62; CHECK-NEXT: ret i1 false 63; CHECK: else: 64; CHECK-NEXT: ret i1 true 65; 66entry: 67 %c.1 = icmp ugt i8 %x, 10 68 %t.1 = icmp ugt i8 %x, 5 69 %and = select i1 %c.1, i1 %t.1, i1 false 70 br i1 %and, label %then, label %else 71 72then: 73 ret i1 0 74 75else: 76 ret i1 1 77} 78 79define i1 @test_first_and_condition_implied_by_second_select_form(i8 %x) { 80; CHECK-LABEL: @test_first_and_condition_implied_by_second_select_form( 81; CHECK-NEXT: entry: 82; CHECK-NEXT: [[C_1:%.*]] = icmp ugt i8 [[X:%.*]], 10 83; CHECK-NEXT: [[T_1:%.*]] = icmp ugt i8 [[X]], 5 84; CHECK-NEXT: [[AND:%.*]] = select i1 [[T_1]], i1 [[C_1]], i1 false 85; CHECK-NEXT: br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]] 86; CHECK: then: 87; CHECK-NEXT: ret i1 false 88; CHECK: else: 89; CHECK-NEXT: ret i1 true 90; 91entry: 92 %c.1 = icmp ugt i8 %x, 10 93 %t.1 = icmp ugt i8 %x, 5 94 %and = select i1 %t.1, i1 %c.1, i1 false 95 br i1 %and, label %then, label %else 96 97then: 98 ret i1 0 99 100else: 101 ret i1 1 102} 103 104define i1 @test_same_cond_for_and(i8 %x) { 105; CHECK-LABEL: @test_same_cond_for_and( 106; CHECK-NEXT: entry: 107; CHECK-NEXT: [[C_1:%.*]] = icmp ugt i8 [[X:%.*]], 10 108; CHECK-NEXT: [[AND:%.*]] = and i1 true, [[C_1]] 109; CHECK-NEXT: br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]] 110; CHECK: then: 111; CHECK-NEXT: ret i1 false 112; CHECK: else: 113; CHECK-NEXT: ret i1 true 114; 115entry: 116 %c.1 = icmp ugt i8 %x, 10 117 %and = and i1 %c.1, %c.1 118 br i1 %and, label %then, label %else 119 120then: 121 ret i1 0 122 123else: 124 ret i1 1 125} 126 127define i1 @test_same_cond_for_and_select_form(i8 %x) { 128; CHECK-LABEL: @test_same_cond_for_and_select_form( 129; CHECK-NEXT: entry: 130; CHECK-NEXT: [[C_1:%.*]] = icmp ugt i8 [[X:%.*]], 10 131; CHECK-NEXT: [[AND:%.*]] = select i1 [[C_1]], i1 [[C_1]], i1 false 132; CHECK-NEXT: br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]] 133; CHECK: then: 134; CHECK-NEXT: ret i1 false 135; CHECK: else: 136; CHECK-NEXT: ret i1 true 137; 138entry: 139 %c.1 = icmp ugt i8 %x, 10 140 %and = select i1 %c.1, i1 %c.1, i1 false 141 br i1 %and, label %then, label %else 142 143then: 144 ret i1 0 145 146else: 147 ret i1 1 148} 149 150define i1 @test_second_and_condition_not_implied_by_first(i8 %x) { 151; CHECK-LABEL: @test_second_and_condition_not_implied_by_first( 152; CHECK-NEXT: entry: 153; CHECK-NEXT: [[C_1:%.*]] = icmp ugt i8 [[X:%.*]], 10 154; CHECK-NEXT: [[C_2:%.*]] = icmp ugt i8 [[X]], 5 155; CHECK-NEXT: [[AND:%.*]] = and i1 true, [[C_1]] 156; CHECK-NEXT: br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]] 157; CHECK: then: 158; CHECK-NEXT: ret i1 false 159; CHECK: else: 160; CHECK-NEXT: ret i1 true 161; 162entry: 163 %c.1 = icmp ugt i8 %x, 10 164 %c.2 = icmp ugt i8 %x, 5 165 %and = and i1 %c.2, %c.1 166 br i1 %and, label %then, label %else 167 168then: 169 ret i1 0 170 171else: 172 ret i1 1 173} 174 175define i1 @test_remove_variables(i1 %c, ptr %A, i64 %B, ptr %C) { 176; CHECK-LABEL: @test_remove_variables( 177; CHECK-NEXT: entry: 178; CHECK-NEXT: br i1 [[C:%.*]], label [[THEN_1:%.*]], label [[EXIT:%.*]] 179; CHECK: then.1: 180; CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[C:%.*]], align 8 181; CHECK-NEXT: [[C_1:%.*]] = icmp ult ptr [[TMP0]], [[A:%.*]] 182; CHECK-NEXT: br i1 [[C_1]], label [[THEN_2:%.*]], label [[ELSE_2:%.*]] 183; CHECK: then.2: 184; CHECK-NEXT: [[C_3:%.*]] = icmp sgt i64 [[B:%.*]], 0 185; CHECK-NEXT: [[AND:%.*]] = and i1 true, [[C_3]] 186; CHECK-NEXT: ret i1 [[AND]] 187; CHECK: else.2: 188; CHECK-NEXT: ret i1 false 189; CHECK: exit: 190; CHECK-NEXT: ret i1 true 191; 192entry: 193 br i1 %c, label %then.1, label %exit 194 195then.1: 196 %0 = load ptr, ptr %C, align 8 197 %c.1 = icmp ult ptr %0, %A 198 br i1 %c.1, label %then.2, label %else.2 199 200then.2: 201 %c.2 = icmp ne ptr %A, null 202 %c.3 = icmp sgt i64 %B, 0 203 %and = and i1 %c.2, %c.3 204 ret i1 %and 205 206else.2: 207 ret i1 0 208 209exit: 210 %t = icmp eq ptr null, null 211 ret i1 %t 212} 213 214define i1 @test_and_op_0_simplified(i32 %v) { 215; CHECK-LABEL: @test_and_op_0_simplified( 216; CHECK-NEXT: entry: 217; CHECK-NEXT: [[C_1:%.*]] = icmp sgt i32 [[V:%.*]], 0 218; CHECK-NEXT: [[AND:%.*]] = and i1 false, [[C_1]] 219; CHECK-NEXT: ret i1 [[AND]] 220; 221entry: 222 %c.1 = icmp sgt i32 %v, 0 223 %t.1 = icmp sgt i32 0, 0 224 %and = and i1 %t.1, %c.1 225 ret i1 %and 226} 227 228define i1 @test_and_op_1_simplified(i32 %v) { 229; CHECK-LABEL: @test_and_op_1_simplified( 230; CHECK-NEXT: entry: 231; CHECK-NEXT: [[C_1:%.*]] = icmp sgt i32 [[V:%.*]], 0 232; CHECK-NEXT: [[AND:%.*]] = and i1 [[C_1]], false 233; CHECK-NEXT: ret i1 [[AND]] 234; 235entry: 236 %c.1 = icmp sgt i32 %v, 0 237 %t.1 = icmp sgt i32 0, 0 238 %and = and i1 %c.1, %t.1 239 ret i1 %and 240} 241 242define i1 @and_select_not_used_for_branch(i32 %x, i32 %y,i32 %z) { 243; CHECK-LABEL: @and_select_not_used_for_branch( 244; CHECK-NEXT: entry: 245; CHECK-NEXT: [[C_1:%.*]] = icmp ne i32 [[X:%.*]], 0 246; CHECK-NEXT: [[C_2:%.*]] = icmp ne i32 [[Y:%.*]], 0 247; CHECK-NEXT: [[C_3:%.*]] = icmp eq i32 [[X]], 16 248; CHECK-NEXT: [[AND:%.*]] = and i1 [[C_2]], [[C_3]] 249; CHECK-NEXT: br i1 [[AND]], label [[THEN:%.*]], label [[EXIT:%.*]] 250; CHECK: then: 251; CHECK-NEXT: [[C_4:%.*]] = icmp eq i32 [[Z:%.*]], 0 252; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C_4]], i1 true, i1 false 253; CHECK-NEXT: br label [[EXIT]] 254; CHECK: exit: 255; CHECK-NEXT: [[RES:%.*]] = phi i1 [ [[C_1]], [[ENTRY:%.*]] ], [ [[SEL]], [[THEN]] ] 256; CHECK-NEXT: ret i1 [[RES]] 257; 258entry: 259 %c.1 = icmp ne i32 %x, 0 260 %c.2 = icmp ne i32 %y, 0 261 %c.3 = icmp eq i32 %x, 16 262 %and = and i1 %c.2, %c.3 263 br i1 %and, label %then, label %exit 264 265then: 266 %c.4 = icmp eq i32 %z, 0 267 %sel = select i1 %c.4, i1 %c.1, i1 false 268 br label %exit 269 270exit: 271 %res = phi i1 [ %c.1, %entry ], [ %sel, %then ] 272 ret i1 %res 273} 274 275define i1 @and_select_scope_limited(i32 %x, i32 %y, i32 %z) { 276; CHECK-LABEL: @and_select_scope_limited( 277; CHECK-NEXT: entry: 278; CHECK-NEXT: [[C_1:%.*]] = icmp ne i32 [[X:%.*]], 0 279; CHECK-NEXT: [[C_2:%.*]] = icmp ne i32 [[Y:%.*]], 0 280; CHECK-NEXT: [[C_3:%.*]] = icmp eq i32 [[X]], 16 281; CHECK-NEXT: [[AND:%.*]] = and i1 [[C_2]], [[C_3]] 282; CHECK-NEXT: br i1 [[AND]], label [[THEN:%.*]], label [[EXIT:%.*]] 283; CHECK: then: 284; CHECK-NEXT: [[C_4:%.*]] = icmp eq i32 [[Z:%.*]], 0 285; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C_4]], i1 true, i1 false 286; CHECK-NEXT: br i1 [[SEL]], label [[T_1:%.*]], label [[EXIT]] 287; CHECK: t.1: 288; CHECK-NEXT: ret i1 true 289; CHECK: exit: 290; CHECK-NEXT: [[RES:%.*]] = phi i1 [ [[C_1]], [[ENTRY:%.*]] ], [ [[SEL]], [[THEN]] ] 291; CHECK-NEXT: ret i1 [[RES]] 292; 293entry: 294 %c.1 = icmp ne i32 %x, 0 295 %c.2 = icmp ne i32 %y, 0 296 %c.3 = icmp eq i32 %x, 16 297 %and = and i1 %c.2, %c.3 298 br i1 %and, label %then, label %exit 299 300then: 301 %c.4 = icmp eq i32 %z, 0 302 %sel = select i1 %c.4, i1 %c.1, i1 false 303 br i1 %sel, label %t.1, label %exit 304 305t.1: 306 ret i1 %c.1 307 308exit: 309 %res = phi i1 [ %c.1, %entry ], [ %sel, %then ] 310 ret i1 %res 311} 312 313declare void @use(ptr) 314 315define void @test_monotonic_ptr_iv_inc_1_eq_to_uge(ptr %start, i16 %len) { 316; CHECK-LABEL: @test_monotonic_ptr_iv_inc_1_eq_to_uge( 317; CHECK-NEXT: entry: 318; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[START:%.*]], i16 [[LEN:%.*]] 319; CHECK-NEXT: br label [[LOOP_PH:%.*]] 320; CHECK: loop.ph: 321; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 322; CHECK: loop.header: 323; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 324; CHECK-NEXT: [[LEN_NEG:%.*]] = icmp sgt i16 [[LEN]], 0 325; CHECK-NEXT: [[C:%.*]] = icmp ne ptr [[PTR_IV]], [[UPPER]] 326; CHECK-NEXT: [[AND_0:%.*]] = and i1 [[LEN_NEG]], [[C]] 327; CHECK-NEXT: br i1 [[AND_0]], label [[FOR_BODY:%.*]], label [[EXIT:%.*]] 328; CHECK: for.body: 329; CHECK-NEXT: [[T_1:%.*]] = icmp uge ptr [[PTR_IV]], [[START]] 330; CHECK-NEXT: [[T_2:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]] 331; CHECK-NEXT: [[AND:%.*]] = and i1 [[T_1]], [[T_2]] 332; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]] 333; CHECK: loop.latch: 334; CHECK-NEXT: call void @use(ptr [[PTR_IV]]) 335; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i16 1 336; CHECK-NEXT: br label [[LOOP_HEADER]] 337; CHECK: exit: 338; CHECK-NEXT: ret void 339; 340entry: 341 %upper = getelementptr inbounds i32, ptr %start, i16 %len 342 br label %loop.ph 343 344loop.ph: 345 br label %loop.header 346 347loop.header: 348 %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ] 349 %len.neg = icmp sgt i16 %len, 0 350 %c = icmp ne ptr %ptr.iv, %upper 351 %and.0 = and i1 %len.neg, %c 352 br i1 %and.0, label %for.body, label %exit 353 354for.body: 355 %t.1 = icmp uge ptr %ptr.iv, %start 356 %t.2 = icmp ult ptr %ptr.iv, %upper 357 %and = and i1 %t.1, %t.2 358 br i1 %and, label %loop.latch, label %exit 359 360loop.latch: 361 call void @use(ptr %ptr.iv) 362 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 1 363 br label %loop.header 364 365exit: 366 ret void 367} 368 369define i1 @test_and_used_in_false_branch(i8 %x) { 370; CHECK-LABEL: @test_and_used_in_false_branch( 371; CHECK-NEXT: entry: 372; CHECK-NEXT: [[C_1:%.*]] = icmp ugt i8 [[X:%.*]], 10 373; CHECK-NEXT: [[T_1:%.*]] = icmp ugt i8 [[X]], 5 374; CHECK-NEXT: [[AND:%.*]] = and i1 [[C_1]], true 375; CHECK-NEXT: br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]] 376; CHECK: then: 377; CHECK-NEXT: ret i1 true 378; CHECK: else: 379; CHECK-NEXT: ret i1 [[T_1]] 380; 381 382entry: 383 %c.1 = icmp ugt i8 %x, 10 384 %t.1 = icmp ugt i8 %x, 5 385 %and = and i1 %c.1, %t.1 386 br i1 %and, label %then, label %else 387 388then: 389 ret i1 %t.1 390 391else: 392 ret i1 %t.1 393} 394 395define i1 @test_or_used_in_false_branch(i8 %x) { 396; CHECK-LABEL: @test_or_used_in_false_branch( 397; CHECK-NEXT: entry: 398; CHECK-NEXT: [[C_1:%.*]] = icmp ule i8 [[X:%.*]], 10 399; CHECK-NEXT: [[T_1:%.*]] = icmp ule i8 [[X]], 5 400; CHECK-NEXT: [[AND:%.*]] = or i1 [[C_1]], false 401; CHECK-NEXT: br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]] 402; CHECK: then: 403; CHECK-NEXT: ret i1 [[T_1]] 404; CHECK: else: 405; CHECK-NEXT: ret i1 false 406; 407 408entry: 409 %c.1 = icmp ule i8 %x, 10 410 %t.1 = icmp ule i8 %x, 5 411 %and = or i1 %c.1, %t.1 412 br i1 %and, label %then, label %else 413 414then: 415 ret i1 %t.1 416 417else: 418 ret i1 %t.1 419} 420 421define i1 @test_or_used_in_false_branch2(i8 %x) { 422; CHECK-LABEL: @test_or_used_in_false_branch2( 423; CHECK-NEXT: entry: 424; CHECK-NEXT: [[C_1:%.*]] = icmp ugt i8 [[X:%.*]], 10 425; CHECK-NEXT: [[T_1:%.*]] = icmp ugt i8 [[X]], 5 426; CHECK-NEXT: [[AND:%.*]] = or i1 false, [[T_1]] 427; CHECK-NEXT: br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]] 428; CHECK: then: 429; CHECK-NEXT: ret i1 [[T_1]] 430; CHECK: else: 431; CHECK-NEXT: ret i1 false 432; 433 434entry: 435 %c.1 = icmp ugt i8 %x, 10 436 %t.1 = icmp ugt i8 %x, 5 437 %and = or i1 %c.1, %t.1 438 br i1 %and, label %then, label %else 439 440then: 441 ret i1 %t.1 442 443else: 444 ret i1 %t.1 445} 446 447define i1 @and_select_first_implies_second_may_be_poison(ptr noundef %A, ptr noundef %B) { 448; CHECK-LABEL: @and_select_first_implies_second_may_be_poison( 449; CHECK-NEXT: entry: 450; CHECK-NEXT: [[C_1:%.*]] = icmp ne ptr [[A:%.*]], [[B:%.*]] 451; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds ptr, ptr [[B]], i64 -1 452; CHECK-NEXT: [[C_2:%.*]] = icmp ugt ptr [[GEP]], [[A]] 453; CHECK-NEXT: [[AND:%.*]] = select i1 [[C_2]], i1 true, i1 false 454; CHECK-NEXT: ret i1 [[AND]] 455; 456entry: 457 %c.1 = icmp ne ptr %A, %B 458 %gep = getelementptr inbounds ptr, ptr %B, i64 -1 459 %c.2 = icmp ugt ptr %gep, %A 460 %and = select i1 %c.2, i1 %c.1, i1 false 461 ret i1 %and 462} 463 464define i1 @and_select_second_implies_first_may_be_poison(ptr noundef %A, ptr noundef %B) { 465; CHECK-LABEL: @and_select_second_implies_first_may_be_poison( 466; CHECK-NEXT: entry: 467; CHECK-NEXT: [[C_1:%.*]] = icmp ne ptr [[A:%.*]], [[B:%.*]] 468; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds ptr, ptr [[B]], i64 -1 469; CHECK-NEXT: [[C_2:%.*]] = icmp ugt ptr [[GEP]], [[A]] 470; CHECK-NEXT: [[AND:%.*]] = select i1 [[C_1]], i1 [[C_2]], i1 false 471; CHECK-NEXT: ret i1 [[AND]] 472; 473entry: 474 %c.1 = icmp ne ptr %A, %B 475 %gep = getelementptr inbounds ptr, ptr %B, i64 -1 476 %c.2 = icmp ugt ptr %gep, %A 477 %and = select i1 %c.1, i1 %c.2, i1 false 478 ret i1 %and 479} 480 481define i1 @and_select_second_implies_first_guaranteed_not_poison(ptr noundef %A, ptr noundef %B) { 482; CHECK-LABEL: @and_select_second_implies_first_guaranteed_not_poison( 483; CHECK-NEXT: entry: 484; CHECK-NEXT: [[C_1:%.*]] = icmp ne ptr [[A:%.*]], [[B:%.*]] 485; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds ptr, ptr [[B]], i64 -1 486; CHECK-NEXT: [[C_2:%.*]] = icmp ugt ptr [[GEP]], [[A]] 487; CHECK-NEXT: call void @no_noundef(i1 [[C_2]]) 488; CHECK-NEXT: [[AND:%.*]] = select i1 [[C_1]], i1 [[C_2]], i1 false 489; CHECK-NEXT: ret i1 [[AND]] 490; 491entry: 492 %c.1 = icmp ne ptr %A, %B 493 %gep = getelementptr inbounds ptr, ptr %B, i64 -1 494 %c.2 = icmp ugt ptr %gep, %A 495 call void @no_noundef(i1 %c.2) 496 %and = select i1 %c.1, i1 %c.2, i1 false 497 ret i1 %and 498} 499 500define void @and_tree_second_implies_first(i32 noundef %v0, i32 noundef %v1, i32 noundef %v2) { 501; CHECK-LABEL: @and_tree_second_implies_first( 502; CHECK-NEXT: entry: 503; CHECK-NEXT: [[CMP0:%.*]] = icmp sge i32 [[V0:%.*]], [[V1:%.*]] 504; CHECK-NEXT: [[CMP1:%.*]] = icmp sge i32 [[V1]], [[V2:%.*]] 505; CHECK-NEXT: [[AND1:%.*]] = and i1 [[CMP0]], [[CMP1]] 506; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[V0]], [[V2]] 507; CHECK-NEXT: [[AND2:%.*]] = and i1 false, [[AND1]] 508; CHECK-NEXT: br i1 [[AND2]], label [[IF_THEN:%.*]], label [[RETURN:%.*]] 509; CHECK: if.then: 510; CHECK-NEXT: call void @side_effect() 511; CHECK-NEXT: br label [[RETURN]] 512; CHECK: return: 513; CHECK-NEXT: ret void 514; 515entry: 516 %cmp0 = icmp sge i32 %v0, %v1 517 %cmp1 = icmp sge i32 %v1, %v2 518 %and1 = and i1 %cmp0, %cmp1 519 %cmp2 = icmp slt i32 %v0, %v2 520 %and2 = and i1 %cmp2, %and1 521 br i1 %and2, label %if.then, label %return 522 523if.then: 524 call void @side_effect() 525 br label %return 526 527return: 528 ret void 529} 530 531define void @and_tree_second_implies_first_perm1(i32 noundef %v0, i32 noundef %v1, i32 noundef %v2) { 532; CHECK-LABEL: @and_tree_second_implies_first_perm1( 533; CHECK-NEXT: entry: 534; CHECK-NEXT: [[CMP0:%.*]] = icmp sge i32 [[V0:%.*]], [[V1:%.*]] 535; CHECK-NEXT: [[CMP1:%.*]] = icmp sge i32 [[V1]], [[V2:%.*]] 536; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[V0]], [[V2]] 537; CHECK-NEXT: [[AND1:%.*]] = and i1 [[CMP2]], [[CMP1]] 538; CHECK-NEXT: [[AND2:%.*]] = and i1 false, [[AND1]] 539; CHECK-NEXT: br i1 [[AND2]], label [[IF_THEN:%.*]], label [[RETURN:%.*]] 540; CHECK: if.then: 541; CHECK-NEXT: call void @side_effect() 542; CHECK-NEXT: br label [[RETURN]] 543; CHECK: return: 544; CHECK-NEXT: ret void 545; 546entry: 547 %cmp0 = icmp sge i32 %v0, %v1 548 %cmp1 = icmp sge i32 %v1, %v2 549 %cmp2 = icmp slt i32 %v0, %v2 550 %and1 = and i1 %cmp2, %cmp1 551 %and2 = and i1 %cmp0, %and1 552 br i1 %and2, label %if.then, label %return 553 554if.then: 555 call void @side_effect() 556 br label %return 557 558return: 559 ret void 560} 561 562 563define void @and_tree_second_implies_first_perm2(i32 noundef %v0, i32 noundef %v1, i32 noundef %v2) { 564; CHECK-LABEL: @and_tree_second_implies_first_perm2( 565; CHECK-NEXT: entry: 566; CHECK-NEXT: [[CMP0:%.*]] = icmp sge i32 [[V0:%.*]], [[V1:%.*]] 567; CHECK-NEXT: [[CMP1:%.*]] = icmp sge i32 [[V1]], [[V2:%.*]] 568; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[V0]], [[V2]] 569; CHECK-NEXT: [[AND1:%.*]] = and i1 [[CMP0]], [[CMP2]] 570; CHECK-NEXT: [[AND2:%.*]] = and i1 false, [[AND1]] 571; CHECK-NEXT: br i1 [[AND2]], label [[IF_THEN:%.*]], label [[RETURN:%.*]] 572; CHECK: if.then: 573; CHECK-NEXT: call void @side_effect() 574; CHECK-NEXT: br label [[RETURN]] 575; CHECK: return: 576; CHECK-NEXT: ret void 577; 578entry: 579 %cmp0 = icmp sge i32 %v0, %v1 580 %cmp1 = icmp sge i32 %v1, %v2 581 %cmp2 = icmp slt i32 %v0, %v2 582 %and1 = and i1 %cmp0, %cmp2 583 %and2 = and i1 %cmp1, %and1 584 br i1 %and2, label %if.then, label %return 585 586if.then: 587 call void @side_effect() 588 br label %return 589 590return: 591 ret void 592} 593 594define void @logical_and_tree_second_implies_first(i32 %v0, i32 %v1, i32 %v2) { 595; CHECK-LABEL: @logical_and_tree_second_implies_first( 596; CHECK-NEXT: entry: 597; CHECK-NEXT: [[CMP0:%.*]] = icmp sge i32 [[V0:%.*]], [[V1:%.*]] 598; CHECK-NEXT: [[CMP1:%.*]] = icmp sge i32 [[V1]], [[V2:%.*]] 599; CHECK-NEXT: [[AND1:%.*]] = select i1 [[CMP0]], i1 [[CMP1]], i1 false 600; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[V0]], [[V2]] 601; CHECK-NEXT: [[AND2:%.*]] = select i1 [[CMP2]], i1 [[AND1]], i1 false 602; CHECK-NEXT: br i1 [[AND2]], label [[IF_THEN:%.*]], label [[RETURN:%.*]] 603; CHECK: if.then: 604; CHECK-NEXT: call void @side_effect() 605; CHECK-NEXT: br label [[RETURN]] 606; CHECK: return: 607; CHECK-NEXT: ret void 608; 609entry: 610 %cmp0 = icmp sge i32 %v0, %v1 611 %cmp1 = icmp sge i32 %v1, %v2 612 %and1 = select i1 %cmp0, i1 %cmp1, i1 false 613 %cmp2 = icmp slt i32 %v0, %v2 614 %and2 = select i1 %cmp2, i1 %and1, i1 false 615 br i1 %and2, label %if.then, label %return 616 617if.then: 618 call void @side_effect() 619 br label %return 620 621return: 622 ret void 623} 624 625define void @or_tree_second_implies_first(i32 noundef %v0, i32 noundef %v1, i32 noundef %v2) { 626; CHECK-LABEL: @or_tree_second_implies_first( 627; CHECK-NEXT: entry: 628; CHECK-NEXT: [[CMP0:%.*]] = icmp sge i32 [[V0:%.*]], [[V1:%.*]] 629; CHECK-NEXT: [[CMP1:%.*]] = icmp sge i32 [[V1]], [[V2:%.*]] 630; CHECK-NEXT: [[AND1:%.*]] = or i1 [[CMP0]], [[CMP1]] 631; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[V0]], [[V2]] 632; CHECK-NEXT: [[AND2:%.*]] = or i1 true, [[AND1]] 633; CHECK-NEXT: br i1 [[AND2]], label [[IF_THEN:%.*]], label [[RETURN:%.*]] 634; CHECK: if.then: 635; CHECK-NEXT: call void @side_effect() 636; CHECK-NEXT: br label [[RETURN]] 637; CHECK: return: 638; CHECK-NEXT: ret void 639; 640entry: 641 %cmp0 = icmp sge i32 %v0, %v1 642 %cmp1 = icmp sge i32 %v1, %v2 643 %and1 = or i1 %cmp0, %cmp1 644 %cmp2 = icmp slt i32 %v0, %v2 645 %and2 = or i1 %cmp2, %and1 646 br i1 %and2, label %if.then, label %return 647 648if.then: 649 call void @side_effect() 650 br label %return 651 652return: 653 ret void 654} 655 656define void @or_tree_second_implies_first_with_unknown_cond(i64 %x, i1 %cond) { 657; CHECK-LABEL: @or_tree_second_implies_first_with_unknown_cond( 658; CHECK-NEXT: entry: 659; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt i64 [[X:%.*]], 1 660; CHECK-NEXT: [[OR1:%.*]] = select i1 [[CMP1]], i1 [[COND:%.*]], i1 false 661; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i64 [[X]], 2 662; CHECK-NEXT: [[OR2:%.*]] = select i1 [[OR1]], i1 false, i1 false 663; CHECK-NEXT: br i1 [[OR2]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 664; CHECK: if.then: 665; CHECK-NEXT: call void @side_effect() 666; CHECK-NEXT: br label [[IF_END]] 667; CHECK: if.end: 668; CHECK-NEXT: ret void 669; 670entry: 671 %cmp1 = icmp ugt i64 %x, 1 672 %or1 = select i1 %cmp1, i1 %cond, i1 false 673 %cmp2 = icmp ult i64 %x, 2 674 %or2 = select i1 %or1, i1 %cmp2, i1 false 675 br i1 %or2, label %if.then, label %if.end 676 677if.then: 678 call void @side_effect() 679 br label %if.end 680 681if.end: 682 ret void 683} 684 685define void @negative_and_or_tree_second_implies_first(i32 noundef %v0, i32 noundef %v1, i32 noundef %v2) { 686; CHECK-LABEL: @negative_and_or_tree_second_implies_first( 687; CHECK-NEXT: entry: 688; CHECK-NEXT: [[CMP0:%.*]] = icmp sge i32 [[V0:%.*]], [[V1:%.*]] 689; CHECK-NEXT: [[CMP1:%.*]] = icmp sge i32 [[V1]], [[V2:%.*]] 690; CHECK-NEXT: [[AND1:%.*]] = or i1 [[CMP0]], [[CMP1]] 691; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[V0]], [[V2]] 692; CHECK-NEXT: [[AND2:%.*]] = and i1 [[CMP2]], [[AND1]] 693; CHECK-NEXT: br i1 [[AND2]], label [[IF_THEN:%.*]], label [[RETURN:%.*]] 694; CHECK: if.then: 695; CHECK-NEXT: call void @side_effect() 696; CHECK-NEXT: br label [[RETURN]] 697; CHECK: return: 698; CHECK-NEXT: ret void 699; 700entry: 701 %cmp0 = icmp sge i32 %v0, %v1 702 %cmp1 = icmp sge i32 %v1, %v2 703 %and1 = or i1 %cmp0, %cmp1 704 %cmp2 = icmp slt i32 %v0, %v2 705 %and2 = and i1 %cmp2, %and1 706 br i1 %and2, label %if.then, label %return 707 708if.then: 709 call void @side_effect() 710 br label %return 711 712return: 713 ret void 714} 715 716declare void @side_effect() 717declare void @no_noundef(i1 noundef) 718