1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -S -enable-loop-simplifycfg-term-folding=true -passes='require<domtree>,loop(loop-simplifycfg)' -verify-loop-info -verify-dom-info -verify-loop-lcssa < %s | FileCheck %s 3; RUN: opt -S -enable-loop-simplifycfg-term-folding=true -passes=loop-simplifycfg -verify-memoryssa -verify-loop-info -verify-dom-info -verify-loop-lcssa < %s | FileCheck %s 4 5target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128" 6 7define void @c() { 8; CHECK-LABEL: @c( 9; CHECK-NEXT: entry: 10; CHECK-NEXT: br label [[D:%.*]] 11; CHECK: d.loopexit: 12; CHECK-NEXT: [[DOTLCSSA:%.*]] = phi i32 [ [[TMP1:%.*]], [[FOR_COND:%.*]] ] 13; CHECK-NEXT: br label [[D]] 14; CHECK: d: 15; CHECK-NEXT: [[TMP0:%.*]] = phi i32 [ undef, [[ENTRY:%.*]] ], [ [[DOTLCSSA]], [[D_LOOPEXIT:%.*]] ] 16; CHECK-NEXT: br label [[FOR_COND]] 17; CHECK: for.cond: 18; CHECK-NEXT: [[TMP1]] = phi i32 [ [[TMP0]], [[D]] ], [ 0, [[IF_END:%.*]] ] 19; CHECK-NEXT: [[TOBOOL2:%.*]] = icmp eq i32 [[TMP1]], 0 20; CHECK-NEXT: br i1 [[TOBOOL2]], label [[IF_END]], label [[D_LOOPEXIT]] 21; CHECK: if.end: 22; CHECK-NEXT: br label [[FOR_COND]] 23; 24entry: 25 br label %d 26 27d.loopexit: ; preds = %if.end.7, %for.body 28 %.lcssa = phi i32 [ %1, %for.body ], [ 0, %if.end.7 ] 29 br label %d 30 31d: ; preds = %d.loopexit, %entry 32 %0 = phi i32 [ undef, %entry ], [ %.lcssa, %d.loopexit ] 33 br label %for.cond 34 35for.cond: ; preds = %if.end.8, %d 36 %1 = phi i32 [ %0, %d ], [ 0, %if.end.8 ] 37 br label %for.body 38 39for.body: ; preds = %for.cond 40 %tobool2 = icmp eq i32 %1, 0 41 br i1 %tobool2, label %if.end, label %d.loopexit 42 43if.end: ; preds = %for.body 44 br label %if.end.7 45 46if.end.7: ; preds = %if.end 47 br i1 true, label %if.end.8, label %d.loopexit 48 49if.end.8: ; preds = %if.end.7 50 br label %for.cond 51} 52 53define void @test_01() { 54; CHECK-LABEL: @test_01( 55; CHECK-NEXT: entry: 56; CHECK-NEXT: br label [[FOR_COND:%.*]] 57; CHECK: for.cond.loopexit: 58; CHECK-NEXT: br label [[FOR_COND]] 59; CHECK: for.cond: 60; CHECK-NEXT: [[INC41_LCSSA3:%.*]] = phi i16 [ poison, [[FOR_COND_LOOPEXIT:%.*]] ], [ undef, [[ENTRY:%.*]] ] 61; CHECK-NEXT: switch i32 0, label [[FOR_COND_SPLIT:%.*]] [ 62; CHECK-NEXT: i32 1, label [[FOR_COND_LOOPEXIT]] 63; CHECK-NEXT: ] 64; CHECK: for.cond.split: 65; CHECK-NEXT: [[INC41_LCSSA3_LCSSA:%.*]] = phi i16 [ [[INC41_LCSSA3]], [[FOR_COND]] ] 66; CHECK-NEXT: br label [[WHILE_COND:%.*]] 67; CHECK: while.cond: 68; CHECK-NEXT: [[INC41:%.*]] = phi i16 [ [[INC4:%.*]], [[WHILE_COND]] ], [ [[INC41_LCSSA3_LCSSA]], [[FOR_COND_SPLIT]] ] 69; CHECK-NEXT: [[INC4]] = add nsw i16 [[INC41]], 1 70; CHECK-NEXT: br label [[WHILE_COND]] 71; 72entry: 73 br label %for.cond 74 75for.cond.loopexit: ; preds = %while.cond 76 %inc41.lcssa = phi i16 [ %inc41, %while.cond ] 77 br label %for.cond 78 79for.cond: ; preds = %for.cond.loopexit, %entry 80 %inc41.lcssa3 = phi i16 [ %inc41.lcssa, %for.cond.loopexit ], [ undef, %entry ] 81 br label %while.cond 82 83while.cond: ; preds = %while.body, %for.cond 84 %inc41 = phi i16 [ %inc4, %while.body ], [ %inc41.lcssa3, %for.cond ] 85 br i1 true, label %while.body, label %for.cond.loopexit 86 87while.body: ; preds = %while.cond 88 %inc4 = add nsw i16 %inc41, 1 89 br label %while.cond 90} 91 92define void @bar() { 93; CHECK-LABEL: @bar( 94; CHECK-NEXT: bb: 95; CHECK-NEXT: switch i32 0, label [[BB_SPLIT:%.*]] [ 96; CHECK-NEXT: i32 1, label [[BB10:%.*]] 97; CHECK-NEXT: ] 98; CHECK: bb.split: 99; CHECK-NEXT: br label [[BB1:%.*]] 100; CHECK: bb1: 101; CHECK-NEXT: [[TMP:%.*]] = phi i32 [ [[TMP7:%.*]], [[BB6:%.*]] ], [ undef, [[BB_SPLIT]] ] 102; CHECK-NEXT: switch i32 undef, label [[BB5:%.*]] [ 103; CHECK-NEXT: i32 0, label [[BB6]] 104; CHECK-NEXT: i32 1, label [[BB8:%.*]] 105; CHECK-NEXT: ] 106; CHECK: bb5: 107; CHECK-NEXT: ret void 108; CHECK: bb6: 109; CHECK-NEXT: [[TMP7]] = add i32 undef, 123 110; CHECK-NEXT: br label [[BB1]] 111; CHECK: bb8: 112; CHECK-NEXT: [[TMP9:%.*]] = phi i32 [ [[TMP]], [[BB1]] ] 113; CHECK-NEXT: [[USE:%.*]] = add i32 [[TMP9]], 1 114; CHECK-NEXT: ret void 115; CHECK: bb10: 116; CHECK-NEXT: ret void 117; 118 119bb: 120 br label %bb1 121 122bb1: ; preds = %bb6, %bb 123 %tmp = phi i32 [ %tmp7, %bb6 ], [ undef, %bb ] 124 br i1 false, label %bb2, label %bb4 125 126bb2: ; preds = %bb1 127 switch i32 undef, label %bb10 [ 128 i32 0, label %bb3 129 i32 1, label %bb8 130 ] 131 132bb3: ; preds = %bb2 133 br label %bb6 134 135bb4: ; preds = %bb1 136 switch i32 undef, label %bb5 [ 137 i32 0, label %bb6 138 i32 1, label %bb8 139 ] 140 141bb5: ; preds = %bb4 142 ret void 143 144bb6: ; preds = %bb4, %bb3 145 %tmp7 = add i32 undef, 123 146 br label %bb1 147 148bb8: ; preds = %bb4, %bb2 149 %tmp9 = phi i32 [ %tmp, %bb2 ], [ %tmp, %bb4 ] 150 %use = add i32 %tmp9, 1 151 ret void 152 153bb10: ; preds = %bb2 154 ret void 155} 156 157define void @memlcssa() { 158; CHECK-LABEL: @memlcssa( 159; CHECK-NEXT: entry: 160; CHECK-NEXT: switch i32 0, label [[ENTRY_SPLIT:%.*]] [ 161; CHECK-NEXT: i32 1, label [[DEFAULT_BB:%.*]] 162; CHECK-NEXT: ] 163; CHECK: entry.split: 164; CHECK-NEXT: br label [[FOR_BODY:%.*]] 165; CHECK: for.body: 166; CHECK-NEXT: call void @foo() 167; CHECK-NEXT: br label [[FOR_BODY]] 168; CHECK: default.bb: 169; CHECK-NEXT: unreachable 170; 171entry: 172 br label %for.body 173 174for.body: ; preds = %exit, %entry 175 br label %switch.bb 176 177switch.bb: ; preds = %for.body 178 switch i2 1, label %default.bb [ 179 i2 1, label %case.bb 180 ] 181 182case.bb: ; preds = %switch 183 br label %exit 184 185default.bb: ; preds = %switch 186 unreachable 187 188exit: ; preds = %case.bb 189 call void @foo() 190 br label %for.body 191} 192 193declare void @foo() 194