1*9880d681SAndroid Build Coastguard Worker; RUN: opt -disable-output < %s -disable-basicaa -scev-aa -aa-eval -print-all-alias-modref-info \ 2*9880d681SAndroid Build Coastguard Worker; RUN: 2>&1 | FileCheck %s 3*9880d681SAndroid Build Coastguard Worker; RUN: opt -disable-output < %s -aa-pipeline=scev-aa -passes=aa-eval -print-all-alias-modref-info \ 4*9880d681SAndroid Build Coastguard Worker; RUN: 2>&1 | FileCheck %s 5*9880d681SAndroid Build Coastguard Worker 6*9880d681SAndroid Build Coastguard Worker; At the time of this writing, -basicaa misses the example of the form 7*9880d681SAndroid Build Coastguard Worker; A[i+(j+1)] != A[i+j], which can arise from multi-dimensional array references, 8*9880d681SAndroid Build Coastguard Worker; and the example of the form A[0] != A[i+1], where i+1 is known to be positive. 9*9880d681SAndroid Build Coastguard Worker 10*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" 11*9880d681SAndroid Build Coastguard Worker 12*9880d681SAndroid Build Coastguard Worker; p[i] and p[i+1] don't alias. 13*9880d681SAndroid Build Coastguard Worker 14*9880d681SAndroid Build Coastguard Worker; CHECK: Function: loop: 3 pointers, 0 call sites 15*9880d681SAndroid Build Coastguard Worker; CHECK: NoAlias: double* %pi, double* %pi.next 16*9880d681SAndroid Build Coastguard Worker 17*9880d681SAndroid Build Coastguard Workerdefine void @loop(double* nocapture %p, i64 %n) nounwind { 18*9880d681SAndroid Build Coastguard Workerentry: 19*9880d681SAndroid Build Coastguard Worker %j = icmp sgt i64 %n, 0 20*9880d681SAndroid Build Coastguard Worker br i1 %j, label %bb, label %return 21*9880d681SAndroid Build Coastguard Worker 22*9880d681SAndroid Build Coastguard Workerbb: 23*9880d681SAndroid Build Coastguard Worker %i = phi i64 [ 0, %entry ], [ %i.next, %bb ] 24*9880d681SAndroid Build Coastguard Worker %pi = getelementptr double, double* %p, i64 %i 25*9880d681SAndroid Build Coastguard Worker %i.next = add i64 %i, 1 26*9880d681SAndroid Build Coastguard Worker %pi.next = getelementptr double, double* %p, i64 %i.next 27*9880d681SAndroid Build Coastguard Worker %x = load double, double* %pi 28*9880d681SAndroid Build Coastguard Worker %y = load double, double* %pi.next 29*9880d681SAndroid Build Coastguard Worker %z = fmul double %x, %y 30*9880d681SAndroid Build Coastguard Worker store double %z, double* %pi 31*9880d681SAndroid Build Coastguard Worker %exitcond = icmp eq i64 %i.next, %n 32*9880d681SAndroid Build Coastguard Worker br i1 %exitcond, label %return, label %bb 33*9880d681SAndroid Build Coastguard Worker 34*9880d681SAndroid Build Coastguard Workerreturn: 35*9880d681SAndroid Build Coastguard Worker ret void 36*9880d681SAndroid Build Coastguard Worker} 37*9880d681SAndroid Build Coastguard Worker 38*9880d681SAndroid Build Coastguard Worker; Slightly more involved: p[j][i], p[j][i+1], and p[j+1][i] don't alias. 39*9880d681SAndroid Build Coastguard Worker 40*9880d681SAndroid Build Coastguard Worker; CHECK: Function: nestedloop: 4 pointers, 0 call sites 41*9880d681SAndroid Build Coastguard Worker; CHECK: NoAlias: double* %pi.j, double* %pi.next.j 42*9880d681SAndroid Build Coastguard Worker; CHECK: NoAlias: double* %pi.j, double* %pi.j.next 43*9880d681SAndroid Build Coastguard Worker; CHECK: NoAlias: double* %pi.j.next, double* %pi.next.j 44*9880d681SAndroid Build Coastguard Worker 45*9880d681SAndroid Build Coastguard Workerdefine void @nestedloop(double* nocapture %p, i64 %m) nounwind { 46*9880d681SAndroid Build Coastguard Workerentry: 47*9880d681SAndroid Build Coastguard Worker %k = icmp sgt i64 %m, 0 48*9880d681SAndroid Build Coastguard Worker br i1 %k, label %guard, label %return 49*9880d681SAndroid Build Coastguard Worker 50*9880d681SAndroid Build Coastguard Workerguard: 51*9880d681SAndroid Build Coastguard Worker %l = icmp sgt i64 91, 0 52*9880d681SAndroid Build Coastguard Worker br i1 %l, label %outer.loop, label %return 53*9880d681SAndroid Build Coastguard Worker 54*9880d681SAndroid Build Coastguard Workerouter.loop: 55*9880d681SAndroid Build Coastguard Worker %j = phi i64 [ 0, %guard ], [ %j.next, %outer.latch ] 56*9880d681SAndroid Build Coastguard Worker br label %bb 57*9880d681SAndroid Build Coastguard Worker 58*9880d681SAndroid Build Coastguard Workerbb: 59*9880d681SAndroid Build Coastguard Worker %i = phi i64 [ 0, %outer.loop ], [ %i.next, %bb ] 60*9880d681SAndroid Build Coastguard Worker %i.next = add i64 %i, 1 61*9880d681SAndroid Build Coastguard Worker 62*9880d681SAndroid Build Coastguard Worker %e = add i64 %i, %j 63*9880d681SAndroid Build Coastguard Worker %pi.j = getelementptr double, double* %p, i64 %e 64*9880d681SAndroid Build Coastguard Worker %f = add i64 %i.next, %j 65*9880d681SAndroid Build Coastguard Worker %pi.next.j = getelementptr double, double* %p, i64 %f 66*9880d681SAndroid Build Coastguard Worker %x = load double, double* %pi.j 67*9880d681SAndroid Build Coastguard Worker %y = load double, double* %pi.next.j 68*9880d681SAndroid Build Coastguard Worker %z = fmul double %x, %y 69*9880d681SAndroid Build Coastguard Worker store double %z, double* %pi.j 70*9880d681SAndroid Build Coastguard Worker 71*9880d681SAndroid Build Coastguard Worker %o = add i64 %j, 91 72*9880d681SAndroid Build Coastguard Worker %g = add i64 %i, %o 73*9880d681SAndroid Build Coastguard Worker %pi.j.next = getelementptr double, double* %p, i64 %g 74*9880d681SAndroid Build Coastguard Worker %a = load double, double* %pi.j.next 75*9880d681SAndroid Build Coastguard Worker %b = fmul double %x, %a 76*9880d681SAndroid Build Coastguard Worker store double %b, double* %pi.j.next 77*9880d681SAndroid Build Coastguard Worker 78*9880d681SAndroid Build Coastguard Worker %exitcond = icmp eq i64 %i.next, 91 79*9880d681SAndroid Build Coastguard Worker br i1 %exitcond, label %outer.latch, label %bb 80*9880d681SAndroid Build Coastguard Worker 81*9880d681SAndroid Build Coastguard Workerouter.latch: 82*9880d681SAndroid Build Coastguard Worker %j.next = add i64 %j, 91 83*9880d681SAndroid Build Coastguard Worker %h = icmp eq i64 %j.next, %m 84*9880d681SAndroid Build Coastguard Worker br i1 %h, label %return, label %outer.loop 85*9880d681SAndroid Build Coastguard Worker 86*9880d681SAndroid Build Coastguard Workerreturn: 87*9880d681SAndroid Build Coastguard Worker ret void 88*9880d681SAndroid Build Coastguard Worker} 89*9880d681SAndroid Build Coastguard Worker 90*9880d681SAndroid Build Coastguard Worker; Even more involved: same as nestedloop, but with a variable extent. 91*9880d681SAndroid Build Coastguard Worker; When n is 1, p[j+1][i] does alias p[j][i+1], and there's no way to 92*9880d681SAndroid Build Coastguard Worker; prove whether n will be greater than 1, so that relation will always 93*9880d681SAndroid Build Coastguard Worker; by MayAlias. The loop is guarded by a n > 0 test though, so 94*9880d681SAndroid Build Coastguard Worker; p[j+1][i] and p[j][i] can theoretically be determined to be NoAlias, 95*9880d681SAndroid Build Coastguard Worker; however the analysis currently doesn't do that. 96*9880d681SAndroid Build Coastguard Worker; TODO: Make the analysis smarter and turn that MayAlias into a NoAlias. 97*9880d681SAndroid Build Coastguard Worker 98*9880d681SAndroid Build Coastguard Worker; CHECK: Function: nestedloop_more: 4 pointers, 0 call sites 99*9880d681SAndroid Build Coastguard Worker; CHECK: NoAlias: double* %pi.j, double* %pi.next.j 100*9880d681SAndroid Build Coastguard Worker; CHECK: MayAlias: double* %pi.j, double* %pi.j.next 101*9880d681SAndroid Build Coastguard Worker 102*9880d681SAndroid Build Coastguard Workerdefine void @nestedloop_more(double* nocapture %p, i64 %n, i64 %m) nounwind { 103*9880d681SAndroid Build Coastguard Workerentry: 104*9880d681SAndroid Build Coastguard Worker %k = icmp sgt i64 %m, 0 105*9880d681SAndroid Build Coastguard Worker br i1 %k, label %guard, label %return 106*9880d681SAndroid Build Coastguard Worker 107*9880d681SAndroid Build Coastguard Workerguard: 108*9880d681SAndroid Build Coastguard Worker %l = icmp sgt i64 %n, 0 109*9880d681SAndroid Build Coastguard Worker br i1 %l, label %outer.loop, label %return 110*9880d681SAndroid Build Coastguard Worker 111*9880d681SAndroid Build Coastguard Workerouter.loop: 112*9880d681SAndroid Build Coastguard Worker %j = phi i64 [ 0, %guard ], [ %j.next, %outer.latch ] 113*9880d681SAndroid Build Coastguard Worker br label %bb 114*9880d681SAndroid Build Coastguard Worker 115*9880d681SAndroid Build Coastguard Workerbb: 116*9880d681SAndroid Build Coastguard Worker %i = phi i64 [ 0, %outer.loop ], [ %i.next, %bb ] 117*9880d681SAndroid Build Coastguard Worker %i.next = add i64 %i, 1 118*9880d681SAndroid Build Coastguard Worker 119*9880d681SAndroid Build Coastguard Worker %e = add i64 %i, %j 120*9880d681SAndroid Build Coastguard Worker %pi.j = getelementptr double, double* %p, i64 %e 121*9880d681SAndroid Build Coastguard Worker %f = add i64 %i.next, %j 122*9880d681SAndroid Build Coastguard Worker %pi.next.j = getelementptr double, double* %p, i64 %f 123*9880d681SAndroid Build Coastguard Worker %x = load double, double* %pi.j 124*9880d681SAndroid Build Coastguard Worker %y = load double, double* %pi.next.j 125*9880d681SAndroid Build Coastguard Worker %z = fmul double %x, %y 126*9880d681SAndroid Build Coastguard Worker store double %z, double* %pi.j 127*9880d681SAndroid Build Coastguard Worker 128*9880d681SAndroid Build Coastguard Worker %o = add i64 %j, %n 129*9880d681SAndroid Build Coastguard Worker %g = add i64 %i, %o 130*9880d681SAndroid Build Coastguard Worker %pi.j.next = getelementptr double, double* %p, i64 %g 131*9880d681SAndroid Build Coastguard Worker %a = load double, double* %pi.j.next 132*9880d681SAndroid Build Coastguard Worker %b = fmul double %x, %a 133*9880d681SAndroid Build Coastguard Worker store double %b, double* %pi.j.next 134*9880d681SAndroid Build Coastguard Worker 135*9880d681SAndroid Build Coastguard Worker %exitcond = icmp eq i64 %i.next, %n 136*9880d681SAndroid Build Coastguard Worker br i1 %exitcond, label %outer.latch, label %bb 137*9880d681SAndroid Build Coastguard Worker 138*9880d681SAndroid Build Coastguard Workerouter.latch: 139*9880d681SAndroid Build Coastguard Worker %j.next = add i64 %j, %n 140*9880d681SAndroid Build Coastguard Worker %h = icmp eq i64 %j.next, %m 141*9880d681SAndroid Build Coastguard Worker br i1 %h, label %return, label %outer.loop 142*9880d681SAndroid Build Coastguard Worker 143*9880d681SAndroid Build Coastguard Workerreturn: 144*9880d681SAndroid Build Coastguard Worker ret void 145*9880d681SAndroid Build Coastguard Worker} 146*9880d681SAndroid Build Coastguard Worker 147*9880d681SAndroid Build Coastguard Worker; ScalarEvolution expands field offsets into constants, which allows it to 148*9880d681SAndroid Build Coastguard Worker; do aggressive analysis. Contrast this with BasicAA, which works by 149*9880d681SAndroid Build Coastguard Worker; recognizing GEP idioms. 150*9880d681SAndroid Build Coastguard Worker 151*9880d681SAndroid Build Coastguard Worker%struct.A = type { %struct.B, i32, i32 } 152*9880d681SAndroid Build Coastguard Worker%struct.B = type { double } 153*9880d681SAndroid Build Coastguard Worker 154*9880d681SAndroid Build Coastguard Worker; CHECK: Function: foo: 7 pointers, 0 call sites 155*9880d681SAndroid Build Coastguard Worker; CHECK: NoAlias: %struct.B* %B, i32* %Z 156*9880d681SAndroid Build Coastguard Worker; CHECK: NoAlias: %struct.B* %B, %struct.B* %C 157*9880d681SAndroid Build Coastguard Worker; CHECK: MustAlias: %struct.B* %C, i32* %Z 158*9880d681SAndroid Build Coastguard Worker; CHECK: NoAlias: %struct.B* %B, i32* %X 159*9880d681SAndroid Build Coastguard Worker; CHECK: MustAlias: i32* %X, i32* %Z 160*9880d681SAndroid Build Coastguard Worker; CHECK: MustAlias: %struct.B* %C, i32* %Y 161*9880d681SAndroid Build Coastguard Worker; CHECK: MustAlias: i32* %X, i32* %Y 162*9880d681SAndroid Build Coastguard Worker 163*9880d681SAndroid Build Coastguard Workerdefine void @foo() { 164*9880d681SAndroid Build Coastguard Workerentry: 165*9880d681SAndroid Build Coastguard Worker %A = alloca %struct.A 166*9880d681SAndroid Build Coastguard Worker %B = getelementptr %struct.A, %struct.A* %A, i32 0, i32 0 167*9880d681SAndroid Build Coastguard Worker %Q = bitcast %struct.B* %B to %struct.A* 168*9880d681SAndroid Build Coastguard Worker %Z = getelementptr %struct.A, %struct.A* %Q, i32 0, i32 1 169*9880d681SAndroid Build Coastguard Worker %C = getelementptr %struct.B, %struct.B* %B, i32 1 170*9880d681SAndroid Build Coastguard Worker %X = bitcast %struct.B* %C to i32* 171*9880d681SAndroid Build Coastguard Worker %Y = getelementptr %struct.A, %struct.A* %A, i32 0, i32 1 172*9880d681SAndroid Build Coastguard Worker ret void 173*9880d681SAndroid Build Coastguard Worker} 174*9880d681SAndroid Build Coastguard Worker 175*9880d681SAndroid Build Coastguard Worker; CHECK: Function: bar: 7 pointers, 0 call sites 176*9880d681SAndroid Build Coastguard Worker; CHECK: NoAlias: %struct.B* %N, i32* %P 177*9880d681SAndroid Build Coastguard Worker; CHECK: NoAlias: %struct.B* %N, %struct.B* %R 178*9880d681SAndroid Build Coastguard Worker; CHECK: MustAlias: %struct.B* %R, i32* %P 179*9880d681SAndroid Build Coastguard Worker; CHECK: NoAlias: %struct.B* %N, i32* %W 180*9880d681SAndroid Build Coastguard Worker; CHECK: MustAlias: i32* %P, i32* %W 181*9880d681SAndroid Build Coastguard Worker; CHECK: MustAlias: %struct.B* %R, i32* %V 182*9880d681SAndroid Build Coastguard Worker; CHECK: MustAlias: i32* %V, i32* %W 183*9880d681SAndroid Build Coastguard Worker 184*9880d681SAndroid Build Coastguard Workerdefine void @bar() { 185*9880d681SAndroid Build Coastguard Worker %M = alloca %struct.A 186*9880d681SAndroid Build Coastguard Worker %N = getelementptr %struct.A, %struct.A* %M, i32 0, i32 0 187*9880d681SAndroid Build Coastguard Worker %O = bitcast %struct.B* %N to %struct.A* 188*9880d681SAndroid Build Coastguard Worker %P = getelementptr %struct.A, %struct.A* %O, i32 0, i32 1 189*9880d681SAndroid Build Coastguard Worker %R = getelementptr %struct.B, %struct.B* %N, i32 1 190*9880d681SAndroid Build Coastguard Worker %W = bitcast %struct.B* %R to i32* 191*9880d681SAndroid Build Coastguard Worker %V = getelementptr %struct.A, %struct.A* %M, i32 0, i32 1 192*9880d681SAndroid Build Coastguard Worker ret void 193*9880d681SAndroid Build Coastguard Worker} 194*9880d681SAndroid Build Coastguard Worker 195*9880d681SAndroid Build Coastguard Worker; CHECK: Function: nonnegative: 2 pointers, 0 call sites 196*9880d681SAndroid Build Coastguard Worker; CHECK: NoAlias: i64* %arrayidx, i64* %p 197*9880d681SAndroid Build Coastguard Worker 198*9880d681SAndroid Build Coastguard Workerdefine void @nonnegative(i64* %p) nounwind { 199*9880d681SAndroid Build Coastguard Workerentry: 200*9880d681SAndroid Build Coastguard Worker br label %for.body 201*9880d681SAndroid Build Coastguard Worker 202*9880d681SAndroid Build Coastguard Workerfor.body: ; preds = %entry, %for.body 203*9880d681SAndroid Build Coastguard Worker %i = phi i64 [ %inc, %for.body ], [ 0, %entry ] ; <i64> [#uses=2] 204*9880d681SAndroid Build Coastguard Worker %inc = add nsw i64 %i, 1 ; <i64> [#uses=2] 205*9880d681SAndroid Build Coastguard Worker %arrayidx = getelementptr inbounds i64, i64* %p, i64 %inc 206*9880d681SAndroid Build Coastguard Worker store i64 0, i64* %arrayidx 207*9880d681SAndroid Build Coastguard Worker %tmp6 = load i64, i64* %p ; <i64> [#uses=1] 208*9880d681SAndroid Build Coastguard Worker %cmp = icmp slt i64 %inc, %tmp6 ; <i1> [#uses=1] 209*9880d681SAndroid Build Coastguard Worker br i1 %cmp, label %for.body, label %for.end 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} 214*9880d681SAndroid Build Coastguard Worker 215*9880d681SAndroid Build Coastguard Worker; CHECK: 14 no alias responses 216*9880d681SAndroid Build Coastguard Worker; CHECK: 26 may alias responses 217*9880d681SAndroid Build Coastguard Worker; CHECK: 18 must alias responses 218