1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -passes='simple-loop-unswitch<nontrivial>' -S < %s | FileCheck %s 3 4; If we try to replace uses of `true` outside of `@foo`, we'll see it here. 5define i1 @bar() { 6; CHECK-LABEL: @bar( 7; CHECK-NEXT: ret i1 true 8; 9 ret i1 true 10} 11 12; We shouldn't unswitch this loop. 13define void @foo() { 14; CHECK-LABEL: @foo( 15; CHECK-NEXT: entry: 16; CHECK-NEXT: br label [[HEADER:%.*]] 17; CHECK: header: 18; CHECK-NEXT: [[VAL:%.*]] = select i1 true, i1 true, i1 false 19; CHECK-NEXT: br i1 [[VAL]], label [[EXIT:%.*]], label [[HEADER]] 20; CHECK: exit: 21; CHECK-NEXT: ret void 22; 23entry: 24 br label %header 25 26header: 27 %val = select i1 true, i1 true, i1 false 28 br i1 %val, label %exit, label %header 29 30exit: 31 ret void 32} 33 34define void @unswitch_trivial_select(i1 %c.1, i1 %c.2, i8 %a) { 35; CHECK-LABEL: @unswitch_trivial_select( 36; CHECK-NEXT: entry: 37; CHECK-NEXT: br i1 [[C_1:%.*]], label [[PH_1:%.*]], label [[EXIT:%.*]] 38; CHECK: ph.1: 39; CHECK-NEXT: br i1 [[C_2:%.*]], label [[PH_2:%.*]], label [[EXIT]] 40; CHECK: ph.2: 41; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[A:%.*]], 30 42; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i1 true, i1 false 43; CHECK-NEXT: [[CMP_FR:%.*]] = freeze i1 [[CMP]] 44; CHECK-NEXT: br i1 [[CMP_FR]], label [[PH_2_SPLIT_US:%.*]], label [[PH_2_SPLIT:%.*]] 45; CHECK: ph.2.split.us: 46; CHECK-NEXT: br label [[LOOP_US:%.*]] 47; CHECK: loop.us: 48; CHECK-NEXT: call void @foo() 49; CHECK-NEXT: br label [[EXIT_LOOPEXIT_SPLIT_US:%.*]] 50; CHECK: exit.loopexit.split.us: 51; CHECK-NEXT: br label [[EXIT_LOOPEXIT:%.*]] 52; CHECK: ph.2.split: 53; CHECK-NEXT: br label [[LOOP:%.*]] 54; CHECK: loop: 55; CHECK-NEXT: call void @foo() 56; CHECK-NEXT: br label [[LOOP_LATCH:%.*]] 57; CHECK: loop.latch: 58; CHECK-NEXT: br label [[LOOP]] 59; CHECK: exit.loopexit: 60; CHECK-NEXT: br label [[EXIT]] 61; CHECK: exit: 62; CHECK-NEXT: ret void 63; 64entry: 65 br i1 %c.1, label %ph.1, label %exit 66 67ph.1: 68 br i1 %c.2, label %ph.2, label %exit 69 70ph.2: 71 %cmp = icmp eq i8 %a, 30 72 %sel = select i1 %cmp, i1 true, i1 false 73 br label %loop 74 75loop: 76 call void @foo() 77 br i1 %sel, label %exit, label %loop.latch 78 79loop.latch: 80 br label %loop 81 82exit: 83 ret void 84} 85 86; Test case for PR55697. 87define i32 @unswitch_trivial_select_cmp_outside(i32 %x) { 88; CHECK-LABEL: @unswitch_trivial_select_cmp_outside( 89; CHECK-NEXT: entry: 90; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[X:%.*]], 100 91; CHECK-NEXT: br i1 [[C]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]] 92; CHECK: entry.split.us: 93; CHECK-NEXT: br label [[LOOP_US:%.*]] 94; CHECK: loop.us: 95; CHECK-NEXT: [[P_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ 35, [[LOOP_US]] ] 96; CHECK-NEXT: br label [[LOOP_US]] 97; CHECK: entry.split: 98; CHECK-NEXT: br label [[LOOP:%.*]] 99; CHECK: loop: 100; CHECK-NEXT: [[P:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ] 101; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 false, i1 true, i1 false 102; CHECK-NEXT: br label [[EXIT:%.*]] 103; CHECK: exit: 104; CHECK-NEXT: [[LCSSA:%.*]] = phi i32 [ [[P]], [[LOOP]] ] 105; CHECK-NEXT: ret i32 [[LCSSA]] 106; 107entry: 108 %c = icmp ult i32 %x, 100 109 br label %loop 110 111loop: 112 %p = phi i32 [ 0, %entry ], [ 35, %loop ] 113 %spec.select = select i1 %c, i1 true, i1 false 114 br i1 %spec.select, label %loop, label %exit 115 116exit: 117 %lcssa = phi i32 [ %p, %loop ] 118 ret i32 %lcssa 119} 120