321 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -passes=loop-idiom < %s -S | FileCheck %s3target datalayout = "e-p:40:64:64:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"4 5%struct.foo = type { i32, i32 }6%struct.foo1 = type { i32, i32, i32 }7%struct.foo2 = type { i32, i16, i16 }8 9;void bar1(foo_t *f, unsigned n) {10; for (unsigned i = 0; i < n; ++i) {11; f[i].a = 0;12; f[i].b = 0;13; }14;}15define void @bar1(ptr %f, i32 %n) nounwind ssp {16; CHECK-LABEL: @bar1(17; CHECK-NEXT: entry:18; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[N:%.*]], 019; CHECK-NEXT: br i1 [[CMP1]], label [[FOR_END:%.*]], label [[FOR_BODY_PREHEADER:%.*]]20; CHECK: for.body.preheader:21; CHECK-NEXT: [[TMP0:%.*]] = shl nuw i32 [[N]], 322; CHECK-NEXT: call void @llvm.memset.p0.i32(ptr align 4 [[F:%.*]], i8 0, i32 [[TMP0]], i1 false)23; CHECK-NEXT: br label [[FOR_BODY:%.*]]24; CHECK: for.body:25; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i32 [ 0, [[FOR_BODY_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ]26; CHECK-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_FOO:%.*]], ptr [[F]], i32 [[INDVARS_IV]], i32 027; CHECK-NEXT: [[B:%.*]] = getelementptr inbounds [[STRUCT_FOO]], ptr [[F]], i32 [[INDVARS_IV]], i32 128; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i32 [[INDVARS_IV]], 129; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[INDVARS_IV_NEXT]], [[N]]30; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_BODY]], label [[FOR_END_LOOPEXIT:%.*]]31; CHECK: for.end.loopexit:32; CHECK-NEXT: br label [[FOR_END]]33; CHECK: for.end:34; CHECK-NEXT: ret void35;36entry:37 %cmp1 = icmp eq i32 %n, 038 br i1 %cmp1, label %for.end, label %for.body.preheader39 40for.body.preheader: ; preds = %entry41 br label %for.body42 43for.body: ; preds = %for.body.preheader, %for.body44 %indvars.iv = phi i32 [ 0, %for.body.preheader ], [ %indvars.iv.next, %for.body ]45 %a = getelementptr inbounds %struct.foo, ptr %f, i32 %indvars.iv, i32 046 store i32 0, ptr %a, align 447 %b = getelementptr inbounds %struct.foo, ptr %f, i32 %indvars.iv, i32 148 store i32 0, ptr %b, align 449 %indvars.iv.next = add nuw nsw i32 %indvars.iv, 150 %exitcond = icmp ne i32 %indvars.iv.next, %n51 br i1 %exitcond, label %for.body, label %for.end.loopexit52 53for.end.loopexit: ; preds = %for.body54 br label %for.end55 56for.end: ; preds = %for.end.loopexit, %entry57 ret void58}59 60;void bar2(foo_t *f, unsigned n) {61; for (unsigned i = 0; i < n; ++i) {62; f[i].b = 0;63; f[i].a = 0;64; }65;}66define void @bar2(ptr %f, i32 %n) nounwind ssp {67; CHECK-LABEL: @bar2(68; CHECK-NEXT: entry:69; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[N:%.*]], 070; CHECK-NEXT: br i1 [[CMP1]], label [[FOR_END:%.*]], label [[FOR_BODY_PREHEADER:%.*]]71; CHECK: for.body.preheader:72; CHECK-NEXT: [[TMP0:%.*]] = shl nuw i32 [[N]], 373; CHECK-NEXT: call void @llvm.memset.p0.i32(ptr align 4 [[F:%.*]], i8 0, i32 [[TMP0]], i1 false)74; CHECK-NEXT: br label [[FOR_BODY:%.*]]75; CHECK: for.body:76; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i32 [ 0, [[FOR_BODY_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ]77; CHECK-NEXT: [[B:%.*]] = getelementptr inbounds [[STRUCT_FOO:%.*]], ptr [[F]], i32 [[INDVARS_IV]], i32 178; CHECK-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_FOO]], ptr [[F]], i32 [[INDVARS_IV]], i32 079; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i32 [[INDVARS_IV]], 180; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[INDVARS_IV_NEXT]], [[N]]81; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_BODY]], label [[FOR_END_LOOPEXIT:%.*]]82; CHECK: for.end.loopexit:83; CHECK-NEXT: br label [[FOR_END]]84; CHECK: for.end:85; CHECK-NEXT: ret void86;87entry:88 %cmp1 = icmp eq i32 %n, 089 br i1 %cmp1, label %for.end, label %for.body.preheader90 91for.body.preheader: ; preds = %entry92 br label %for.body93 94for.body: ; preds = %for.body.preheader, %for.body95 %indvars.iv = phi i32 [ 0, %for.body.preheader ], [ %indvars.iv.next, %for.body ]96 %b = getelementptr inbounds %struct.foo, ptr %f, i32 %indvars.iv, i32 197 store i32 0, ptr %b, align 498 %a = getelementptr inbounds %struct.foo, ptr %f, i32 %indvars.iv, i32 099 store i32 0, ptr %a, align 4100 %indvars.iv.next = add nuw nsw i32 %indvars.iv, 1101 %exitcond = icmp ne i32 %indvars.iv.next, %n102 br i1 %exitcond, label %for.body, label %for.end.loopexit103 104for.end.loopexit: ; preds = %for.body105 br label %for.end106 107for.end: ; preds = %for.end.loopexit, %entry108 ret void109}110 111;void bar3(foo_t *f, unsigned n) {112; for (unsigned i = n; i > 0; --i) {113; f[i].a = 0;114; f[i].b = 0;115; }116;}117define void @bar3(ptr nocapture %f, i32 %n) nounwind ssp {118; CHECK-LABEL: @bar3(119; CHECK-NEXT: entry:120; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[N:%.*]], 0121; CHECK-NEXT: br i1 [[CMP1]], label [[FOR_END:%.*]], label [[FOR_BODY_PREHEADER:%.*]]122; CHECK: for.body.preheader:123; CHECK-NEXT: [[UGLYGEP:%.*]] = getelementptr i8, ptr [[F:%.*]], i32 8124; CHECK-NEXT: [[TMP0:%.*]] = shl nuw i32 [[N]], 3125; CHECK-NEXT: call void @llvm.memset.p0.i32(ptr align 4 [[UGLYGEP]], i8 0, i32 [[TMP0]], i1 false)126; CHECK-NEXT: br label [[FOR_BODY:%.*]]127; CHECK: for.body:128; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i32 [ [[N]], [[FOR_BODY_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ]129; CHECK-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_FOO:%.*]], ptr [[F]], i32 [[INDVARS_IV]], i32 0130; CHECK-NEXT: [[B:%.*]] = getelementptr inbounds [[STRUCT_FOO]], ptr [[F]], i32 [[INDVARS_IV]], i32 1131; CHECK-NEXT: [[DEC:%.*]] = add i32 [[INDVARS_IV]], -1132; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[DEC]], 0133; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i32 [[INDVARS_IV]], -1134; CHECK-NEXT: br i1 [[CMP]], label [[FOR_END_LOOPEXIT:%.*]], label [[FOR_BODY]]135; CHECK: for.end.loopexit:136; CHECK-NEXT: br label [[FOR_END]]137; CHECK: for.end:138; CHECK-NEXT: ret void139;140entry:141 %cmp1 = icmp eq i32 %n, 0142 br i1 %cmp1, label %for.end, label %for.body.preheader143 144for.body.preheader: ; preds = %entry145 br label %for.body146 147for.body: ; preds = %for.body.preheader, %for.body148 %indvars.iv = phi i32 [ %n, %for.body.preheader ], [ %indvars.iv.next, %for.body ]149 %a = getelementptr inbounds %struct.foo, ptr %f, i32 %indvars.iv, i32 0150 store i32 0, ptr %a, align 4151 %b = getelementptr inbounds %struct.foo, ptr %f, i32 %indvars.iv, i32 1152 store i32 0, ptr %b, align 4153 %dec = add i32 %indvars.iv, -1154 %cmp = icmp eq i32 %dec, 0155 %indvars.iv.next = add nsw i32 %indvars.iv, -1156 br i1 %cmp, label %for.end.loopexit, label %for.body157 158for.end.loopexit: ; preds = %for.body159 br label %for.end160 161for.end: ; preds = %for.end.loopexit, %entry162 ret void163}164 165;void bar4(foo_t *f, unsigned n) {166; for (unsigned i = 0; i < n; ++i) {167; f[i].a = 0;168; f[i].b = 1;169; }170;}171define void @bar4(ptr nocapture %f, i32 %n) nounwind ssp {172; CHECK-LABEL: @bar4(173; CHECK-NEXT: entry:174; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[N:%.*]], 0175; CHECK-NEXT: br i1 [[CMP1]], label [[FOR_END:%.*]], label [[FOR_BODY_PREHEADER:%.*]]176; CHECK: for.body.preheader:177; CHECK-NEXT: br label [[FOR_BODY:%.*]]178; CHECK: for.body:179; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i32 [ 0, [[FOR_BODY_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ]180; CHECK-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_FOO:%.*]], ptr [[F:%.*]], i32 [[INDVARS_IV]], i32 0181; CHECK-NEXT: store i32 0, ptr [[A]], align 4182; CHECK-NEXT: [[B:%.*]] = getelementptr inbounds [[STRUCT_FOO]], ptr [[F]], i32 [[INDVARS_IV]], i32 1183; CHECK-NEXT: store i32 1, ptr [[B]], align 4184; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i32 [[INDVARS_IV]], 1185; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[INDVARS_IV_NEXT]], [[N]]186; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_BODY]], label [[FOR_END_LOOPEXIT:%.*]]187; CHECK: for.end.loopexit:188; CHECK-NEXT: br label [[FOR_END]]189; CHECK: for.end:190; CHECK-NEXT: ret void191;192entry:193 %cmp1 = icmp eq i32 %n, 0194 br i1 %cmp1, label %for.end, label %for.body.preheader195 196for.body.preheader: ; preds = %entry197 br label %for.body198 199for.body: ; preds = %for.body.preheader, %for.body200 %indvars.iv = phi i32 [ 0, %for.body.preheader ], [ %indvars.iv.next, %for.body ]201 %a = getelementptr inbounds %struct.foo, ptr %f, i32 %indvars.iv, i32 0202 store i32 0, ptr %a, align 4203 %b = getelementptr inbounds %struct.foo, ptr %f, i32 %indvars.iv, i32 1204 store i32 1, ptr %b, align 4205 %indvars.iv.next = add nuw nsw i32 %indvars.iv, 1206 %exitcond = icmp ne i32 %indvars.iv.next, %n207 br i1 %exitcond, label %for.body, label %for.end.loopexit208 209for.end.loopexit: ; preds = %for.body210 br label %for.end211 212for.end: ; preds = %for.end.loopexit, %entry213 ret void214}215 216;void bar5(foo1_t *f, unsigned n) {217; for (unsigned i = 0; i < n; ++i) {218; f[i].a = 0;219; f[i].b = 0;220; }221;}222define void @bar5(ptr nocapture %f, i32 %n) nounwind ssp {223; CHECK-LABEL: @bar5(224; CHECK-NEXT: entry:225; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[N:%.*]], 0226; CHECK-NEXT: br i1 [[CMP1]], label [[FOR_END:%.*]], label [[FOR_BODY_PREHEADER:%.*]]227; CHECK: for.body.preheader:228; CHECK-NEXT: br label [[FOR_BODY:%.*]]229; CHECK: for.body:230; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i32 [ 0, [[FOR_BODY_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ]231; CHECK-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_FOO1:%.*]], ptr [[F:%.*]], i32 [[INDVARS_IV]], i32 0232; CHECK-NEXT: store i32 0, ptr [[A]], align 4233; CHECK-NEXT: [[B:%.*]] = getelementptr inbounds [[STRUCT_FOO1]], ptr [[F]], i32 [[INDVARS_IV]], i32 1234; CHECK-NEXT: store i32 0, ptr [[B]], align 4235; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i32 [[INDVARS_IV]], 1236; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[INDVARS_IV_NEXT]], [[N]]237; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_BODY]], label [[FOR_END_LOOPEXIT:%.*]]238; CHECK: for.end.loopexit:239; CHECK-NEXT: br label [[FOR_END]]240; CHECK: for.end:241; CHECK-NEXT: ret void242;243entry:244 %cmp1 = icmp eq i32 %n, 0245 br i1 %cmp1, label %for.end, label %for.body.preheader246 247for.body.preheader: ; preds = %entry248 br label %for.body249 250for.body: ; preds = %for.body.preheader, %for.body251 %indvars.iv = phi i32 [ 0, %for.body.preheader ], [ %indvars.iv.next, %for.body ]252 %a = getelementptr inbounds %struct.foo1, ptr %f, i32 %indvars.iv, i32 0253 store i32 0, ptr %a, align 4254 %b = getelementptr inbounds %struct.foo1, ptr %f, i32 %indvars.iv, i32 1255 store i32 0, ptr %b, align 4256 %indvars.iv.next = add nuw nsw i32 %indvars.iv, 1257 %exitcond = icmp ne i32 %indvars.iv.next, %n258 br i1 %exitcond, label %for.body, label %for.end.loopexit259 260for.end.loopexit: ; preds = %for.body261 br label %for.end262 263for.end: ; preds = %for.end.loopexit, %entry264 ret void265}266 267;void bar6(foo2_t *f, unsigned n) {268; for (unsigned i = 0; i < n; ++i) {269; f[i].a = 0;270; f[i].b = 0;271; f[i].c = 0;272; }273;}274define void @bar6(ptr nocapture %f, i32 %n) nounwind ssp {275; CHECK-LABEL: @bar6(276; CHECK-NEXT: entry:277; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[N:%.*]], 0278; CHECK-NEXT: br i1 [[CMP1]], label [[FOR_END:%.*]], label [[FOR_BODY_PREHEADER:%.*]]279; CHECK: for.body.preheader:280; CHECK-NEXT: [[TMP0:%.*]] = shl nuw i32 [[N]], 3281; CHECK-NEXT: call void @llvm.memset.p0.i32(ptr align 4 [[F:%.*]], i8 0, i32 [[TMP0]], i1 false)282; CHECK-NEXT: br label [[FOR_BODY:%.*]]283; CHECK: for.body:284; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i32 [ 0, [[FOR_BODY_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ]285; CHECK-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_FOO2:%.*]], ptr [[F]], i32 [[INDVARS_IV]], i32 0286; CHECK-NEXT: [[B:%.*]] = getelementptr inbounds [[STRUCT_FOO2]], ptr [[F]], i32 [[INDVARS_IV]], i32 1287; CHECK-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_FOO2]], ptr [[F]], i32 [[INDVARS_IV]], i32 2288; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i32 [[INDVARS_IV]], 1289; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[INDVARS_IV_NEXT]], [[N]]290; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_BODY]], label [[FOR_END_LOOPEXIT:%.*]]291; CHECK: for.end.loopexit:292; CHECK-NEXT: br label [[FOR_END]]293; CHECK: for.end:294; CHECK-NEXT: ret void295;296entry:297 %cmp1 = icmp eq i32 %n, 0298 br i1 %cmp1, label %for.end, label %for.body.preheader299 300for.body.preheader: ; preds = %entry301 br label %for.body302 303for.body: ; preds = %for.body.preheader, %for.body304 %indvars.iv = phi i32 [ 0, %for.body.preheader ], [ %indvars.iv.next, %for.body ]305 %a = getelementptr inbounds %struct.foo2, ptr %f, i32 %indvars.iv, i32 0306 store i32 0, ptr %a, align 4307 %b = getelementptr inbounds %struct.foo2, ptr %f, i32 %indvars.iv, i32 1308 store i16 0, ptr %b, align 4309 %c = getelementptr inbounds %struct.foo2, ptr %f, i32 %indvars.iv, i32 2310 store i16 0, ptr %c, align 2311 %indvars.iv.next = add nuw nsw i32 %indvars.iv, 1312 %exitcond = icmp ne i32 %indvars.iv.next, %n313 br i1 %exitcond, label %for.body, label %for.end.loopexit314 315for.end.loopexit: ; preds = %for.body316 br label %for.end317 318for.end: ; preds = %for.end.loopexit, %entry319 ret void320}321