1*9880d681SAndroid Build Coastguard Worker; RUN: opt -loop-accesses -analyze < %s | FileCheck %s 2*9880d681SAndroid Build Coastguard Worker; RUN: opt -passes='require<scalar-evolution>,require<aa>,loop(print-access-info)' -disable-output < %s 2>&1 | FileCheck %s 3*9880d681SAndroid Build Coastguard Worker 4*9880d681SAndroid Build Coastguard Workertarget datalayout = "e-m:e-i64:64-i128:128-n32:64-S128" 5*9880d681SAndroid Build Coastguard Workertarget triple = "aarch64--linux-gnueabi" 6*9880d681SAndroid Build Coastguard Worker 7*9880d681SAndroid Build Coastguard Worker; 3 reads and 3 writes should need 12 memchecks 8*9880d681SAndroid Build Coastguard Worker; CHECK: function 'testf': 9*9880d681SAndroid Build Coastguard Worker; CHECK: Memory dependences are safe with run-time checks 10*9880d681SAndroid Build Coastguard Worker 11*9880d681SAndroid Build Coastguard Worker; Memory dependencies have labels starting from 0, so in 12*9880d681SAndroid Build Coastguard Worker; order to verify that we have n checks, we look for 13*9880d681SAndroid Build Coastguard Worker; (n-1): and not n:. 14*9880d681SAndroid Build Coastguard Worker 15*9880d681SAndroid Build Coastguard Worker; CHECK: Run-time memory checks: 16*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: Check 0: 17*9880d681SAndroid Build Coastguard Worker; CHECK: Check 11: 18*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: Check 12: 19*9880d681SAndroid Build Coastguard Worker 20*9880d681SAndroid Build Coastguard Workerdefine void @testf(i16* %a, 21*9880d681SAndroid Build Coastguard Worker i16* %b, 22*9880d681SAndroid Build Coastguard Worker i16* %c, 23*9880d681SAndroid Build Coastguard Worker i16* %d, 24*9880d681SAndroid Build Coastguard Worker i16* %e, 25*9880d681SAndroid Build Coastguard Worker i16* %f) { 26*9880d681SAndroid Build Coastguard Workerentry: 27*9880d681SAndroid Build Coastguard Worker br label %for.body 28*9880d681SAndroid Build Coastguard Worker 29*9880d681SAndroid Build Coastguard Workerfor.body: ; preds = %for.body, %entry 30*9880d681SAndroid Build Coastguard Worker %ind = phi i64 [ 0, %entry ], [ %add, %for.body ] 31*9880d681SAndroid Build Coastguard Worker 32*9880d681SAndroid Build Coastguard Worker %add = add nuw nsw i64 %ind, 1 33*9880d681SAndroid Build Coastguard Worker 34*9880d681SAndroid Build Coastguard Worker %arrayidxA = getelementptr inbounds i16, i16* %a, i64 %ind 35*9880d681SAndroid Build Coastguard Worker %loadA = load i16, i16* %arrayidxA, align 2 36*9880d681SAndroid Build Coastguard Worker 37*9880d681SAndroid Build Coastguard Worker %arrayidxB = getelementptr inbounds i16, i16* %b, i64 %ind 38*9880d681SAndroid Build Coastguard Worker %loadB = load i16, i16* %arrayidxB, align 2 39*9880d681SAndroid Build Coastguard Worker 40*9880d681SAndroid Build Coastguard Worker %arrayidxC = getelementptr inbounds i16, i16* %c, i64 %ind 41*9880d681SAndroid Build Coastguard Worker %loadC = load i16, i16* %arrayidxC, align 2 42*9880d681SAndroid Build Coastguard Worker 43*9880d681SAndroid Build Coastguard Worker %mul = mul i16 %loadB, %loadA 44*9880d681SAndroid Build Coastguard Worker %mul1 = mul i16 %mul, %loadC 45*9880d681SAndroid Build Coastguard Worker 46*9880d681SAndroid Build Coastguard Worker %arrayidxD = getelementptr inbounds i16, i16* %d, i64 %ind 47*9880d681SAndroid Build Coastguard Worker store i16 %mul1, i16* %arrayidxD, align 2 48*9880d681SAndroid Build Coastguard Worker 49*9880d681SAndroid Build Coastguard Worker %arrayidxE = getelementptr inbounds i16, i16* %e, i64 %ind 50*9880d681SAndroid Build Coastguard Worker store i16 %mul, i16* %arrayidxE, align 2 51*9880d681SAndroid Build Coastguard Worker 52*9880d681SAndroid Build Coastguard Worker %arrayidxF = getelementptr inbounds i16, i16* %f, i64 %ind 53*9880d681SAndroid Build Coastguard Worker store i16 %mul1, i16* %arrayidxF, align 2 54*9880d681SAndroid Build Coastguard Worker 55*9880d681SAndroid Build Coastguard Worker %exitcond = icmp eq i64 %add, 20 56*9880d681SAndroid Build Coastguard Worker br i1 %exitcond, label %for.end, label %for.body 57*9880d681SAndroid Build Coastguard Worker 58*9880d681SAndroid Build Coastguard Workerfor.end: ; preds = %for.body 59*9880d681SAndroid Build Coastguard Worker ret void 60*9880d681SAndroid Build Coastguard Worker} 61*9880d681SAndroid Build Coastguard Worker 62*9880d681SAndroid Build Coastguard Worker; The following (testg and testh) check that we can group 63*9880d681SAndroid Build Coastguard Worker; memory checks of accesses which differ by a constant value. 64*9880d681SAndroid Build Coastguard Worker; Both tests are based on the following C code: 65*9880d681SAndroid Build Coastguard Worker; 66*9880d681SAndroid Build Coastguard Worker; void testh(short *a, short *b, short *c) { 67*9880d681SAndroid Build Coastguard Worker; unsigned long ind = 0; 68*9880d681SAndroid Build Coastguard Worker; for (unsigned long ind = 0; ind < 20; ++ind) { 69*9880d681SAndroid Build Coastguard Worker; c[2 * ind] = a[ind] * a[ind + 1]; 70*9880d681SAndroid Build Coastguard Worker; c[2 * ind + 1] = a[ind] * a[ind + 1] * b[ind]; 71*9880d681SAndroid Build Coastguard Worker; } 72*9880d681SAndroid Build Coastguard Worker; } 73*9880d681SAndroid Build Coastguard Worker; 74*9880d681SAndroid Build Coastguard Worker; It is sufficient to check the intervals 75*9880d681SAndroid Build Coastguard Worker; [a, a + 21], [b, b + 20] against [c, c + 41]. 76*9880d681SAndroid Build Coastguard Worker 77*9880d681SAndroid Build Coastguard Worker; 3 reads and 2 writes - two of the reads can be merged, 78*9880d681SAndroid Build Coastguard Worker; and the writes can be merged as well. This gives us a 79*9880d681SAndroid Build Coastguard Worker; total of 2 memory checks. 80*9880d681SAndroid Build Coastguard Worker 81*9880d681SAndroid Build Coastguard Worker; CHECK: function 'testg': 82*9880d681SAndroid Build Coastguard Worker 83*9880d681SAndroid Build Coastguard Worker; CHECK: Run-time memory checks: 84*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: Check 0: 85*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: Comparing group ([[ZERO:.+]]): 86*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %arrayidxC1 = getelementptr inbounds i16, i16* %c, i64 %store_ind_inc 87*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %arrayidxC = getelementptr inbounds i16, i16* %c, i64 %store_ind 88*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: Against group ([[ONE:.+]]): 89*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %arrayidxA1 = getelementptr inbounds i16, i16* %a, i64 %add 90*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %arrayidxA = getelementptr inbounds i16, i16* %a, i64 %ind 91*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: Check 1: 92*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: Comparing group ({{.*}}[[ZERO]]): 93*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %arrayidxC1 = getelementptr inbounds i16, i16* %c, i64 %store_ind_inc 94*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %arrayidxC = getelementptr inbounds i16, i16* %c, i64 %store_ind 95*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: Against group ([[TWO:.+]]): 96*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %arrayidxB = getelementptr inbounds i16, i16* %b, i64 %ind 97*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: Grouped accesses: 98*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: Group {{.*}}[[ZERO]]: 99*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: (Low: %c High: (78 + %c)) 100*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: Member: {(2 + %c)<nsw>,+,4} 101*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: Member: {%c,+,4} 102*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: Group {{.*}}[[ONE]]: 103*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: (Low: %a High: (40 + %a)) 104*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: Member: {(2 + %a)<nsw>,+,2} 105*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: Member: {%a,+,2} 106*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: Group {{.*}}[[TWO]]: 107*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: (Low: %b High: (38 + %b)) 108*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: Member: {%b,+,2} 109*9880d681SAndroid Build Coastguard Worker 110*9880d681SAndroid Build Coastguard Workerdefine void @testg(i16* %a, 111*9880d681SAndroid Build Coastguard Worker i16* %b, 112*9880d681SAndroid Build Coastguard Worker i16* %c) { 113*9880d681SAndroid Build Coastguard Workerentry: 114*9880d681SAndroid Build Coastguard Worker br label %for.body 115*9880d681SAndroid Build Coastguard Worker 116*9880d681SAndroid Build Coastguard Workerfor.body: ; preds = %for.body, %entry 117*9880d681SAndroid Build Coastguard Worker %ind = phi i64 [ 0, %entry ], [ %add, %for.body ] 118*9880d681SAndroid Build Coastguard Worker %store_ind = phi i64 [ 0, %entry ], [ %store_ind_next, %for.body ] 119*9880d681SAndroid Build Coastguard Worker 120*9880d681SAndroid Build Coastguard Worker %add = add nuw nsw i64 %ind, 1 121*9880d681SAndroid Build Coastguard Worker %store_ind_inc = add nuw nsw i64 %store_ind, 1 122*9880d681SAndroid Build Coastguard Worker %store_ind_next = add nuw nsw i64 %store_ind_inc, 1 123*9880d681SAndroid Build Coastguard Worker 124*9880d681SAndroid Build Coastguard Worker %arrayidxA = getelementptr inbounds i16, i16* %a, i64 %ind 125*9880d681SAndroid Build Coastguard Worker %loadA = load i16, i16* %arrayidxA, align 2 126*9880d681SAndroid Build Coastguard Worker 127*9880d681SAndroid Build Coastguard Worker %arrayidxA1 = getelementptr inbounds i16, i16* %a, i64 %add 128*9880d681SAndroid Build Coastguard Worker %loadA1 = load i16, i16* %arrayidxA1, align 2 129*9880d681SAndroid Build Coastguard Worker 130*9880d681SAndroid Build Coastguard Worker %arrayidxB = getelementptr inbounds i16, i16* %b, i64 %ind 131*9880d681SAndroid Build Coastguard Worker %loadB = load i16, i16* %arrayidxB, align 2 132*9880d681SAndroid Build Coastguard Worker 133*9880d681SAndroid Build Coastguard Worker %mul = mul i16 %loadA, %loadA1 134*9880d681SAndroid Build Coastguard Worker %mul1 = mul i16 %mul, %loadB 135*9880d681SAndroid Build Coastguard Worker 136*9880d681SAndroid Build Coastguard Worker %arrayidxC = getelementptr inbounds i16, i16* %c, i64 %store_ind 137*9880d681SAndroid Build Coastguard Worker store i16 %mul1, i16* %arrayidxC, align 2 138*9880d681SAndroid Build Coastguard Worker 139*9880d681SAndroid Build Coastguard Worker %arrayidxC1 = getelementptr inbounds i16, i16* %c, i64 %store_ind_inc 140*9880d681SAndroid Build Coastguard Worker store i16 %mul, i16* %arrayidxC1, align 2 141*9880d681SAndroid Build Coastguard Worker 142*9880d681SAndroid Build Coastguard Worker %exitcond = icmp eq i64 %add, 20 143*9880d681SAndroid Build Coastguard Worker br i1 %exitcond, label %for.end, label %for.body 144*9880d681SAndroid Build Coastguard Worker 145*9880d681SAndroid Build Coastguard Workerfor.end: ; preds = %for.body 146*9880d681SAndroid Build Coastguard Worker ret void 147*9880d681SAndroid Build Coastguard Worker} 148*9880d681SAndroid Build Coastguard Worker 149*9880d681SAndroid Build Coastguard Worker; 3 reads and 2 writes - the writes can be merged into a single 150*9880d681SAndroid Build Coastguard Worker; group, but the GEPs used for the reads are not marked as inbounds. 151*9880d681SAndroid Build Coastguard Worker; We can still merge them because we are using a unit stride for 152*9880d681SAndroid Build Coastguard Worker; accesses, so we cannot overflow the GEPs. 153*9880d681SAndroid Build Coastguard Worker 154*9880d681SAndroid Build Coastguard Worker; CHECK: function 'testh': 155*9880d681SAndroid Build Coastguard Worker; CHECK: Run-time memory checks: 156*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: Check 0: 157*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: Comparing group ([[ZERO:.+]]): 158*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %arrayidxC1 = getelementptr inbounds i16, i16* %c, i64 %store_ind_inc 159*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %arrayidxC = getelementptr inbounds i16, i16* %c, i64 %store_ind 160*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: Against group ([[ONE:.+]]): 161*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %arrayidxA1 = getelementptr i16, i16* %a, i64 %add 162*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %arrayidxA = getelementptr i16, i16* %a, i64 %ind 163*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: Check 1: 164*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: Comparing group ({{.*}}[[ZERO]]): 165*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %arrayidxC1 = getelementptr inbounds i16, i16* %c, i64 %store_ind_inc 166*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %arrayidxC = getelementptr inbounds i16, i16* %c, i64 %store_ind 167*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: Against group ([[TWO:.+]]): 168*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %arrayidxB = getelementptr i16, i16* %b, i64 %ind 169*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: Grouped accesses: 170*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: Group {{.*}}[[ZERO]]: 171*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: (Low: %c High: (78 + %c)) 172*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: Member: {(2 + %c)<nsw>,+,4} 173*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: Member: {%c,+,4} 174*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: Group {{.*}}[[ONE]]: 175*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: (Low: %a High: (40 + %a)) 176*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: Member: {(2 + %a),+,2} 177*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: Member: {%a,+,2} 178*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: Group {{.*}}[[TWO]]: 179*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: (Low: %b High: (38 + %b)) 180*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: Member: {%b,+,2} 181*9880d681SAndroid Build Coastguard Worker 182*9880d681SAndroid Build Coastguard Workerdefine void @testh(i16* %a, 183*9880d681SAndroid Build Coastguard Worker i16* %b, 184*9880d681SAndroid Build Coastguard Worker i16* %c) { 185*9880d681SAndroid Build Coastguard Workerentry: 186*9880d681SAndroid Build Coastguard Worker br label %for.body 187*9880d681SAndroid Build Coastguard Worker 188*9880d681SAndroid Build Coastguard Workerfor.body: ; preds = %for.body, %entry 189*9880d681SAndroid Build Coastguard Worker %ind = phi i64 [ 0, %entry ], [ %add, %for.body ] 190*9880d681SAndroid Build Coastguard Worker %store_ind = phi i64 [ 0, %entry ], [ %store_ind_next, %for.body ] 191*9880d681SAndroid Build Coastguard Worker 192*9880d681SAndroid Build Coastguard Worker %add = add nuw nsw i64 %ind, 1 193*9880d681SAndroid Build Coastguard Worker %store_ind_inc = add nuw nsw i64 %store_ind, 1 194*9880d681SAndroid Build Coastguard Worker %store_ind_next = add nuw nsw i64 %store_ind_inc, 1 195*9880d681SAndroid Build Coastguard Worker 196*9880d681SAndroid Build Coastguard Worker %arrayidxA = getelementptr i16, i16* %a, i64 %ind 197*9880d681SAndroid Build Coastguard Worker %loadA = load i16, i16* %arrayidxA, align 2 198*9880d681SAndroid Build Coastguard Worker 199*9880d681SAndroid Build Coastguard Worker %arrayidxA1 = getelementptr i16, i16* %a, i64 %add 200*9880d681SAndroid Build Coastguard Worker %loadA1 = load i16, i16* %arrayidxA1, align 2 201*9880d681SAndroid Build Coastguard Worker 202*9880d681SAndroid Build Coastguard Worker %arrayidxB = getelementptr i16, i16* %b, i64 %ind 203*9880d681SAndroid Build Coastguard Worker %loadB = load i16, i16* %arrayidxB, align 2 204*9880d681SAndroid Build Coastguard Worker 205*9880d681SAndroid Build Coastguard Worker %mul = mul i16 %loadA, %loadA1 206*9880d681SAndroid Build Coastguard Worker %mul1 = mul i16 %mul, %loadB 207*9880d681SAndroid Build Coastguard Worker 208*9880d681SAndroid Build Coastguard Worker %arrayidxC = getelementptr inbounds i16, i16* %c, i64 %store_ind 209*9880d681SAndroid Build Coastguard Worker store i16 %mul1, i16* %arrayidxC, align 2 210*9880d681SAndroid Build Coastguard Worker 211*9880d681SAndroid Build Coastguard Worker %arrayidxC1 = getelementptr inbounds i16, i16* %c, i64 %store_ind_inc 212*9880d681SAndroid Build Coastguard Worker store i16 %mul, i16* %arrayidxC1, align 2 213*9880d681SAndroid Build Coastguard Worker 214*9880d681SAndroid Build Coastguard Worker %exitcond = icmp eq i64 %add, 20 215*9880d681SAndroid Build Coastguard Worker br i1 %exitcond, label %for.end, label %for.body 216*9880d681SAndroid Build Coastguard Worker 217*9880d681SAndroid Build Coastguard Workerfor.end: ; preds = %for.body 218*9880d681SAndroid Build Coastguard Worker ret void 219*9880d681SAndroid Build Coastguard Worker} 220*9880d681SAndroid Build Coastguard Worker 221*9880d681SAndroid Build Coastguard Worker; Don't merge pointers if we need to perform a check against a pointer 222*9880d681SAndroid Build Coastguard Worker; to the same underlying object (doing so would emit a check that could be 223*9880d681SAndroid Build Coastguard Worker; falsely invalidated) For example, in the following loop: 224*9880d681SAndroid Build Coastguard Worker; 225*9880d681SAndroid Build Coastguard Worker; for (i = 0; i < 5000; ++i) 226*9880d681SAndroid Build Coastguard Worker; a[i + offset] = a[i] + a[i + 10000] 227*9880d681SAndroid Build Coastguard Worker; 228*9880d681SAndroid Build Coastguard Worker; we should not merge the intervals associated with the reads (0,5000) and 229*9880d681SAndroid Build Coastguard Worker; (10000, 15000) into (0, 15000) as this will pottentially fail the check 230*9880d681SAndroid Build Coastguard Worker; against the interval associated with the write. 231*9880d681SAndroid Build Coastguard Worker; 232*9880d681SAndroid Build Coastguard Worker; We cannot have this check unless ShouldRetryWithRuntimeCheck is set, 233*9880d681SAndroid Build Coastguard Worker; and therefore the grouping algorithm would create a separate group for 234*9880d681SAndroid Build Coastguard Worker; each pointer. 235*9880d681SAndroid Build Coastguard Worker 236*9880d681SAndroid Build Coastguard Worker; CHECK: function 'testi': 237*9880d681SAndroid Build Coastguard Worker; CHECK: Run-time memory checks: 238*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: Check 0: 239*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: Comparing group ([[ZERO:.+]]): 240*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %storeidx = getelementptr inbounds i16, i16* %a, i64 %store_ind 241*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: Against group ([[ONE:.+]]): 242*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %arrayidxA1 = getelementptr i16, i16* %a, i64 %ind 243*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: Check 1: 244*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: Comparing group ({{.*}}[[ZERO]]): 245*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %storeidx = getelementptr inbounds i16, i16* %a, i64 %store_ind 246*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: Against group ([[TWO:.+]]): 247*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %arrayidxA2 = getelementptr i16, i16* %a, i64 %ind2 248*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: Grouped accesses: 249*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: Group {{.*}}[[ZERO]]: 250*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: (Low: ((2 * %offset) + %a)<nsw> High: (9998 + (2 * %offset) + %a)) 251*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: Member: {((2 * %offset) + %a)<nsw>,+,2}<nsw><%for.body> 252*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: Group {{.*}}[[ONE]]: 253*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: (Low: %a High: (9998 + %a)) 254*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: Member: {%a,+,2}<%for.body> 255*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: Group {{.*}}[[TWO]]: 256*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: (Low: (20000 + %a) High: (29998 + %a)) 257*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: Member: {(20000 + %a),+,2}<%for.body> 258*9880d681SAndroid Build Coastguard Worker 259*9880d681SAndroid Build Coastguard Workerdefine void @testi(i16* %a, 260*9880d681SAndroid Build Coastguard Worker i64 %offset) { 261*9880d681SAndroid Build Coastguard Workerentry: 262*9880d681SAndroid Build Coastguard Worker br label %for.body 263*9880d681SAndroid Build Coastguard Worker 264*9880d681SAndroid Build Coastguard Workerfor.body: ; preds = %for.body, %entry 265*9880d681SAndroid Build Coastguard Worker %ind = phi i64 [ 0, %entry ], [ %add, %for.body ] 266*9880d681SAndroid Build Coastguard Worker %store_ind = phi i64 [ %offset, %entry ], [ %store_ind_inc, %for.body ] 267*9880d681SAndroid Build Coastguard Worker 268*9880d681SAndroid Build Coastguard Worker %add = add nuw nsw i64 %ind, 1 269*9880d681SAndroid Build Coastguard Worker %store_ind_inc = add nuw nsw i64 %store_ind, 1 270*9880d681SAndroid Build Coastguard Worker 271*9880d681SAndroid Build Coastguard Worker %arrayidxA1 = getelementptr i16, i16* %a, i64 %ind 272*9880d681SAndroid Build Coastguard Worker %ind2 = add nuw nsw i64 %ind, 10000 273*9880d681SAndroid Build Coastguard Worker %arrayidxA2 = getelementptr i16, i16* %a, i64 %ind2 274*9880d681SAndroid Build Coastguard Worker 275*9880d681SAndroid Build Coastguard Worker %loadA1 = load i16, i16* %arrayidxA1, align 2 276*9880d681SAndroid Build Coastguard Worker %loadA2 = load i16, i16* %arrayidxA2, align 2 277*9880d681SAndroid Build Coastguard Worker 278*9880d681SAndroid Build Coastguard Worker %addres = add i16 %loadA1, %loadA2 279*9880d681SAndroid Build Coastguard Worker 280*9880d681SAndroid Build Coastguard Worker %storeidx = getelementptr inbounds i16, i16* %a, i64 %store_ind 281*9880d681SAndroid Build Coastguard Worker store i16 %addres, i16* %storeidx, align 2 282*9880d681SAndroid Build Coastguard Worker 283*9880d681SAndroid Build Coastguard Worker %exitcond = icmp eq i64 %add, 5000 284*9880d681SAndroid Build Coastguard Worker br i1 %exitcond, label %for.end, label %for.body 285*9880d681SAndroid Build Coastguard Worker 286*9880d681SAndroid Build Coastguard Workerfor.end: ; preds = %for.body 287*9880d681SAndroid Build Coastguard Worker ret void 288*9880d681SAndroid Build Coastguard Worker} 289