267 lines · plain
1; RUN: opt < %s -aa-pipeline=basic-aa -passes=aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s2target 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-S128"3target triple = "x86_64-unknown-linux-gnu"4 5; rdar://72825916 7@X = common global i32 08@Y = common global i32 09@Z = common global i32 010 11; CHECK-LABEL: foo12; CHECK: NoAlias: i32* %P, i32* @Z13 14define void @foo(i32 %cond) nounwind {15entry:16 %"alloca point" = bitcast i32 0 to i3217 %tmp = icmp ne i32 %cond, 018 br i1 %tmp, label %bb, label %bb119 20bb:21 br label %bb222 23bb1:24 br label %bb225 26bb2:27 %P = phi ptr [ @X, %bb ], [ @Y, %bb1 ]28 %tmp1 = load i32, ptr @Z, align 429 store i32 123, ptr %P, align 430 %tmp2 = load i32, ptr @Z, align 431 br label %return32 33return:34 ret void35}36 37; Pointers can vary in between iterations of loops.38; PR1806839 40; CHECK-LABEL: pr1806841; CHECK: MayAlias: i32* %0, i32* %arrayidx542; CHECK: NoAlias: i32* %arrayidx13, i32* %arrayidx543 44define i32 @pr18068(ptr %jj7, ptr %j) {45entry:46 %oa5 = alloca [100 x i32], align 1647 br label %codeRepl48 49codeRepl:50 %0 = phi ptr [ %arrayidx13, %for.body ], [ %j, %entry ]51 %targetBlock = call i1 @cond(ptr %jj7)52 br i1 %targetBlock, label %for.body, label %bye53 54for.body:55 %1 = load i32, ptr %jj7, align 456 %idxprom4 = zext i32 %1 to i6457 %arrayidx5 = getelementptr inbounds [100 x i32], ptr %oa5, i64 0, i64 %idxprom458 %2 = load i32, ptr %arrayidx5, align 459 %sub6 = sub i32 %2, 660 store i32 %sub6, ptr %arrayidx5, align 461 ; %0 and %arrayidx5 can alias! It is not safe to DSE the above store.62 %3 = load i32, ptr %0, align 463 store i32 %3, ptr %arrayidx5, align 464 %sub11 = add i32 %1, -165 %idxprom12 = zext i32 %sub11 to i6466 %arrayidx13 = getelementptr inbounds [100 x i32], ptr %oa5, i64 0, i64 %idxprom1267 load i32, ptr %arrayidx1368 call void @inc(ptr %jj7)69 br label %codeRepl70 71bye:72 %.reload = load i32, ptr %jj7, align 473 ret i32 %.reload74}75 76declare i1 @cond(ptr)77 78declare void @inc(ptr)79 80 81; When we have a chain of phis in nested loops we should recognise if there's82; actually only one underlying value.83; FIXME: All of these could be NoAlias.84; CHECK-LABEL: loop_phi_chain85; CHECK: MayAlias: i32* %val1, i32* @Y86; CHECK: MayAlias: i32* %val2, i32* @Y87; CHECK: MayAlias: i32* %val3, i32* @Y88define void @loop_phi_chain(i32 %a, i32 %b, i32 %c) {89entry:90 br label %loop191 92loop1:93 %n1 = phi i32 [ 0, %entry ], [ %add1, %loop2 ]94 %val1 = phi ptr [ @X, %entry ], [ %val2, %loop2 ]95 load i32, ptr %val196 %add1 = add i32 %n1, 197 %cmp1 = icmp ne i32 %n1, 3298 br i1 %cmp1, label %loop2, label %end99 100loop2:101 %n2 = phi i32 [ 0, %loop1 ], [ %add2, %loop3 ]102 %val2 = phi ptr [ %val1, %loop1 ], [ %val3, %loop3 ]103 load i32, ptr %val2104 %add2 = add i32 %n2, 1105 %cmp2 = icmp ne i32 %n2, 32106 br i1 %cmp2, label %loop3, label %loop1107 108loop3:109 %n3 = phi i32 [ 0, %loop2 ], [ %add3, %loop3 ]110 %val3 = phi ptr [ %val2, %loop2 ], [ %val3, %loop3 ]111 store i32 0, ptr %val3, align 4112 store i32 0, ptr @Y, align 4113 %add3 = add i32 %n3, 1114 %cmp3 = icmp ne i32 %n3, 32115 br i1 %cmp3, label %loop3, label %loop2116 117end:118 ret void119}120 121; CHECK-LABEL: phi_and_select122; CHECK: MustAlias: i32* %p, i32* %s123define void @phi_and_select(i1 %c, i1 %c2, ptr %x, ptr %y) {124entry:125 br i1 %c, label %true, label %false126 127true:128 br label %exit129 130false:131 br label %exit132 133exit:134 %p = phi ptr [ %x, %true ], [ %y, %false ]135 %s = select i1 %c2, ptr %p, ptr %p136 store i32 0, ptr %p137 store i32 0, ptr %s138 ret void139}140 141; CHECK-LABEL: phi_and_phi_cycle142; CHECK: NoAlias: i32* %p1, i32* %p2143define void @phi_and_phi_cycle(ptr noalias %x, ptr noalias %y) {144entry:145 br label %loop146 147loop:148 %p1 = phi ptr [ %x, %entry ], [ %p1.next, %loop ]149 %p2 = phi ptr [ %y, %entry ], [ %p2.next, %loop ]150 %p1.next = getelementptr i32, ptr %p1, i64 1151 %p2.next = getelementptr i32, ptr %p1, i64 2152 store i32 0, ptr %p1153 store i32 0, ptr %p2154 br label %loop155}156 157; CHECK-LABEL: phi_and_gep_unknown_size158; CHECK: Just Mod: call void @llvm.memset.p0.i32(ptr %g, i8 0, i32 %size, i1 false) <-> call void @llvm.memset.p0.i32(ptr %z, i8 0, i32 %size, i1 false)159; TODO: This should be NoModRef.160define void @phi_and_gep_unknown_size(i1 %c, ptr %x, ptr %y, ptr noalias %z, i32 %size) {161entry:162 br i1 %c, label %true, label %false163 164true:165 br label %exit166 167false:168 br label %exit169 170exit:171 %p = phi ptr [ %x, %true ], [ %y, %false ]172 %g = getelementptr inbounds i8, ptr %p, i64 1173 call void @llvm.memset.p0.i32(ptr %g, i8 0, i32 %size, i1 false)174 call void @llvm.memset.p0.i32(ptr %z, i8 0, i32 %size, i1 false)175 ret void176}177 178declare void @llvm.memset.p0.i32(ptr, i8, i32, i1)179 180; CHECK-LABEL: unsound_inequality181; CHECK: MayAlias: i32* %arrayidx5, i32* %phi182; CHECK: MayAlias: i32* %arrayidx13, i32* %phi183; CHECK: NoAlias: i32* %arrayidx13, i32* %arrayidx5184 185; When recursively reasoning about phis, we can't use predicates between186; two values as we might be comparing the two from different iterations.187define i32 @unsound_inequality(ptr %jj7, ptr %j) {188entry:189 %oa5 = alloca [100 x i32], align 16190 br label %for.body191 192for.body: ; preds = %for.body, %entry193 %phi = phi ptr [ %arrayidx13, %for.body ], [ %j, %entry ]194 load i32, ptr %phi195 %idx = load i32, ptr %jj7, align 4196 %arrayidx5 = getelementptr inbounds [100 x i32], ptr %oa5, i64 0, i32 %idx197 store i32 0, ptr %arrayidx5, align 4198 store i32 0, ptr %phi, align 4199 %notequal = add i32 %idx, 1200 %arrayidx13 = getelementptr inbounds [100 x i32], ptr %oa5, i64 0, i32 %notequal201 store i32 0, ptr %arrayidx13, align 4202 br label %for.body203} 204 205; CHECK-LABEL: single_arg_phi206; CHECK: NoAlias: i32* %ptr, i32* %ptr.next207; CHECK: MustAlias: i32* %ptr, i32* %ptr.phi208; CHECK: MustAlias: i32* %ptr.next, i32* %ptr.next.phi209define void @single_arg_phi(ptr %ptr.base) {210entry:211 br label %loop212 213loop:214 %ptr = phi ptr [ %ptr.base, %entry ], [ %ptr.next, %split ]215 %ptr.next = getelementptr inbounds i32, ptr %ptr, i64 1216 load i32, ptr %ptr217 load i32, ptr %ptr.next218 br label %split219 220split:221 %ptr.phi = phi ptr [ %ptr, %loop ]222 %ptr.next.phi = phi ptr [ %ptr.next, %loop ]223 load i32, ptr %ptr.phi224 load i32, ptr %ptr.next.phi225 br label %loop226}227 228; CHECK-LABEL: phi_of_geps_based_on_alloca229; CHECK: NoAlias: i32* %gep3, i32* %phi230define void @phi_of_geps_based_on_alloca(i1 %c) {231 %a = alloca [3 x i32]232 br i1 %c, label %if, label %else233 234if:235 %gep1 = getelementptr i32, ptr %a, i64 1236 br label %join237 238else:239 %gep2 = getelementptr i32, ptr %a, i64 2240 br label %join241 242join:243 %phi = phi ptr [ %gep1, %if ], [ %gep2, %else ]244 %gep3 = getelementptr i32, ptr %a, i64 3245 load i32, ptr %phi246 load i32, ptr %gep3247 ret void248}249 250; Don't crash with an unreachable predecessor.251; CHECK-LABEL: pr59360252; CHECK: MayAlias: i32* %loaded.ptr, i32* %phi253define void @pr59360() {254entry:255 br label %outer256 257loopexit: ; No predecessors!258 br label %outer259 260outer: ; preds = %loopexit, %entry261 %phi = phi ptr [ %loaded.ptr, %loopexit ], [ null, %entry ]262 store i32 0, ptr %phi, align 4263 %loaded.ptr = load ptr, ptr null, align 8264 %0 = load i32, ptr %loaded.ptr, align 4265 ret void266}267