1*9880d681SAndroid Build Coastguard Worker; RUN: opt -basicaa -loop-idiom < %s -S | FileCheck %s 2*9880d681SAndroid Build Coastguard Workertarget 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*9880d681SAndroid Build Coastguard Worker 4*9880d681SAndroid Build Coastguard Worker; For @test11_pattern 5*9880d681SAndroid Build Coastguard Worker; CHECK: @.memset_pattern = private unnamed_addr constant [4 x i32] [i32 1, i32 1, i32 1, i32 1] 6*9880d681SAndroid Build Coastguard Worker 7*9880d681SAndroid Build Coastguard Worker; For @test13_pattern 8*9880d681SAndroid Build Coastguard Worker; CHECK: @.memset_pattern.1 = private unnamed_addr constant [2 x i32*] [i32* @G, i32* @G] 9*9880d681SAndroid Build Coastguard Worker 10*9880d681SAndroid Build Coastguard Workertarget triple = "x86_64-apple-darwin10.0.0" 11*9880d681SAndroid Build Coastguard Worker 12*9880d681SAndroid Build Coastguard Workerdefine void @test1(i8* %Base, i64 %Size) nounwind ssp { 13*9880d681SAndroid Build Coastguard Workerbb.nph: ; preds = %entry 14*9880d681SAndroid Build Coastguard Worker br label %for.body 15*9880d681SAndroid Build Coastguard Worker 16*9880d681SAndroid Build Coastguard Workerfor.body: ; preds = %bb.nph, %for.body 17*9880d681SAndroid Build Coastguard Worker %indvar = phi i64 [ 0, %bb.nph ], [ %indvar.next, %for.body ] 18*9880d681SAndroid Build Coastguard Worker %I.0.014 = getelementptr i8, i8* %Base, i64 %indvar 19*9880d681SAndroid Build Coastguard Worker store i8 0, i8* %I.0.014, align 1 20*9880d681SAndroid Build Coastguard Worker %indvar.next = add i64 %indvar, 1 21*9880d681SAndroid Build Coastguard Worker %exitcond = icmp eq i64 %indvar.next, %Size 22*9880d681SAndroid Build Coastguard Worker br i1 %exitcond, label %for.end, label %for.body 23*9880d681SAndroid Build Coastguard Worker 24*9880d681SAndroid Build Coastguard Workerfor.end: ; preds = %for.body, %entry 25*9880d681SAndroid Build Coastguard Worker ret void 26*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test1( 27*9880d681SAndroid Build Coastguard Worker; CHECK: call void @llvm.memset.p0i8.i64(i8* %Base, i8 0, i64 %Size, i32 1, i1 false) 28*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: store 29*9880d681SAndroid Build Coastguard Worker} 30*9880d681SAndroid Build Coastguard Worker 31*9880d681SAndroid Build Coastguard Worker; This is a loop that was rotated but where the blocks weren't merged. This 32*9880d681SAndroid Build Coastguard Worker; shouldn't perturb us. 33*9880d681SAndroid Build Coastguard Workerdefine void @test1a(i8* %Base, i64 %Size) nounwind ssp { 34*9880d681SAndroid Build Coastguard Workerbb.nph: ; preds = %entry 35*9880d681SAndroid Build Coastguard Worker br label %for.body 36*9880d681SAndroid Build Coastguard Worker 37*9880d681SAndroid Build Coastguard Workerfor.body: ; preds = %bb.nph, %for.body 38*9880d681SAndroid Build Coastguard Worker %indvar = phi i64 [ 0, %bb.nph ], [ %indvar.next, %for.body.cont ] 39*9880d681SAndroid Build Coastguard Worker %I.0.014 = getelementptr i8, i8* %Base, i64 %indvar 40*9880d681SAndroid Build Coastguard Worker store i8 0, i8* %I.0.014, align 1 41*9880d681SAndroid Build Coastguard Worker %indvar.next = add i64 %indvar, 1 42*9880d681SAndroid Build Coastguard Worker br label %for.body.cont 43*9880d681SAndroid Build Coastguard Workerfor.body.cont: 44*9880d681SAndroid Build Coastguard Worker %exitcond = icmp eq i64 %indvar.next, %Size 45*9880d681SAndroid Build Coastguard Worker br i1 %exitcond, label %for.end, label %for.body 46*9880d681SAndroid Build Coastguard Worker 47*9880d681SAndroid Build Coastguard Workerfor.end: ; preds = %for.body, %entry 48*9880d681SAndroid Build Coastguard Worker ret void 49*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test1a( 50*9880d681SAndroid Build Coastguard Worker; CHECK: call void @llvm.memset.p0i8.i64(i8* %Base, i8 0, i64 %Size, i32 1, i1 false) 51*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: store 52*9880d681SAndroid Build Coastguard Worker} 53*9880d681SAndroid Build Coastguard Worker 54*9880d681SAndroid Build Coastguard Worker 55*9880d681SAndroid Build Coastguard Workerdefine void @test2(i32* %Base, i64 %Size) nounwind ssp { 56*9880d681SAndroid Build Coastguard Workerentry: 57*9880d681SAndroid Build Coastguard Worker %cmp10 = icmp eq i64 %Size, 0 58*9880d681SAndroid Build Coastguard Worker br i1 %cmp10, label %for.end, label %for.body 59*9880d681SAndroid Build Coastguard Worker 60*9880d681SAndroid Build Coastguard Workerfor.body: ; preds = %entry, %for.body 61*9880d681SAndroid Build Coastguard Worker %i.011 = phi i64 [ %inc, %for.body ], [ 0, %entry ] 62*9880d681SAndroid Build Coastguard Worker %add.ptr.i = getelementptr i32, i32* %Base, i64 %i.011 63*9880d681SAndroid Build Coastguard Worker store i32 16843009, i32* %add.ptr.i, align 4 64*9880d681SAndroid Build Coastguard Worker %inc = add nsw i64 %i.011, 1 65*9880d681SAndroid Build Coastguard Worker %exitcond = icmp eq i64 %inc, %Size 66*9880d681SAndroid Build Coastguard Worker br i1 %exitcond, label %for.end, label %for.body 67*9880d681SAndroid Build Coastguard Worker 68*9880d681SAndroid Build Coastguard Workerfor.end: ; preds = %for.body, %entry 69*9880d681SAndroid Build Coastguard Worker ret void 70*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test2( 71*9880d681SAndroid Build Coastguard Worker; CHECK: br i1 %cmp10, 72*9880d681SAndroid Build Coastguard Worker; CHECK: %0 = shl i64 %Size, 2 73*9880d681SAndroid Build Coastguard Worker; CHECK: call void @llvm.memset.p0i8.i64(i8* %Base1, i8 1, i64 %0, i32 4, i1 false) 74*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: store 75*9880d681SAndroid Build Coastguard Worker} 76*9880d681SAndroid Build Coastguard Worker 77*9880d681SAndroid Build Coastguard Worker; This is a case where there is an extra may-aliased store in the loop, we can't 78*9880d681SAndroid Build Coastguard Worker; promote the memset. 79*9880d681SAndroid Build Coastguard Workerdefine void @test3(i32* %Base, i64 %Size, i8 *%MayAlias) nounwind ssp { 80*9880d681SAndroid Build Coastguard Workerentry: 81*9880d681SAndroid Build Coastguard Worker br label %for.body 82*9880d681SAndroid Build Coastguard Worker 83*9880d681SAndroid Build Coastguard Workerfor.body: ; preds = %entry, %for.body 84*9880d681SAndroid Build Coastguard Worker %i.011 = phi i64 [ %inc, %for.body ], [ 0, %entry ] 85*9880d681SAndroid Build Coastguard Worker %add.ptr.i = getelementptr i32, i32* %Base, i64 %i.011 86*9880d681SAndroid Build Coastguard Worker store i32 16843009, i32* %add.ptr.i, align 4 87*9880d681SAndroid Build Coastguard Worker 88*9880d681SAndroid Build Coastguard Worker store i8 42, i8* %MayAlias 89*9880d681SAndroid Build Coastguard Worker %inc = add nsw i64 %i.011, 1 90*9880d681SAndroid Build Coastguard Worker %exitcond = icmp eq i64 %inc, %Size 91*9880d681SAndroid Build Coastguard Worker br i1 %exitcond, label %for.end, label %for.body 92*9880d681SAndroid Build Coastguard Worker 93*9880d681SAndroid Build Coastguard Workerfor.end: ; preds = %entry 94*9880d681SAndroid Build Coastguard Worker ret void 95*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test3( 96*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: memset 97*9880d681SAndroid Build Coastguard Worker; CHECK: ret void 98*9880d681SAndroid Build Coastguard Worker} 99*9880d681SAndroid Build Coastguard Worker 100*9880d681SAndroid Build Coastguard Worker 101*9880d681SAndroid Build Coastguard Worker;; TODO: We should be able to promote this memset. Not yet though. 102*9880d681SAndroid Build Coastguard Workerdefine void @test4(i8* %Base) nounwind ssp { 103*9880d681SAndroid Build Coastguard Workerbb.nph: ; preds = %entry 104*9880d681SAndroid Build Coastguard Worker %Base100 = getelementptr i8, i8* %Base, i64 1000 105*9880d681SAndroid Build Coastguard Worker br label %for.body 106*9880d681SAndroid Build Coastguard Worker 107*9880d681SAndroid Build Coastguard Workerfor.body: ; preds = %bb.nph, %for.body 108*9880d681SAndroid Build Coastguard Worker %indvar = phi i64 [ 0, %bb.nph ], [ %indvar.next, %for.body ] 109*9880d681SAndroid Build Coastguard Worker %I.0.014 = getelementptr i8, i8* %Base, i64 %indvar 110*9880d681SAndroid Build Coastguard Worker store i8 0, i8* %I.0.014, align 1 111*9880d681SAndroid Build Coastguard Worker 112*9880d681SAndroid Build Coastguard Worker ;; Store beyond the range memset, should be safe to promote. 113*9880d681SAndroid Build Coastguard Worker store i8 42, i8* %Base100 114*9880d681SAndroid Build Coastguard Worker 115*9880d681SAndroid Build Coastguard Worker %indvar.next = add i64 %indvar, 1 116*9880d681SAndroid Build Coastguard Worker %exitcond = icmp eq i64 %indvar.next, 100 117*9880d681SAndroid Build Coastguard Worker br i1 %exitcond, label %for.end, label %for.body 118*9880d681SAndroid Build Coastguard Worker 119*9880d681SAndroid Build Coastguard Workerfor.end: ; preds = %for.body, %entry 120*9880d681SAndroid Build Coastguard Worker ret void 121*9880d681SAndroid Build Coastguard Worker; CHECK-TODO-LABEL: @test4( 122*9880d681SAndroid Build Coastguard Worker; CHECK-TODO: call void @llvm.memset.p0i8.i64(i8* %Base, i8 0, i64 100, i32 1, i1 false) 123*9880d681SAndroid Build Coastguard Worker; CHECK-TODO-NOT: store 124*9880d681SAndroid Build Coastguard Worker} 125*9880d681SAndroid Build Coastguard Worker 126*9880d681SAndroid Build Coastguard Worker; This can't be promoted: the memset is a store of a loop variant value. 127*9880d681SAndroid Build Coastguard Workerdefine void @test5(i8* %Base, i64 %Size) nounwind ssp { 128*9880d681SAndroid Build Coastguard Workerbb.nph: ; preds = %entry 129*9880d681SAndroid Build Coastguard Worker br label %for.body 130*9880d681SAndroid Build Coastguard Worker 131*9880d681SAndroid Build Coastguard Workerfor.body: ; preds = %bb.nph, %for.body 132*9880d681SAndroid Build Coastguard Worker %indvar = phi i64 [ 0, %bb.nph ], [ %indvar.next, %for.body ] 133*9880d681SAndroid Build Coastguard Worker %I.0.014 = getelementptr i8, i8* %Base, i64 %indvar 134*9880d681SAndroid Build Coastguard Worker 135*9880d681SAndroid Build Coastguard Worker %V = trunc i64 %indvar to i8 136*9880d681SAndroid Build Coastguard Worker store i8 %V, i8* %I.0.014, align 1 137*9880d681SAndroid Build Coastguard Worker %indvar.next = add i64 %indvar, 1 138*9880d681SAndroid Build Coastguard Worker %exitcond = icmp eq i64 %indvar.next, %Size 139*9880d681SAndroid Build Coastguard Worker br i1 %exitcond, label %for.end, label %for.body 140*9880d681SAndroid Build Coastguard Worker 141*9880d681SAndroid Build Coastguard Workerfor.end: ; preds = %for.body, %entry 142*9880d681SAndroid Build Coastguard Worker ret void 143*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test5( 144*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: memset 145*9880d681SAndroid Build Coastguard Worker; CHECK: ret void 146*9880d681SAndroid Build Coastguard Worker} 147*9880d681SAndroid Build Coastguard Worker 148*9880d681SAndroid Build Coastguard Worker 149*9880d681SAndroid Build Coastguard Worker;; memcpy formation 150*9880d681SAndroid Build Coastguard Workerdefine void @test6(i64 %Size) nounwind ssp { 151*9880d681SAndroid Build Coastguard Workerbb.nph: 152*9880d681SAndroid Build Coastguard Worker %Base = alloca i8, i32 10000 153*9880d681SAndroid Build Coastguard Worker %Dest = alloca i8, i32 10000 154*9880d681SAndroid Build Coastguard Worker br label %for.body 155*9880d681SAndroid Build Coastguard Worker 156*9880d681SAndroid Build Coastguard Workerfor.body: ; preds = %bb.nph, %for.body 157*9880d681SAndroid Build Coastguard Worker %indvar = phi i64 [ 0, %bb.nph ], [ %indvar.next, %for.body ] 158*9880d681SAndroid Build Coastguard Worker %I.0.014 = getelementptr i8, i8* %Base, i64 %indvar 159*9880d681SAndroid Build Coastguard Worker %DestI = getelementptr i8, i8* %Dest, i64 %indvar 160*9880d681SAndroid Build Coastguard Worker %V = load i8, i8* %I.0.014, align 1 161*9880d681SAndroid Build Coastguard Worker store i8 %V, i8* %DestI, align 1 162*9880d681SAndroid Build Coastguard Worker %indvar.next = add i64 %indvar, 1 163*9880d681SAndroid Build Coastguard Worker %exitcond = icmp eq i64 %indvar.next, %Size 164*9880d681SAndroid Build Coastguard Worker br i1 %exitcond, label %for.end, label %for.body 165*9880d681SAndroid Build Coastguard Worker 166*9880d681SAndroid Build Coastguard Workerfor.end: ; preds = %for.body, %entry 167*9880d681SAndroid Build Coastguard Worker ret void 168*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test6( 169*9880d681SAndroid Build Coastguard Worker; CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %Dest, i8* %Base, i64 %Size, i32 1, i1 false) 170*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: store 171*9880d681SAndroid Build Coastguard Worker; CHECK: ret void 172*9880d681SAndroid Build Coastguard Worker} 173*9880d681SAndroid Build Coastguard Worker 174*9880d681SAndroid Build Coastguard Worker 175*9880d681SAndroid Build Coastguard Worker; This is a loop that was rotated but where the blocks weren't merged. This 176*9880d681SAndroid Build Coastguard Worker; shouldn't perturb us. 177*9880d681SAndroid Build Coastguard Workerdefine void @test7(i8* %Base, i64 %Size) nounwind ssp { 178*9880d681SAndroid Build Coastguard Workerbb.nph: ; preds = %entry 179*9880d681SAndroid Build Coastguard Worker br label %for.body 180*9880d681SAndroid Build Coastguard Worker 181*9880d681SAndroid Build Coastguard Workerfor.body: ; preds = %bb.nph, %for.body 182*9880d681SAndroid Build Coastguard Worker %indvar = phi i64 [ 0, %bb.nph ], [ %indvar.next, %for.body.cont ] 183*9880d681SAndroid Build Coastguard Worker br label %for.body.cont 184*9880d681SAndroid Build Coastguard Workerfor.body.cont: 185*9880d681SAndroid Build Coastguard Worker %I.0.014 = getelementptr i8, i8* %Base, i64 %indvar 186*9880d681SAndroid Build Coastguard Worker store i8 0, i8* %I.0.014, align 1 187*9880d681SAndroid Build Coastguard Worker %indvar.next = add i64 %indvar, 1 188*9880d681SAndroid Build Coastguard Worker %exitcond = icmp eq i64 %indvar.next, %Size 189*9880d681SAndroid Build Coastguard Worker br i1 %exitcond, label %for.end, label %for.body 190*9880d681SAndroid Build Coastguard Worker 191*9880d681SAndroid Build Coastguard Workerfor.end: ; preds = %for.body, %entry 192*9880d681SAndroid Build Coastguard Worker ret void 193*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test7( 194*9880d681SAndroid Build Coastguard Worker; CHECK: call void @llvm.memset.p0i8.i64(i8* %Base, i8 0, i64 %Size, i32 1, i1 false) 195*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: store 196*9880d681SAndroid Build Coastguard Worker} 197*9880d681SAndroid Build Coastguard Worker 198*9880d681SAndroid Build Coastguard Worker; This is a loop should not be transformed, it only executes one iteration. 199*9880d681SAndroid Build Coastguard Workerdefine void @test8(i64* %Ptr, i64 %Size) nounwind ssp { 200*9880d681SAndroid Build Coastguard Workerbb.nph: ; preds = %entry 201*9880d681SAndroid Build Coastguard Worker br label %for.body 202*9880d681SAndroid Build Coastguard Worker 203*9880d681SAndroid Build Coastguard Workerfor.body: ; preds = %bb.nph, %for.body 204*9880d681SAndroid Build Coastguard Worker %indvar = phi i64 [ 0, %bb.nph ], [ %indvar.next, %for.body ] 205*9880d681SAndroid Build Coastguard Worker %PI = getelementptr i64, i64* %Ptr, i64 %indvar 206*9880d681SAndroid Build Coastguard Worker store i64 0, i64 *%PI 207*9880d681SAndroid Build Coastguard Worker %indvar.next = add i64 %indvar, 1 208*9880d681SAndroid Build Coastguard Worker %exitcond = icmp eq i64 %indvar.next, 1 209*9880d681SAndroid Build Coastguard Worker br i1 %exitcond, label %for.end, label %for.body 210*9880d681SAndroid Build Coastguard Worker 211*9880d681SAndroid Build Coastguard Workerfor.end: ; preds = %for.body, %entry 212*9880d681SAndroid Build Coastguard Worker ret void 213*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test8( 214*9880d681SAndroid Build Coastguard Worker; CHECK: store i64 0, i64* %PI 215*9880d681SAndroid Build Coastguard Worker} 216*9880d681SAndroid Build Coastguard Worker 217*9880d681SAndroid Build Coastguard Workerdeclare i8* @external(i8*) 218*9880d681SAndroid Build Coastguard Worker 219*9880d681SAndroid Build Coastguard Worker;; This cannot be transformed into a memcpy, because the read-from location is 220*9880d681SAndroid Build Coastguard Worker;; mutated by the loop. 221*9880d681SAndroid Build Coastguard Workerdefine void @test9(i64 %Size) nounwind ssp { 222*9880d681SAndroid Build Coastguard Workerbb.nph: 223*9880d681SAndroid Build Coastguard Worker %Base = alloca i8, i32 10000 224*9880d681SAndroid Build Coastguard Worker %Dest = alloca i8, i32 10000 225*9880d681SAndroid Build Coastguard Worker 226*9880d681SAndroid Build Coastguard Worker %BaseAlias = call i8* @external(i8* %Base) 227*9880d681SAndroid Build Coastguard Worker br label %for.body 228*9880d681SAndroid Build Coastguard Worker 229*9880d681SAndroid Build Coastguard Workerfor.body: ; preds = %bb.nph, %for.body 230*9880d681SAndroid Build Coastguard Worker %indvar = phi i64 [ 0, %bb.nph ], [ %indvar.next, %for.body ] 231*9880d681SAndroid Build Coastguard Worker %I.0.014 = getelementptr i8, i8* %Base, i64 %indvar 232*9880d681SAndroid Build Coastguard Worker %DestI = getelementptr i8, i8* %Dest, i64 %indvar 233*9880d681SAndroid Build Coastguard Worker %V = load i8, i8* %I.0.014, align 1 234*9880d681SAndroid Build Coastguard Worker store i8 %V, i8* %DestI, align 1 235*9880d681SAndroid Build Coastguard Worker 236*9880d681SAndroid Build Coastguard Worker ;; This store can clobber the input. 237*9880d681SAndroid Build Coastguard Worker store i8 4, i8* %BaseAlias 238*9880d681SAndroid Build Coastguard Worker 239*9880d681SAndroid Build Coastguard Worker %indvar.next = add i64 %indvar, 1 240*9880d681SAndroid Build Coastguard Worker %exitcond = icmp eq i64 %indvar.next, %Size 241*9880d681SAndroid Build Coastguard Worker br i1 %exitcond, label %for.end, label %for.body 242*9880d681SAndroid Build Coastguard Worker 243*9880d681SAndroid Build Coastguard Workerfor.end: ; preds = %for.body, %entry 244*9880d681SAndroid Build Coastguard Worker ret void 245*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test9( 246*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: llvm.memcpy 247*9880d681SAndroid Build Coastguard Worker; CHECK: ret void 248*9880d681SAndroid Build Coastguard Worker} 249*9880d681SAndroid Build Coastguard Worker 250*9880d681SAndroid Build Coastguard Worker; Two dimensional nested loop should be promoted to one big memset. 251*9880d681SAndroid Build Coastguard Workerdefine void @test10(i8* %X) nounwind ssp { 252*9880d681SAndroid Build Coastguard Workerentry: 253*9880d681SAndroid Build Coastguard Worker br label %bb.nph 254*9880d681SAndroid Build Coastguard Worker 255*9880d681SAndroid Build Coastguard Workerbb.nph: ; preds = %entry, %for.inc10 256*9880d681SAndroid Build Coastguard Worker %i.04 = phi i32 [ 0, %entry ], [ %inc12, %for.inc10 ] 257*9880d681SAndroid Build Coastguard Worker br label %for.body5 258*9880d681SAndroid Build Coastguard Worker 259*9880d681SAndroid Build Coastguard Workerfor.body5: ; preds = %for.body5, %bb.nph 260*9880d681SAndroid Build Coastguard Worker %j.02 = phi i32 [ 0, %bb.nph ], [ %inc, %for.body5 ] 261*9880d681SAndroid Build Coastguard Worker %mul = mul nsw i32 %i.04, 100 262*9880d681SAndroid Build Coastguard Worker %add = add nsw i32 %j.02, %mul 263*9880d681SAndroid Build Coastguard Worker %idxprom = sext i32 %add to i64 264*9880d681SAndroid Build Coastguard Worker %arrayidx = getelementptr inbounds i8, i8* %X, i64 %idxprom 265*9880d681SAndroid Build Coastguard Worker store i8 0, i8* %arrayidx, align 1 266*9880d681SAndroid Build Coastguard Worker %inc = add nsw i32 %j.02, 1 267*9880d681SAndroid Build Coastguard Worker %cmp4 = icmp eq i32 %inc, 100 268*9880d681SAndroid Build Coastguard Worker br i1 %cmp4, label %for.inc10, label %for.body5 269*9880d681SAndroid Build Coastguard Worker 270*9880d681SAndroid Build Coastguard Workerfor.inc10: ; preds = %for.body5 271*9880d681SAndroid Build Coastguard Worker %inc12 = add nsw i32 %i.04, 1 272*9880d681SAndroid Build Coastguard Worker %cmp = icmp eq i32 %inc12, 100 273*9880d681SAndroid Build Coastguard Worker br i1 %cmp, label %for.end13, label %bb.nph 274*9880d681SAndroid Build Coastguard Worker 275*9880d681SAndroid Build Coastguard Workerfor.end13: ; preds = %for.inc10 276*9880d681SAndroid Build Coastguard Worker ret void 277*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test10( 278*9880d681SAndroid Build Coastguard Worker; CHECK: entry: 279*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* %X, i8 0, i64 10000, i32 1, i1 false) 280*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: store 281*9880d681SAndroid Build Coastguard Worker; CHECK: ret void 282*9880d681SAndroid Build Coastguard Worker} 283*9880d681SAndroid Build Coastguard Worker 284*9880d681SAndroid Build Coastguard Worker; On darwin10 (which is the triple in this .ll file) this loop can be turned 285*9880d681SAndroid Build Coastguard Worker; into a memset_pattern call. 286*9880d681SAndroid Build Coastguard Worker; rdar://9009151 287*9880d681SAndroid Build Coastguard Workerdefine void @test11_pattern(i32* nocapture %P) nounwind ssp { 288*9880d681SAndroid Build Coastguard Workerentry: 289*9880d681SAndroid Build Coastguard Worker br label %for.body 290*9880d681SAndroid Build Coastguard Worker 291*9880d681SAndroid Build Coastguard Workerfor.body: ; preds = %entry, %for.body 292*9880d681SAndroid Build Coastguard Worker %indvar = phi i64 [ 0, %entry ], [ %indvar.next, %for.body ] 293*9880d681SAndroid Build Coastguard Worker %arrayidx = getelementptr i32, i32* %P, i64 %indvar 294*9880d681SAndroid Build Coastguard Worker store i32 1, i32* %arrayidx, align 4 295*9880d681SAndroid Build Coastguard Worker %indvar.next = add i64 %indvar, 1 296*9880d681SAndroid Build Coastguard Worker %exitcond = icmp eq i64 %indvar.next, 10000 297*9880d681SAndroid Build Coastguard Worker br i1 %exitcond, label %for.end, label %for.body 298*9880d681SAndroid Build Coastguard Worker 299*9880d681SAndroid Build Coastguard Workerfor.end: ; preds = %for.body 300*9880d681SAndroid Build Coastguard Worker ret void 301*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test11_pattern( 302*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: entry: 303*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bitcast 304*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: memset_pattern 305*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: store 306*9880d681SAndroid Build Coastguard Worker; CHECK: ret void 307*9880d681SAndroid Build Coastguard Worker} 308*9880d681SAndroid Build Coastguard Worker 309*9880d681SAndroid Build Coastguard Worker; Store of null should turn into memset of zero. 310*9880d681SAndroid Build Coastguard Workerdefine void @test12(i32** nocapture %P) nounwind ssp { 311*9880d681SAndroid Build Coastguard Workerentry: 312*9880d681SAndroid Build Coastguard Worker br label %for.body 313*9880d681SAndroid Build Coastguard Worker 314*9880d681SAndroid Build Coastguard Workerfor.body: ; preds = %entry, %for.body 315*9880d681SAndroid Build Coastguard Worker %indvar = phi i64 [ 0, %entry ], [ %indvar.next, %for.body ] 316*9880d681SAndroid Build Coastguard Worker %arrayidx = getelementptr i32*, i32** %P, i64 %indvar 317*9880d681SAndroid Build Coastguard Worker store i32* null, i32** %arrayidx, align 4 318*9880d681SAndroid Build Coastguard Worker %indvar.next = add i64 %indvar, 1 319*9880d681SAndroid Build Coastguard Worker %exitcond = icmp eq i64 %indvar.next, 10000 320*9880d681SAndroid Build Coastguard Worker br i1 %exitcond, label %for.end, label %for.body 321*9880d681SAndroid Build Coastguard Worker 322*9880d681SAndroid Build Coastguard Workerfor.end: ; preds = %for.body 323*9880d681SAndroid Build Coastguard Worker ret void 324*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test12( 325*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: entry: 326*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bitcast 327*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* %P1, i8 0, i64 80000, i32 4, i1 false) 328*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: store 329*9880d681SAndroid Build Coastguard Worker; CHECK: ret void 330*9880d681SAndroid Build Coastguard Worker} 331*9880d681SAndroid Build Coastguard Worker 332*9880d681SAndroid Build Coastguard Worker@G = global i32 5 333*9880d681SAndroid Build Coastguard Worker 334*9880d681SAndroid Build Coastguard Worker; This store-of-address loop can be turned into a memset_pattern call. 335*9880d681SAndroid Build Coastguard Worker; rdar://9009151 336*9880d681SAndroid Build Coastguard Workerdefine void @test13_pattern(i32** nocapture %P) nounwind ssp { 337*9880d681SAndroid Build Coastguard Workerentry: 338*9880d681SAndroid Build Coastguard Worker br label %for.body 339*9880d681SAndroid Build Coastguard Worker 340*9880d681SAndroid Build Coastguard Workerfor.body: ; preds = %entry, %for.body 341*9880d681SAndroid Build Coastguard Worker %indvar = phi i64 [ 0, %entry ], [ %indvar.next, %for.body ] 342*9880d681SAndroid Build Coastguard Worker %arrayidx = getelementptr i32*, i32** %P, i64 %indvar 343*9880d681SAndroid Build Coastguard Worker store i32* @G, i32** %arrayidx, align 4 344*9880d681SAndroid Build Coastguard Worker %indvar.next = add i64 %indvar, 1 345*9880d681SAndroid Build Coastguard Worker %exitcond = icmp eq i64 %indvar.next, 10000 346*9880d681SAndroid Build Coastguard Worker br i1 %exitcond, label %for.end, label %for.body 347*9880d681SAndroid Build Coastguard Worker 348*9880d681SAndroid Build Coastguard Workerfor.end: ; preds = %for.body 349*9880d681SAndroid Build Coastguard Worker ret void 350*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test13_pattern( 351*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: entry: 352*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bitcast 353*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: memset_pattern 354*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: store 355*9880d681SAndroid Build Coastguard Worker; CHECK: ret void 356*9880d681SAndroid Build Coastguard Worker} 357*9880d681SAndroid Build Coastguard Worker 358*9880d681SAndroid Build Coastguard Worker 359*9880d681SAndroid Build Coastguard Worker 360*9880d681SAndroid Build Coastguard Worker; PR9815 - This is a partial overlap case that cannot be safely transformed 361*9880d681SAndroid Build Coastguard Worker; into a memcpy. 362*9880d681SAndroid Build Coastguard Worker@g_50 = global [7 x i32] [i32 0, i32 0, i32 0, i32 0, i32 1, i32 0, i32 0], align 16 363*9880d681SAndroid Build Coastguard Worker 364*9880d681SAndroid Build Coastguard Workerdefine i32 @test14() nounwind { 365*9880d681SAndroid Build Coastguard Workerentry: 366*9880d681SAndroid Build Coastguard Worker br label %for.body 367*9880d681SAndroid Build Coastguard Worker 368*9880d681SAndroid Build Coastguard Workerfor.body: ; preds = %for.inc, %for.body.lr.ph 369*9880d681SAndroid Build Coastguard Worker %tmp5 = phi i32 [ %inc, %for.body ], [ 0, %entry ] 370*9880d681SAndroid Build Coastguard Worker %add = add nsw i32 %tmp5, 4 371*9880d681SAndroid Build Coastguard Worker %idxprom = sext i32 %add to i64 372*9880d681SAndroid Build Coastguard Worker %arrayidx = getelementptr inbounds [7 x i32], [7 x i32]* @g_50, i32 0, i64 %idxprom 373*9880d681SAndroid Build Coastguard Worker %tmp2 = load i32, i32* %arrayidx, align 4 374*9880d681SAndroid Build Coastguard Worker %add4 = add nsw i32 %tmp5, 5 375*9880d681SAndroid Build Coastguard Worker %idxprom5 = sext i32 %add4 to i64 376*9880d681SAndroid Build Coastguard Worker %arrayidx6 = getelementptr inbounds [7 x i32], [7 x i32]* @g_50, i32 0, i64 %idxprom5 377*9880d681SAndroid Build Coastguard Worker store i32 %tmp2, i32* %arrayidx6, align 4 378*9880d681SAndroid Build Coastguard Worker %inc = add nsw i32 %tmp5, 1 379*9880d681SAndroid Build Coastguard Worker %cmp = icmp slt i32 %inc, 2 380*9880d681SAndroid Build Coastguard Worker br i1 %cmp, label %for.body, label %for.end 381*9880d681SAndroid Build Coastguard Worker 382*9880d681SAndroid Build Coastguard Workerfor.end: ; preds = %for.inc 383*9880d681SAndroid Build Coastguard Worker %tmp8 = load i32, i32* getelementptr inbounds ([7 x i32], [7 x i32]* @g_50, i32 0, i64 6), align 4 384*9880d681SAndroid Build Coastguard Worker ret i32 %tmp8 385*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test14( 386*9880d681SAndroid Build Coastguard Worker; CHECK: for.body: 387*9880d681SAndroid Build Coastguard Worker; CHECK: load i32 388*9880d681SAndroid Build Coastguard Worker; CHECK: store i32 389*9880d681SAndroid Build Coastguard Worker; CHECK: br i1 %cmp 390*9880d681SAndroid Build Coastguard Worker 391*9880d681SAndroid Build Coastguard Worker} 392*9880d681SAndroid Build Coastguard Worker 393*9880d681SAndroid Build Coastguard Workerdefine void @PR14241(i32* %s, i64 %size) { 394*9880d681SAndroid Build Coastguard Worker; Ensure that we don't form a memcpy for strided loops. Briefly, when we taught 395*9880d681SAndroid Build Coastguard Worker; LoopIdiom about memmove and strided loops, this got miscompiled into a memcpy 396*9880d681SAndroid Build Coastguard Worker; instead of a memmove. If we get the memmove transform back, this will catch 397*9880d681SAndroid Build Coastguard Worker; regressions. 398*9880d681SAndroid Build Coastguard Worker; 399*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @PR14241( 400*9880d681SAndroid Build Coastguard Worker 401*9880d681SAndroid Build Coastguard Workerentry: 402*9880d681SAndroid Build Coastguard Worker %end.idx = add i64 %size, -1 403*9880d681SAndroid Build Coastguard Worker %end.ptr = getelementptr inbounds i32, i32* %s, i64 %end.idx 404*9880d681SAndroid Build Coastguard Worker br label %while.body 405*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: memcpy 406*9880d681SAndroid Build Coastguard Worker; 407*9880d681SAndroid Build Coastguard Worker; FIXME: When we regain the ability to form a memmove here, this test should be 408*9880d681SAndroid Build Coastguard Worker; reversed and turned into a positive assertion. 409*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: memmove 410*9880d681SAndroid Build Coastguard Worker 411*9880d681SAndroid Build Coastguard Workerwhile.body: 412*9880d681SAndroid Build Coastguard Worker %phi.ptr = phi i32* [ %s, %entry ], [ %next.ptr, %while.body ] 413*9880d681SAndroid Build Coastguard Worker %src.ptr = getelementptr inbounds i32, i32* %phi.ptr, i64 1 414*9880d681SAndroid Build Coastguard Worker %val = load i32, i32* %src.ptr, align 4 415*9880d681SAndroid Build Coastguard Worker; CHECK: load 416*9880d681SAndroid Build Coastguard Worker %dst.ptr = getelementptr inbounds i32, i32* %phi.ptr, i64 0 417*9880d681SAndroid Build Coastguard Worker store i32 %val, i32* %dst.ptr, align 4 418*9880d681SAndroid Build Coastguard Worker; CHECK: store 419*9880d681SAndroid Build Coastguard Worker %next.ptr = getelementptr inbounds i32, i32* %phi.ptr, i64 1 420*9880d681SAndroid Build Coastguard Worker %cmp = icmp eq i32* %next.ptr, %end.ptr 421*9880d681SAndroid Build Coastguard Worker br i1 %cmp, label %exit, label %while.body 422*9880d681SAndroid Build Coastguard Worker 423*9880d681SAndroid Build Coastguard Workerexit: 424*9880d681SAndroid Build Coastguard Worker ret void 425*9880d681SAndroid Build Coastguard Worker; CHECK: ret void 426*9880d681SAndroid Build Coastguard Worker} 427*9880d681SAndroid Build Coastguard Worker 428*9880d681SAndroid Build Coastguard Worker; Recognize loops with a negative stride. 429*9880d681SAndroid Build Coastguard Workerdefine void @test15(i32* nocapture %f) { 430*9880d681SAndroid Build Coastguard Workerentry: 431*9880d681SAndroid Build Coastguard Worker br label %for.body 432*9880d681SAndroid Build Coastguard Worker 433*9880d681SAndroid Build Coastguard Workerfor.body: 434*9880d681SAndroid Build Coastguard Worker %indvars.iv = phi i64 [ 65536, %entry ], [ %indvars.iv.next, %for.body ] 435*9880d681SAndroid Build Coastguard Worker %arrayidx = getelementptr inbounds i32, i32* %f, i64 %indvars.iv 436*9880d681SAndroid Build Coastguard Worker store i32 0, i32* %arrayidx, align 4 437*9880d681SAndroid Build Coastguard Worker %indvars.iv.next = add nsw i64 %indvars.iv, -1 438*9880d681SAndroid Build Coastguard Worker %cmp = icmp sgt i64 %indvars.iv, 0 439*9880d681SAndroid Build Coastguard Worker br i1 %cmp, label %for.body, label %for.cond.cleanup 440*9880d681SAndroid Build Coastguard Worker 441*9880d681SAndroid Build Coastguard Workerfor.cond.cleanup: 442*9880d681SAndroid Build Coastguard Worker ret void 443*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test15( 444*9880d681SAndroid Build Coastguard Worker; CHECK: call void @llvm.memset.p0i8.i64(i8* %f1, i8 0, i64 262148, i32 4, i1 false) 445*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: store 446*9880d681SAndroid Build Coastguard Worker; CHECK: ret void 447*9880d681SAndroid Build Coastguard Worker} 448*9880d681SAndroid Build Coastguard Worker 449*9880d681SAndroid Build Coastguard Worker; Loop with a negative stride. Verify an aliasing write to f[65536] prevents 450*9880d681SAndroid Build Coastguard Worker; the creation of a memset. 451*9880d681SAndroid Build Coastguard Workerdefine void @test16(i32* nocapture %f) { 452*9880d681SAndroid Build Coastguard Workerentry: 453*9880d681SAndroid Build Coastguard Worker %arrayidx1 = getelementptr inbounds i32, i32* %f, i64 65536 454*9880d681SAndroid Build Coastguard Worker br label %for.body 455*9880d681SAndroid Build Coastguard Worker 456*9880d681SAndroid Build Coastguard Workerfor.body: ; preds = %entry, %for.body 457*9880d681SAndroid Build Coastguard Worker %indvars.iv = phi i64 [ 65536, %entry ], [ %indvars.iv.next, %for.body ] 458*9880d681SAndroid Build Coastguard Worker %arrayidx = getelementptr inbounds i32, i32* %f, i64 %indvars.iv 459*9880d681SAndroid Build Coastguard Worker store i32 0, i32* %arrayidx, align 4 460*9880d681SAndroid Build Coastguard Worker store i32 1, i32* %arrayidx1, align 4 461*9880d681SAndroid Build Coastguard Worker %indvars.iv.next = add nsw i64 %indvars.iv, -1 462*9880d681SAndroid Build Coastguard Worker %cmp = icmp sgt i64 %indvars.iv, 0 463*9880d681SAndroid Build Coastguard Worker br i1 %cmp, label %for.body, label %for.cond.cleanup 464*9880d681SAndroid Build Coastguard Worker 465*9880d681SAndroid Build Coastguard Workerfor.cond.cleanup: ; preds = %for.body 466*9880d681SAndroid Build Coastguard Worker ret void 467*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test16( 468*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: call void @llvm.memset.p0i8.i64 469*9880d681SAndroid Build Coastguard Worker; CHECK: ret void 470*9880d681SAndroid Build Coastguard Worker} 471*9880d681SAndroid Build Coastguard Worker 472*9880d681SAndroid Build Coastguard Worker; Handle memcpy-able loops with negative stride. 473*9880d681SAndroid Build Coastguard Workerdefine noalias i32* @test17(i32* nocapture readonly %a, i32 %c) { 474*9880d681SAndroid Build Coastguard Workerentry: 475*9880d681SAndroid Build Coastguard Worker %conv = sext i32 %c to i64 476*9880d681SAndroid Build Coastguard Worker %mul = shl nsw i64 %conv, 2 477*9880d681SAndroid Build Coastguard Worker %call = tail call noalias i8* @malloc(i64 %mul) 478*9880d681SAndroid Build Coastguard Worker %0 = bitcast i8* %call to i32* 479*9880d681SAndroid Build Coastguard Worker %tobool.9 = icmp eq i32 %c, 0 480*9880d681SAndroid Build Coastguard Worker br i1 %tobool.9, label %while.end, label %while.body.preheader 481*9880d681SAndroid Build Coastguard Worker 482*9880d681SAndroid Build Coastguard Workerwhile.body.preheader: ; preds = %entry 483*9880d681SAndroid Build Coastguard Worker br label %while.body 484*9880d681SAndroid Build Coastguard Worker 485*9880d681SAndroid Build Coastguard Workerwhile.body: ; preds = %while.body.preheader, %while.body 486*9880d681SAndroid Build Coastguard Worker %dec10.in = phi i32 [ %dec10, %while.body ], [ %c, %while.body.preheader ] 487*9880d681SAndroid Build Coastguard Worker %dec10 = add nsw i32 %dec10.in, -1 488*9880d681SAndroid Build Coastguard Worker %idxprom = sext i32 %dec10 to i64 489*9880d681SAndroid Build Coastguard Worker %arrayidx = getelementptr inbounds i32, i32* %a, i64 %idxprom 490*9880d681SAndroid Build Coastguard Worker %1 = load i32, i32* %arrayidx, align 4 491*9880d681SAndroid Build Coastguard Worker %arrayidx2 = getelementptr inbounds i32, i32* %0, i64 %idxprom 492*9880d681SAndroid Build Coastguard Worker store i32 %1, i32* %arrayidx2, align 4 493*9880d681SAndroid Build Coastguard Worker %tobool = icmp eq i32 %dec10, 0 494*9880d681SAndroid Build Coastguard Worker br i1 %tobool, label %while.end.loopexit, label %while.body 495*9880d681SAndroid Build Coastguard Worker 496*9880d681SAndroid Build Coastguard Workerwhile.end.loopexit: ; preds = %while.body 497*9880d681SAndroid Build Coastguard Worker br label %while.end 498*9880d681SAndroid Build Coastguard Worker 499*9880d681SAndroid Build Coastguard Workerwhile.end: ; preds = %while.end.loopexit, %entry 500*9880d681SAndroid Build Coastguard Worker ret i32* %0 501*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test17( 502*9880d681SAndroid Build Coastguard Worker; CHECK: call void @llvm.memcpy 503*9880d681SAndroid Build Coastguard Worker; CHECK: ret i32* 504*9880d681SAndroid Build Coastguard Worker} 505*9880d681SAndroid Build Coastguard Worker 506*9880d681SAndroid Build Coastguard Workerdeclare noalias i8* @malloc(i64) 507*9880d681SAndroid Build Coastguard Worker 508*9880d681SAndroid Build Coastguard Worker; Handle memcpy-able loops with negative stride. 509*9880d681SAndroid Build Coastguard Worker; void test18(unsigned *__restrict__ a, unsigned *__restrict__ b) { 510*9880d681SAndroid Build Coastguard Worker; for (int i = 2047; i >= 0; --i) { 511*9880d681SAndroid Build Coastguard Worker; a[i] = b[i]; 512*9880d681SAndroid Build Coastguard Worker; } 513*9880d681SAndroid Build Coastguard Worker; } 514*9880d681SAndroid Build Coastguard Workerdefine void @test18(i32* noalias nocapture %a, i32* noalias nocapture readonly %b) #0 { 515*9880d681SAndroid Build Coastguard Workerentry: 516*9880d681SAndroid Build Coastguard Worker br label %for.body 517*9880d681SAndroid Build Coastguard Worker 518*9880d681SAndroid Build Coastguard Workerfor.body: ; preds = %entry, %for.body 519*9880d681SAndroid Build Coastguard Worker %indvars.iv = phi i64 [ 2047, %entry ], [ %indvars.iv.next, %for.body ] 520*9880d681SAndroid Build Coastguard Worker %arrayidx = getelementptr inbounds i32, i32* %b, i64 %indvars.iv 521*9880d681SAndroid Build Coastguard Worker %0 = load i32, i32* %arrayidx, align 4 522*9880d681SAndroid Build Coastguard Worker %arrayidx2 = getelementptr inbounds i32, i32* %a, i64 %indvars.iv 523*9880d681SAndroid Build Coastguard Worker store i32 %0, i32* %arrayidx2, align 4 524*9880d681SAndroid Build Coastguard Worker %indvars.iv.next = add nsw i64 %indvars.iv, -1 525*9880d681SAndroid Build Coastguard Worker %cmp = icmp sgt i64 %indvars.iv, 0 526*9880d681SAndroid Build Coastguard Worker br i1 %cmp, label %for.body, label %for.cond.cleanup 527*9880d681SAndroid Build Coastguard Worker 528*9880d681SAndroid Build Coastguard Workerfor.cond.cleanup: ; preds = %for.body 529*9880d681SAndroid Build Coastguard Worker ret void 530*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test18( 531*9880d681SAndroid Build Coastguard Worker; CHECK: call void @llvm.memcpy 532*9880d681SAndroid Build Coastguard Worker; CHECK: ret 533*9880d681SAndroid Build Coastguard Worker} 534*9880d681SAndroid Build Coastguard Worker 535*9880d681SAndroid Build Coastguard Worker; Two dimensional nested loop with negative stride should be promoted to one big memset. 536*9880d681SAndroid Build Coastguard Workerdefine void @test19(i8* nocapture %X) { 537*9880d681SAndroid Build Coastguard Workerentry: 538*9880d681SAndroid Build Coastguard Worker br label %for.cond1.preheader 539*9880d681SAndroid Build Coastguard Worker 540*9880d681SAndroid Build Coastguard Workerfor.cond1.preheader: ; preds = %entry, %for.inc4 541*9880d681SAndroid Build Coastguard Worker %i.06 = phi i32 [ 99, %entry ], [ %dec5, %for.inc4 ] 542*9880d681SAndroid Build Coastguard Worker %mul = mul nsw i32 %i.06, 100 543*9880d681SAndroid Build Coastguard Worker br label %for.body3 544*9880d681SAndroid Build Coastguard Worker 545*9880d681SAndroid Build Coastguard Workerfor.body3: ; preds = %for.cond1.preheader, %for.body3 546*9880d681SAndroid Build Coastguard Worker %j.05 = phi i32 [ 99, %for.cond1.preheader ], [ %dec, %for.body3 ] 547*9880d681SAndroid Build Coastguard Worker %add = add nsw i32 %j.05, %mul 548*9880d681SAndroid Build Coastguard Worker %idxprom = sext i32 %add to i64 549*9880d681SAndroid Build Coastguard Worker %arrayidx = getelementptr inbounds i8, i8* %X, i64 %idxprom 550*9880d681SAndroid Build Coastguard Worker store i8 0, i8* %arrayidx, align 1 551*9880d681SAndroid Build Coastguard Worker %dec = add nsw i32 %j.05, -1 552*9880d681SAndroid Build Coastguard Worker %cmp2 = icmp sgt i32 %j.05, 0 553*9880d681SAndroid Build Coastguard Worker br i1 %cmp2, label %for.body3, label %for.inc4 554*9880d681SAndroid Build Coastguard Worker 555*9880d681SAndroid Build Coastguard Workerfor.inc4: ; preds = %for.body3 556*9880d681SAndroid Build Coastguard Worker %dec5 = add nsw i32 %i.06, -1 557*9880d681SAndroid Build Coastguard Worker %cmp = icmp sgt i32 %i.06, 0 558*9880d681SAndroid Build Coastguard Worker br i1 %cmp, label %for.cond1.preheader, label %for.end6 559*9880d681SAndroid Build Coastguard Worker 560*9880d681SAndroid Build Coastguard Workerfor.end6: ; preds = %for.inc4 561*9880d681SAndroid Build Coastguard Worker ret void 562*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test19( 563*9880d681SAndroid Build Coastguard Worker; CHECK: entry: 564*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* %X, i8 0, i64 10000, i32 1, i1 false) 565*9880d681SAndroid Build Coastguard Worker; CHECK: ret void 566*9880d681SAndroid Build Coastguard Worker} 567*9880d681SAndroid Build Coastguard Worker 568*9880d681SAndroid Build Coastguard Worker; Validate that "memset_pattern" has the proper attributes. 569*9880d681SAndroid Build Coastguard Worker; CHECK: declare void @memset_pattern16(i8* nocapture, i8* nocapture readonly, i64) [[ATTRS:#[0-9]+]] 570*9880d681SAndroid Build Coastguard Worker; CHECK: [[ATTRS]] = { argmemonly } 571