427 lines · plain
1; RUN: opt < %s -aa-pipeline=basic-aa -passes=aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s2 3; CHECK-LABEL: Function: simple: 5 pointers, 0 call sites4; CHECK: NoAlias: float* %src1, float* %src25; CHECK: NoAlias: float* %phi, float* %src16; CHECK: MayAlias: float* %phi, float* %src27; CHECK: NoAlias: float* %next, float* %src18; CHECK: MayAlias: float* %next, float* %src29; CHECK: NoAlias: float* %next, float* %phi10; CHECK: NoAlias: float* %g, float* %src111; CHECK: NoAlias: float* %g, float* %src212; CHECK: NoAlias: float* %g, float* %phi13; CHECK: NoAlias: float* %g, float* %next14define void @simple(ptr %src1, ptr noalias %src2, i32 %n) nounwind {15entry:16 load float, ptr %src117 load float, ptr %src218 br label %loop19 20loop:21 %phi = phi ptr [ %src2, %entry ], [ %next, %loop ]22 %idx = phi i32 [ 0, %entry ], [ %idxn, %loop ]23 %next = getelementptr inbounds float, ptr %phi, i32 124 %g = getelementptr inbounds float, ptr %src1, i32 325 %l = load float, ptr %phi26 load float, ptr %next27 %a = fadd float %l, 1.028 store float %a, ptr %g29 %idxn = add nsw nuw i32 %idx, 130 %cmp5 = icmp eq i32 %idxn, %n31 br i1 %cmp5, label %end, label %loop32 33end:34 ret void35}36 37; CHECK-LABEL: Function: notmust: 6 pointers, 0 call sites38; CHECK: MustAlias: i8* %tab, [2 x i32]* %tab39; CHECK: PartialAlias (off -4): i32* %arrayidx, [2 x i32]* %tab40; CHECK: NoAlias: i32* %arrayidx, i8* %tab41; CHECK: MustAlias: i32* %tab, [2 x i32]* %tab42; CHECK: MustAlias: i32* %tab, i8* %tab43; CHECK: NoAlias: i32* %arrayidx, i32* %tab44; CHECK: MayAlias: i32* %incdec.ptr.i, [2 x i32]* %tab45; CHECK: NoAlias: i32* %incdec.ptr.i, i8* %tab46; CHECK: MayAlias: i32* %arrayidx, i32* %incdec.ptr.i47; CHECK: NoAlias: i32* %incdec.ptr.i, i32* %tab48; CHECK: MayAlias: i32* %p.addr.05.i, [2 x i32]* %tab49; CHECK: MayAlias: i32* %p.addr.05.i, i8* %tab50; CHECK: MayAlias: i32* %arrayidx, i32* %p.addr.05.i51; CHECK: MayAlias: i32* %p.addr.05.i, i32* %tab52; CHECK: NoAlias: i32* %incdec.ptr.i, i32* %p.addr.05.i53define i32 @notmust() nounwind {54entry:55 %tab = alloca [2 x i32], align 456 %ignore1 = load [2 x i32], ptr %tab57 %ignore2 = load i8, ptr %tab58 %arrayidx = getelementptr inbounds [2 x i32], ptr %tab, i32 0, i32 159 store i32 0, ptr %arrayidx, align 460 store i32 0, ptr %tab, align 461 %0 = add i32 1, 162 %cmp4.i = icmp slt i32 %0, 263 br i1 %cmp4.i, label %while.body.i, label %f.exit64 65while.body.i: ; preds = %while.body.i, %entry66 %1 = phi i32 [ 1, %while.body.i ], [ %0, %entry ]67 %foo.06.i = phi i32 [ %sub.i, %while.body.i ], [ 2, %entry ]68 %p.addr.05.i = phi ptr [ %incdec.ptr.i, %while.body.i ], [ %tab, %entry ]69 %sub.i = sub nsw i32 %foo.06.i, %170 %incdec.ptr.i = getelementptr inbounds i32, ptr %p.addr.05.i, i32 171 %ignore3 = load i32, ptr %incdec.ptr.i72 store i32 %sub.i, ptr %p.addr.05.i, align 473 %cmp.i = icmp sgt i32 %sub.i, 174 br i1 %cmp.i, label %while.body.i, label %f.exit75 76f.exit: ; preds = %entry, %while.body.i77 %2 = load i32, ptr %tab, align 478 %cmp = icmp eq i32 %2, 279 %3 = load i32, ptr %arrayidx, align 480 %cmp4 = icmp eq i32 %3, 181 %or.cond = and i1 %cmp, %cmp482 br i1 %or.cond, label %if.end, label %if.then83 84if.then: ; preds = %f.exit85 unreachable86 87if.end: ; preds = %f.exit88 ret i32 089}90 91; CHECK-LABEL: Function: reverse: 6 pointers, 0 call sites92; CHECK: MustAlias: i8* %tab, [10 x i32]* %tab93; CHECK: MustAlias: i32* %tab, [10 x i32]* %tab94; CHECK: MustAlias: i32* %tab, i8* %tab95; CHECK: PartialAlias (off -36): i32* %arrayidx1, [10 x i32]* %tab96; CHECK: NoAlias: i32* %arrayidx1, i8* %tab97; CHECK: NoAlias: i32* %arrayidx1, i32* %tab98; CHECK: MayAlias: i32* %incdec.ptr.i, [10 x i32]* %tab99; CHECK: MayAlias: i32* %incdec.ptr.i, i8* %tab100; CHECK: MayAlias: i32* %incdec.ptr.i, i32* %tab101; CHECK: MayAlias: i32* %arrayidx1, i32* %incdec.ptr.i102; CHECK: MayAlias: i32* %p.addr.05.i, [10 x i32]* %tab103; CHECK: MayAlias: i32* %p.addr.05.i, i8* %tab104; CHECK: MayAlias: i32* %p.addr.05.i, i32* %tab105; CHECK: MayAlias: i32* %arrayidx1, i32* %p.addr.05.i106; CHECK: NoAlias: i32* %incdec.ptr.i, i32* %p.addr.05.i107define i32 @reverse() nounwind {108entry:109 %tab = alloca [10 x i32], align 4110 %ignore1 = load [10 x i32], ptr %tab111 %ignore2 = load i8, ptr %tab112 store i32 0, ptr %tab, align 4113 %arrayidx1 = getelementptr inbounds [10 x i32], ptr %tab, i32 0, i32 9114 store i32 0, ptr %arrayidx1, align 4115 %0 = add i32 1, 1116 %cmp4.i = icmp slt i32 %0, 2117 br i1 %cmp4.i, label %while.body.i, label %f.exit118 119while.body.i: ; preds = %while.body.i, %entry120 %1 = phi i32 [ 1, %while.body.i ], [ %0, %entry ]121 %foo.06.i = phi i32 [ %sub.i, %while.body.i ], [ 2, %entry ]122 %p.addr.05.i = phi ptr [ %incdec.ptr.i, %while.body.i ], [ %arrayidx1, %entry ]123 %sub.i = sub nsw i32 %foo.06.i, %1124 %incdec.ptr.i = getelementptr inbounds i32, ptr %p.addr.05.i, i32 -1125 %ignore3 = load i32, ptr %incdec.ptr.i126 store i32 %sub.i, ptr %p.addr.05.i, align 4127 %cmp.i = icmp sgt i32 %sub.i, 1128 br i1 %cmp.i, label %while.body.i, label %f.exit129 130f.exit: ; preds = %entry, %while.body.i131 %2 = load i32, ptr %arrayidx1, align 4132 %cmp = icmp eq i32 %2, 2133 %3 = load i32, ptr %tab, align 4134 %cmp4 = icmp eq i32 %3, 1135 %or.cond = and i1 %cmp, %cmp4136 br i1 %or.cond, label %if.end, label %if.then137 138if.then: ; preds = %f.exit139 unreachable140 141if.end: ; preds = %f.exit142 ret i32 0143}144 145; CHECK-LABEL: Function: negative: 5 pointers, 1 call sites146; CHECK: PartialAlias (off -4): i16* %_tmp1, [3 x i16]* %int_arr.10147; CHECK: MayAlias: [3 x i16]* %int_arr.10, i16* %ls1.9.0148; CHECK: MayAlias: i16* %_tmp1, i16* %ls1.9.0149; CHECK: MayAlias: i16* %_tmp7, [3 x i16]* %int_arr.10150; CHECK: MayAlias: i16* %_tmp1, i16* %_tmp7151; CHECK: NoAlias: i16* %_tmp7, i16* %ls1.9.0152; CHECK: PartialAlias (off -2): i16* %_tmp11, [3 x i16]* %int_arr.10153; CHECK: NoAlias: i16* %_tmp1, i16* %_tmp11154; CHECK: MayAlias: i16* %_tmp11, i16* %ls1.9.0155; CHECK: MayAlias: i16* %_tmp11, i16* %_tmp7156; CHECK: NoModRef: Ptr: [3 x i16]* %int_arr.10 <-> %_tmp16 = call i16 @call(i32 %_tmp13)157; CHECK: NoModRef: Ptr: i16* %_tmp1 <-> %_tmp16 = call i16 @call(i32 %_tmp13)158; CHECK: Both ModRef: Ptr: i16* %ls1.9.0 <-> %_tmp16 = call i16 @call(i32 %_tmp13)159; CHECK: Both ModRef: Ptr: i16* %_tmp7 <-> %_tmp16 = call i16 @call(i32 %_tmp13)160; CHECK: NoModRef: Ptr: i16* %_tmp11 <-> %_tmp16 = call i16 @call(i32 %_tmp13)161define i16 @negative(i16 %argc.5.par) {162 %int_arr.10 = alloca [3 x i16], align 1163 load [3 x i16], ptr %int_arr.10164 %_tmp1 = getelementptr inbounds [3 x i16], ptr %int_arr.10, i16 0, i16 2165 load i16, ptr %_tmp1166 br label %bb1167 168bb1: ; preds = %bb1, %0169 %i.7.0 = phi i16 [ 2, %0 ], [ %_tmp5, %bb1 ]170 %ls1.9.0 = phi ptr [ %_tmp1, %0 ], [ %_tmp7, %bb1 ]171 store i16 %i.7.0, ptr %ls1.9.0, align 1172 %_tmp5 = add nsw i16 %i.7.0, -1173 %_tmp7 = getelementptr i16, ptr %ls1.9.0, i16 -1174 load i16, ptr %_tmp7175 %_tmp9 = icmp sgt i16 %i.7.0, 0176 br i1 %_tmp9, label %bb1, label %bb3177 178bb3: ; preds = %bb1179 %_tmp11 = getelementptr inbounds [3 x i16], ptr %int_arr.10, i16 0, i16 1180 %_tmp12 = load i16, ptr %_tmp11, align 1181 %_tmp13 = sext i16 %_tmp12 to i32182 %_tmp16 = call i16 @call(i32 %_tmp13)183 %_tmp18.not = icmp eq i16 %_tmp12, 1184 br i1 %_tmp18.not, label %bb5, label %bb4185 186bb4: ; preds = %bb3187 ret i16 1188 189bb5: ; preds = %bb3, %bb4190 ret i16 0191}192 193; CHECK-LABEL: Function: dynamic_offset194; CHECK: NoAlias: i8* %a, i8* %p.base195; CHECK: MayAlias: i8* %p, i8* %p.base196; CHECK: NoAlias: i8* %a, i8* %p197; CHECK: MayAlias: i8* %p.base, i8* %p.next198; CHECK: NoAlias: i8* %a, i8* %p.next199; CHECK: MayAlias: i8* %p, i8* %p.next200define void @dynamic_offset(i1 %c, ptr noalias %p.base) {201entry:202 %a = alloca i8203 load i8, ptr %p.base204 load i8, ptr %a205 br label %loop206 207loop:208 %p = phi ptr [ %p.base, %entry ], [ %p.next, %loop ]209 %offset = call i16 @call(i32 0)210 %p.next = getelementptr inbounds i8, ptr %p, i16 %offset211 load i8, ptr %p212 load i8, ptr %p.next213 br i1 %c, label %loop, label %exit214 215exit:216 ret void217}218 219; TODO: Currently yields an asymmetric result.220; CHECK-LABEL: Function: symmetry221; CHECK: MayAlias: i32* %p, i32* %p.base222; CHECK: MayAlias: i32* %p.base, i32* %p.next223; CHECK: NoAlias: i32* %p, i32* %p.next224; CHECK: MayAlias: i32* %p.base, i32* %result225; CHECK: NoAlias: i32* %p, i32* %result226; CHECK: MustAlias: i32* %p.next, i32* %result227define ptr @symmetry(ptr %p.base, i1 %c) {228entry:229 load i32, ptr %p.base230 br label %loop231 232loop:233 %p = phi ptr [ %p.base, %entry ], [ %p.next, %loop ]234 %p.next = getelementptr inbounds i32, ptr %p, i32 1235 load i32, ptr %p236 load i32, ptr %p.next237 br i1 %c, label %loop, label %exit238 239exit:240 %result = phi ptr [ %p.next, %loop ]241 load i32, ptr %result242 ret ptr %result243}244 245; FIXME: %a and %p.inner do not alias.246; CHECK-LABEL: Function: nested_loop247; CHECK: NoAlias: i8* %a, i8* %p.base248; CHECK: NoAlias: i8* %a, i8* %p.outer249; CHECK: MayAlias: i8* %a, i8* %p.inner250; CHECK: NoAlias: i8* %a, i8* %p.inner.next251; CHECK: NoAlias: i8* %a, i8* %p.outer.next252define void @nested_loop(i1 %c, i1 %c2, ptr noalias %p.base) {253entry:254 %a = alloca i8255 load i8, ptr %p.base256 load i8, ptr %a257 br label %outer_loop258 259outer_loop:260 %p.outer = phi ptr [ %p.base, %entry ], [ %p.outer.next, %outer_loop_latch ]261 load i8, ptr %p.outer262 br label %inner_loop263 264inner_loop:265 %p.inner = phi ptr [ %p.outer, %outer_loop ], [ %p.inner.next, %inner_loop ]266 %p.inner.next = getelementptr inbounds i8, ptr %p.inner, i64 1267 load i8, ptr %p.inner268 load i8, ptr %p.inner.next269 br i1 %c, label %inner_loop, label %outer_loop_latch270 271outer_loop_latch:272 %p.outer.next = getelementptr inbounds i8, ptr %p.inner, i64 10273 load i8, ptr %p.outer.next274 br i1 %c2, label %outer_loop, label %exit275 276exit:277 ret void278}279 280; Same as the previous test case, but avoiding phi of phi.281; CHECK-LABEL: Function: nested_loop2282; CHECK: NoAlias: i8* %a, i8* %p.base283; CHECK: NoAlias: i8* %a, i8* %p.outer284; CHECK: NoAlias: i8* %a, i8* %p.outer.next285; CHECK: MayAlias: i8* %a, i8* %p.inner286; CHECK: NoAlias: i8* %a, i8* %p.inner.next287; TODO: (a, p.inner) could be NoAlias288define void @nested_loop2(i1 %c, i1 %c2, ptr noalias %p.base) {289entry:290 %a = alloca i8291 load i8, ptr %p.base292 load i8, ptr %a293 br label %outer_loop294 295outer_loop:296 %p.outer = phi ptr [ %p.base, %entry ], [ %p.outer.next, %outer_loop_latch ]297 %p.outer.next = getelementptr inbounds i8, ptr %p.outer, i64 10298 load i8, ptr %p.outer299 load i8, ptr %p.outer.next300 br label %inner_loop301 302inner_loop:303 %p.inner = phi ptr [ %p.outer.next, %outer_loop ], [ %p.inner.next, %inner_loop ]304 %p.inner.next = getelementptr inbounds i8, ptr %p.inner, i64 1305 load i8, ptr %p.inner306 load i8, ptr %p.inner.next307 br i1 %c, label %inner_loop, label %outer_loop_latch308 309outer_loop_latch:310 br i1 %c2, label %outer_loop, label %exit311 312exit:313 ret void314}315 316; CHECK-LABEL: Function: nested_loop3317; CHECK: NoAlias: i8* %a, i8* %p.base318; CHECK: NoAlias: i8* %a, i8* %p.outer319; CHECK: NoAlias: i8* %a, i8* %p.outer.next320; CHECK: NoAlias: i8* %a, i8* %p.inner321; CHECK: NoAlias: i8* %a, i8* %p.inner.next322define void @nested_loop3(i1 %c, i1 %c2, ptr noalias %p.base) {323entry:324 %a = alloca i8325 load i8, ptr %p.base326 load i8, ptr %a327 br label %outer_loop328 329outer_loop:330 %p.outer = phi ptr [ %p.base, %entry ], [ %p.outer.next, %outer_loop_latch ]331 %p.outer.next = getelementptr inbounds i8, ptr %p.outer, i64 10332 load i8, ptr %p.outer333 load i8, ptr %p.outer.next334 br label %inner_loop335 336inner_loop:337 %p.inner = phi ptr [ %p.outer, %outer_loop ], [ %p.inner.next, %inner_loop ]338 %p.inner.next = getelementptr inbounds i8, ptr %p.inner, i64 1339 load i8, ptr %p.inner340 load i8, ptr %p.inner.next341 br i1 %c, label %inner_loop, label %outer_loop_latch342 343outer_loop_latch:344 br i1 %c2, label %outer_loop, label %exit345 346exit:347 ret void348}349 350; CHECK-LABEL: Function: sibling_loop351; CHECK: NoAlias: i8* %a, i8* %p.base352; CHECK: NoAlias: i8* %a, i8* %p1353; CHECK: NoAlias: i8* %a, i8* %p1.next354; CHECK: MayAlias: i8* %a, i8* %p2355; CHECK: NoAlias: i8* %a, i8* %p2.next356; TODO: %p2 does not alias %a357define void @sibling_loop(i1 %c, i1 %c2, ptr noalias %p.base) {358entry:359 %a = alloca i8360 load i8, ptr %p.base361 load i8, ptr %a362 br label %loop1363 364loop1:365 %p1 = phi ptr [ %p.base, %entry ], [ %p1.next, %loop1 ]366 %p1.next = getelementptr inbounds i8, ptr %p1, i64 10367 load i8, ptr %p1368 load i8, ptr %p1.next369 br i1 %c, label %loop1, label %loop2370 371loop2:372 %p2 = phi ptr [ %p1.next, %loop1 ], [ %p2.next, %loop2 ]373 %p2.next = getelementptr inbounds i8, ptr %p2, i64 1374 load i8, ptr %p2375 load i8, ptr %p2.next376 br i1 %c2, label %loop2, label %exit377 378exit:379 ret void380}381 382; CHECK-LABEL: Function: sibling_loop2383; CHECK: NoAlias: i8* %a, i8* %p.base384; CHECK: NoAlias: i8* %a, i8* %p1385; CHECK: NoAlias: i8* %a, i8* %p1.next386; CHECK: NoAlias: i8* %a, i8* %p2387; CHECK: NoAlias: i8* %a, i8* %p2.next388define void @sibling_loop2(i1 %c, i1 %c2, ptr noalias %p.base) {389entry:390 %a = alloca i8391 load i8, ptr %p.base392 load i8, ptr %a393 br label %loop1394 395loop1:396 %p1 = phi ptr [ %p.base, %entry ], [ %p1.next, %loop1 ]397 %p1.next = getelementptr inbounds i8, ptr %p1, i64 10398 load i8, ptr %p1399 load i8, ptr %p1.next400 br i1 %c, label %loop1, label %loop2401 402loop2:403 %p2 = phi ptr [ %p1, %loop1 ], [ %p2.next, %loop2 ]404 %p2.next = getelementptr inbounds i8, ptr %p2, i64 1405 load i8, ptr %p2406 load i8, ptr %p2.next407 br i1 %c2, label %loop2, label %exit408 409exit:410 ret void411}412 413; CHECK: MustAlias: i8* %a, i8* %phi414define void @phi_contains_self() {415entry:416 %a = alloca i32417 load i8, ptr %a418 br label %loop419 420loop:421 %phi = phi ptr [ %phi, %loop ], [ %a, %entry ]422 load i8, ptr %phi423 br label %loop424}425 426declare i16 @call(i32)427