1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=indvars -S | FileCheck %s 3 4; This tests that the IV is recomputed outside of the loop even when it is known 5; to be computed by the loop and used in the loop any way, if it is cheap to do 6; so. In the example below the value can be computed outside of the loop, 7; and we should do so because after that IV is no longer used outside of 8; the loop, which is likely beneficial for vectorization. 9; 10; extern void func(unsigned val); 11; 12; void test(unsigned m) 13; { 14; unsigned a = 0; 15; 16; for (int i=0; i<186; i++) { 17; a += m; 18; func(a); 19; } 20; 21; func(a); 22; } 23 24declare void @func(i32) 25 26define void @test(i32 %m) nounwind uwtable { 27; CHECK-LABEL: @test( 28; CHECK-NEXT: entry: 29; CHECK-NEXT: br label [[FOR_BODY:%.*]] 30; CHECK: for.body: 31; CHECK-NEXT: [[I_06:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY]] ] 32; CHECK-NEXT: [[A_05:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ADD:%.*]], [[FOR_BODY]] ] 33; CHECK-NEXT: [[ADD]] = add i32 [[A_05]], [[M:%.*]] 34; CHECK-NEXT: tail call void @func(i32 [[ADD]]) 35; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I_06]], 1 36; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i32 [[INC]], 186 37; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_END:%.*]], label [[FOR_BODY]] 38; CHECK: for.end: 39; CHECK-NEXT: [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[FOR_BODY]] ] 40; CHECK-NEXT: tail call void @func(i32 [[ADD_LCSSA]]) 41; CHECK-NEXT: ret void 42; 43entry: 44 br label %for.body 45 46for.body: ; preds = %for.body, %entry 47 %i.06 = phi i32 [ 0, %entry ], [ %inc, %for.body ] 48 %a.05 = phi i32 [ 0, %entry ], [ %add, %for.body ] 49 %add = add i32 %a.05, %m 50 tail call void @func(i32 %add) 51 %inc = add nsw i32 %i.06, 1 52 %exitcond = icmp eq i32 %inc, 186 53 br i1 %exitcond, label %for.end, label %for.body 54 55for.end: ; preds = %for.body 56 tail call void @func(i32 %add) 57 ret void 58} 59 60define i32 @test2(i32 %m) nounwind uwtable { 61; CHECK-LABEL: @test2( 62; CHECK-NEXT: entry: 63; CHECK-NEXT: br label [[FOR_BODY:%.*]] 64; CHECK: for.body: 65; CHECK-NEXT: [[I_06:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY]] ] 66; CHECK-NEXT: [[A_05:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ADD:%.*]], [[FOR_BODY]] ] 67; CHECK-NEXT: [[ADD]] = add i32 [[A_05]], [[M:%.*]] 68; CHECK-NEXT: tail call void @func(i32 [[ADD]]) 69; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I_06]], 1 70; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i32 [[INC]], 186 71; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_END:%.*]], label [[FOR_BODY]] 72; CHECK: for.end: 73; CHECK-NEXT: [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[FOR_BODY]] ] 74; CHECK-NEXT: ret i32 [[ADD_LCSSA]] 75; 76entry: 77 br label %for.body 78 79for.body: ; preds = %for.body, %entry 80 %i.06 = phi i32 [ 0, %entry ], [ %inc, %for.body ] 81 %a.05 = phi i32 [ 0, %entry ], [ %add, %for.body ] 82 %add = add i32 %a.05, %m 83 tail call void @func(i32 %add) 84 %inc = add nsw i32 %i.06, 1 85 %exitcond = icmp eq i32 %inc, 186 86 br i1 %exitcond, label %for.end, label %for.body 87 88for.end: ; preds = %for.body 89 ret i32 %add 90} 91 92define void @test3(i32 %m) nounwind uwtable { 93; CHECK-LABEL: @test3( 94; CHECK-NEXT: entry: 95; CHECK-NEXT: br label [[FOR_BODY:%.*]] 96; CHECK: for.body: 97; CHECK-NEXT: [[I_06:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY]] ] 98; CHECK-NEXT: [[A_05:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ADD:%.*]], [[FOR_BODY]] ] 99; CHECK-NEXT: [[ADD]] = add i32 [[A_05]], [[M:%.*]] 100; CHECK-NEXT: tail call void @func(i32 [[ADD]]) 101; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I_06]], 1 102; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i32 [[INC]], 186 103; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_END:%.*]], label [[FOR_BODY]] 104; CHECK: for.end: 105; CHECK-NEXT: [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[FOR_BODY]] ] 106; CHECK-NEXT: tail call void @func(i32 [[ADD_LCSSA]]) 107; CHECK-NEXT: ret void 108; 109entry: 110 br label %for.body 111 112for.body: ; preds = %for.body, %entry 113 %i.06 = phi i32 [ 0, %entry ], [ %inc, %for.body ] 114 %a.05 = phi i32 [ 0, %entry ], [ %add, %for.body ] 115 %add = add i32 %a.05, %m 116 mul i32 %add, 1 117 mul i32 %add, 1 118 mul i32 %add, 1 119 mul i32 %add, 1 120 mul i32 %add, 1 121 mul i32 %add, 1 122 tail call void @func(i32 %add) 123 %inc = add nsw i32 %i.06, 1 124 %exitcond = icmp eq i32 %inc, 186 125 br i1 %exitcond, label %for.end, label %for.body 126 127for.end: ; preds = %for.body 128 tail call void @func(i32 %add) 129 ret void 130} 131 132define void @test4(i32 %m) nounwind uwtable { 133; CHECK-LABEL: @test4( 134; CHECK-NEXT: entry: 135; CHECK-NEXT: br label [[FOR_BODY:%.*]] 136; CHECK: for.body: 137; CHECK-NEXT: [[I_06:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY]] ] 138; CHECK-NEXT: [[A_05:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ADD:%.*]], [[FOR_BODY]] ] 139; CHECK-NEXT: [[ADD]] = add i32 [[A_05]], [[M:%.*]] 140; CHECK-NEXT: tail call void @func(i32 [[ADD]]) 141; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I_06]], 1 142; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i32 [[INC]], 186 143; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_END:%.*]], label [[FOR_BODY]] 144; CHECK: for.end: 145; CHECK-NEXT: [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[FOR_BODY]] ] 146; CHECK-NEXT: [[SOFT_USE:%.*]] = add i32 [[ADD_LCSSA]], 123 147; CHECK-NEXT: tail call void @func(i32 [[SOFT_USE]]) 148; CHECK-NEXT: ret void 149; 150entry: 151 br label %for.body 152 153for.body: ; preds = %for.body, %entry 154 %i.06 = phi i32 [ 0, %entry ], [ %inc, %for.body ] 155 %a.05 = phi i32 [ 0, %entry ], [ %add, %for.body ] 156 %add = add i32 %a.05, %m 157 tail call void @func(i32 %add) 158 %inc = add nsw i32 %i.06, 1 159 %exitcond = icmp eq i32 %inc, 186 160 br i1 %exitcond, label %for.end, label %for.body 161 162for.end: ; preds = %for.body 163 %soft_use = add i32 %add, 123 164 tail call void @func(i32 %soft_use) 165 ret void 166} 167 168define void @test5(i32 %m) nounwind uwtable { 169; CHECK-LABEL: @test5( 170; CHECK-NEXT: entry: 171; CHECK-NEXT: br label [[FOR_BODY:%.*]] 172; CHECK: for.body: 173; CHECK-NEXT: [[I_06:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY]] ] 174; CHECK-NEXT: [[A_05:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ADD:%.*]], [[FOR_BODY]] ] 175; CHECK-NEXT: [[ADD]] = add i32 [[A_05]], [[M:%.*]] 176; CHECK-NEXT: [[SOFT_USE:%.*]] = add i32 [[ADD]], 123 177; CHECK-NEXT: tail call void @func(i32 [[SOFT_USE]]) 178; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I_06]], 1 179; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i32 [[INC]], 186 180; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_END:%.*]], label [[FOR_BODY]] 181; CHECK: for.end: 182; CHECK-NEXT: [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[FOR_BODY]] ] 183; CHECK-NEXT: tail call void @func(i32 [[ADD_LCSSA]]) 184; CHECK-NEXT: ret void 185; 186entry: 187 br label %for.body 188 189for.body: ; preds = %for.body, %entry 190 %i.06 = phi i32 [ 0, %entry ], [ %inc, %for.body ] 191 %a.05 = phi i32 [ 0, %entry ], [ %add, %for.body ] 192 %add = add i32 %a.05, %m 193 %soft_use = add i32 %add, 123 194 tail call void @func(i32 %soft_use) 195 %inc = add nsw i32 %i.06, 1 196 %exitcond = icmp eq i32 %inc, 186 197 br i1 %exitcond, label %for.end, label %for.body 198 199for.end: ; preds = %for.body 200 tail call void @func(i32 %add) 201 ret void 202} 203 204define void @test6(i32 %m, ptr %p) nounwind uwtable { 205; CHECK-LABEL: @test6( 206; CHECK-NEXT: entry: 207; CHECK-NEXT: br label [[FOR_BODY:%.*]] 208; CHECK: for.body: 209; CHECK-NEXT: [[I_06:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY]] ] 210; CHECK-NEXT: [[A_05:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ADD:%.*]], [[FOR_BODY]] ] 211; CHECK-NEXT: [[ADD]] = add i32 [[A_05]], [[M:%.*]] 212; CHECK-NEXT: [[SOFT_USE:%.*]] = add i32 [[ADD]], 123 213; CHECK-NEXT: [[PIDX:%.*]] = getelementptr i32, ptr [[P:%.*]], i32 [[ADD]] 214; CHECK-NEXT: store i32 [[SOFT_USE]], ptr [[PIDX]] 215; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I_06]], 1 216; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i32 [[INC]], 186 217; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_END:%.*]], label [[FOR_BODY]] 218; CHECK: for.end: 219; CHECK-NEXT: [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[FOR_BODY]] ] 220; CHECK-NEXT: tail call void @func(i32 [[ADD_LCSSA]]) 221; CHECK-NEXT: ret void 222; 223entry: 224 br label %for.body 225 226for.body: ; preds = %for.body, %entry 227 %i.06 = phi i32 [ 0, %entry ], [ %inc, %for.body ] 228 %a.05 = phi i32 [ 0, %entry ], [ %add, %for.body ] 229 %add = add i32 %a.05, %m 230 %soft_use = add i32 %add, 123 231 %pidx = getelementptr i32, ptr %p, i32 %add 232 store i32 %soft_use, ptr %pidx 233 %inc = add nsw i32 %i.06, 1 234 %exitcond = icmp eq i32 %inc, 186 235 br i1 %exitcond, label %for.end, label %for.body 236 237for.end: ; preds = %for.body 238 tail call void @func(i32 %add) 239 ret void 240} 241