1; RUN: opt -basicaa -loop-idiom < %s -S | FileCheck %s 2target datalayout = "e-p:64:64:64-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" 3 4; CHECK: @.memset_pattern = private unnamed_addr constant [4 x i32] [i32 2, i32 2, i32 2, i32 2], align 16 5; CHECK: @.memset_pattern.1 = private unnamed_addr constant [4 x i32] [i32 2, i32 2, i32 2, i32 2], align 16 6; CHECK: @.memset_pattern.2 = private unnamed_addr constant [4 x i32] [i32 2, i32 2, i32 2, i32 2], align 16 7 8target triple = "x86_64-apple-darwin10.0.0" 9 10%struct.foo = type { i32, i32 } 11%struct.foo1 = type { i32, i32, i32 } 12 13;void bar1(foo_t *f, unsigned n) { 14; for (unsigned i = 0; i < n; ++i) { 15; f[i].a = 2; 16; f[i].b = 2; 17; } 18;} 19define void @bar1(%struct.foo* %f, i32 %n) nounwind ssp { 20entry: 21 %cmp1 = icmp eq i32 %n, 0 22 br i1 %cmp1, label %for.end, label %for.body.preheader 23 24for.body.preheader: ; preds = %entry 25 br label %for.body 26 27for.body: ; preds = %for.body.preheader, %for.body 28 %indvars.iv = phi i64 [ 0, %for.body.preheader ], [ %indvars.iv.next, %for.body ] 29 %a = getelementptr inbounds %struct.foo, %struct.foo* %f, i64 %indvars.iv, i32 0 30 store i32 2, i32* %a, align 4 31 %b = getelementptr inbounds %struct.foo, %struct.foo* %f, i64 %indvars.iv, i32 1 32 store i32 2, i32* %b, align 4 33 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 34 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 35 %exitcond = icmp ne i32 %lftr.wideiv, %n 36 br i1 %exitcond, label %for.body, label %for.end.loopexit 37 38for.end.loopexit: ; preds = %for.body 39 br label %for.end 40 41for.end: ; preds = %for.end.loopexit, %entry 42 ret void 43; CHECK-LABEL: @bar1( 44; CHECK: call void @memset_pattern16 45; CHECK-NOT: store 46} 47 48;void bar2(foo_t *f, unsigned n) { 49; for (unsigned i = 0; i < n; ++i) { 50; f[i].b = 2; 51; f[i].a = 2; 52; } 53;} 54define void @bar2(%struct.foo* %f, i32 %n) nounwind ssp { 55entry: 56 %cmp1 = icmp eq i32 %n, 0 57 br i1 %cmp1, label %for.end, label %for.body.preheader 58 59for.body.preheader: ; preds = %entry 60 br label %for.body 61 62for.body: ; preds = %for.body.preheader, %for.body 63 %indvars.iv = phi i64 [ 0, %for.body.preheader ], [ %indvars.iv.next, %for.body ] 64 %b = getelementptr inbounds %struct.foo, %struct.foo* %f, i64 %indvars.iv, i32 1 65 store i32 2, i32* %b, align 4 66 %a = getelementptr inbounds %struct.foo, %struct.foo* %f, i64 %indvars.iv, i32 0 67 store i32 2, i32* %a, align 4 68 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 69 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 70 %exitcond = icmp ne i32 %lftr.wideiv, %n 71 br i1 %exitcond, label %for.body, label %for.end.loopexit 72 73for.end.loopexit: ; preds = %for.body 74 br label %for.end 75 76for.end: ; preds = %for.end.loopexit, %entry 77 ret void 78; CHECK-LABEL: @bar2( 79; CHECK: call void @memset_pattern16 80; CHECK-NOT: store 81} 82 83;void bar3(foo_t *f, unsigned n) { 84; for (unsigned i = n; i > 0; --i) { 85; f[i].a = 2; 86; f[i].b = 2; 87; } 88;} 89define void @bar3(%struct.foo* nocapture %f, i32 %n) nounwind ssp { 90entry: 91 %cmp1 = icmp eq i32 %n, 0 92 br i1 %cmp1, label %for.end, label %for.body.preheader 93 94for.body.preheader: ; preds = %entry 95 %0 = zext i32 %n to i64 96 br label %for.body 97 98for.body: ; preds = %for.body.preheader, %for.body 99 %indvars.iv = phi i64 [ %0, %for.body.preheader ], [ %indvars.iv.next, %for.body ] 100 %a = getelementptr inbounds %struct.foo, %struct.foo* %f, i64 %indvars.iv, i32 0 101 store i32 2, i32* %a, align 4 102 %b = getelementptr inbounds %struct.foo, %struct.foo* %f, i64 %indvars.iv, i32 1 103 store i32 2, i32* %b, align 4 104 %1 = trunc i64 %indvars.iv to i32 105 %dec = add i32 %1, -1 106 %cmp = icmp eq i32 %dec, 0 107 %indvars.iv.next = add nsw i64 %indvars.iv, -1 108 br i1 %cmp, label %for.end.loopexit, label %for.body 109 110for.end.loopexit: ; preds = %for.body 111 br label %for.end 112 113for.end: ; preds = %for.end.loopexit, %entry 114 ret void 115; CHECK-LABEL: @bar3( 116; CHECK: call void @memset_pattern16 117; CHECK-NOT: store 118} 119 120;void bar4(foo_t *f, unsigned n) { 121; for (unsigned i = 0; i < n; ++i) { 122; f[i].a = 0; 123; f[i].b = 1; 124; } 125;} 126define void @bar4(%struct.foo* nocapture %f, i32 %n) nounwind ssp { 127entry: 128 %cmp1 = icmp eq i32 %n, 0 129 br i1 %cmp1, label %for.end, label %for.body.preheader 130 131for.body.preheader: ; preds = %entry 132 br label %for.body 133 134for.body: ; preds = %for.body.preheader, %for.body 135 %indvars.iv = phi i64 [ 0, %for.body.preheader ], [ %indvars.iv.next, %for.body ] 136 %a = getelementptr inbounds %struct.foo, %struct.foo* %f, i64 %indvars.iv, i32 0 137 store i32 0, i32* %a, align 4 138 %b = getelementptr inbounds %struct.foo, %struct.foo* %f, i64 %indvars.iv, i32 1 139 store i32 1, i32* %b, align 4 140 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 141 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 142 %exitcond = icmp ne i32 %lftr.wideiv, %n 143 br i1 %exitcond, label %for.body, label %for.end.loopexit 144 145for.end.loopexit: ; preds = %for.body 146 br label %for.end 147 148for.end: ; preds = %for.end.loopexit, %entry 149 ret void 150; CHECK-LABEL: @bar4( 151; CHECK-NOT: call void @memset_pattern16 152} 153 154;void bar5(foo1_t *f, unsigned n) { 155; for (unsigned i = 0; i < n; ++i) { 156; f[i].a = 1; 157; f[i].b = 1; 158; } 159;} 160define void @bar5(%struct.foo1* nocapture %f, i32 %n) nounwind ssp { 161entry: 162 %cmp1 = icmp eq i32 %n, 0 163 br i1 %cmp1, label %for.end, label %for.body.preheader 164 165for.body.preheader: ; preds = %entry 166 br label %for.body 167 168for.body: ; preds = %for.body.preheader, %for.body 169 %indvars.iv = phi i64 [ 0, %for.body.preheader ], [ %indvars.iv.next, %for.body ] 170 %a = getelementptr inbounds %struct.foo1, %struct.foo1* %f, i64 %indvars.iv, i32 0 171 store i32 1, i32* %a, align 4 172 %b = getelementptr inbounds %struct.foo1, %struct.foo1* %f, i64 %indvars.iv, i32 1 173 store i32 1, i32* %b, align 4 174 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 175 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 176 %exitcond = icmp ne i32 %lftr.wideiv, %n 177 br i1 %exitcond, label %for.body, label %for.end.loopexit 178 179for.end.loopexit: ; preds = %for.body 180 br label %for.end 181 182for.end: ; preds = %for.end.loopexit, %entry 183 ret void 184; CHECK-LABEL: @bar5( 185; CHECK-NOT: call void @memset_pattern16 186} 187