1; RUN: opt < %s -aa-pipeline=basic-aa -passes=aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s 2target 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://7282591 6 7@X = common global i32 0 8@Y = common global i32 0 9@Z = common global i32 0 10 11; CHECK-LABEL: foo 12; CHECK: NoAlias: i32* %P, i32* @Z 13 14define void @foo(i32 %cond) nounwind { 15entry: 16 %"alloca point" = bitcast i32 0 to i32 17 %tmp = icmp ne i32 %cond, 0 18 br i1 %tmp, label %bb, label %bb1 19 20bb: 21 br label %bb2 22 23bb1: 24 br label %bb2 25 26bb2: 27 %P = phi ptr [ @X, %bb ], [ @Y, %bb1 ] 28 %tmp1 = load i32, ptr @Z, align 4 29 store i32 123, ptr %P, align 4 30 %tmp2 = load i32, ptr @Z, align 4 31 br label %return 32 33return: 34 ret void 35} 36 37; Pointers can vary in between iterations of loops. 38; PR18068 39 40; CHECK-LABEL: pr18068 41; CHECK: MayAlias: i32* %0, i32* %arrayidx5 42; CHECK: NoAlias: i32* %arrayidx13, i32* %arrayidx5 43 44define i32 @pr18068(ptr %jj7, ptr %j) { 45entry: 46 %oa5 = alloca [100 x i32], align 16 47 br label %codeRepl 48 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 %bye 53 54for.body: 55 %1 = load i32, ptr %jj7, align 4 56 %idxprom4 = zext i32 %1 to i64 57 %arrayidx5 = getelementptr inbounds [100 x i32], ptr %oa5, i64 0, i64 %idxprom4 58 %2 = load i32, ptr %arrayidx5, align 4 59 %sub6 = sub i32 %2, 6 60 store i32 %sub6, ptr %arrayidx5, align 4 61 ; %0 and %arrayidx5 can alias! It is not safe to DSE the above store. 62 %3 = load i32, ptr %0, align 4 63 store i32 %3, ptr %arrayidx5, align 4 64 %sub11 = add i32 %1, -1 65 %idxprom12 = zext i32 %sub11 to i64 66 %arrayidx13 = getelementptr inbounds [100 x i32], ptr %oa5, i64 0, i64 %idxprom12 67 load i32, ptr %arrayidx13 68 call void @inc(ptr %jj7) 69 br label %codeRepl 70 71bye: 72 %.reload = load i32, ptr %jj7, align 4 73 ret i32 %.reload 74} 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's 82; actually only one underlying value. 83; FIXME: All of these could be NoAlias. 84; CHECK-LABEL: loop_phi_chain 85; CHECK: MayAlias: i32* %val1, i32* @Y 86; CHECK: MayAlias: i32* %val2, i32* @Y 87; CHECK: MayAlias: i32* %val3, i32* @Y 88define void @loop_phi_chain(i32 %a, i32 %b, i32 %c) { 89entry: 90 br label %loop1 91 92loop1: 93 %n1 = phi i32 [ 0, %entry ], [ %add1, %loop2 ] 94 %val1 = phi ptr [ @X, %entry ], [ %val2, %loop2 ] 95 load i32, ptr %val1 96 %add1 = add i32 %n1, 1 97 %cmp1 = icmp ne i32 %n1, 32 98 br i1 %cmp1, label %loop2, label %end 99 100loop2: 101 %n2 = phi i32 [ 0, %loop1 ], [ %add2, %loop3 ] 102 %val2 = phi ptr [ %val1, %loop1 ], [ %val3, %loop3 ] 103 load i32, ptr %val2 104 %add2 = add i32 %n2, 1 105 %cmp2 = icmp ne i32 %n2, 32 106 br i1 %cmp2, label %loop3, label %loop1 107 108loop3: 109 %n3 = phi i32 [ 0, %loop2 ], [ %add3, %loop3 ] 110 %val3 = phi ptr [ %val2, %loop2 ], [ %val3, %loop3 ] 111 store i32 0, ptr %val3, align 4 112 store i32 0, ptr @Y, align 4 113 %add3 = add i32 %n3, 1 114 %cmp3 = icmp ne i32 %n3, 32 115 br i1 %cmp3, label %loop3, label %loop2 116 117end: 118 ret void 119} 120 121; CHECK-LABEL: phi_and_select 122; CHECK: MustAlias: i32* %p, i32* %s 123define void @phi_and_select(i1 %c, i1 %c2, ptr %x, ptr %y) { 124entry: 125 br i1 %c, label %true, label %false 126 127true: 128 br label %exit 129 130false: 131 br label %exit 132 133exit: 134 %p = phi ptr [ %x, %true ], [ %y, %false ] 135 %s = select i1 %c2, ptr %p, ptr %p 136 store i32 0, ptr %p 137 store i32 0, ptr %s 138 ret void 139} 140 141; CHECK-LABEL: phi_and_phi_cycle 142; CHECK: NoAlias: i32* %p1, i32* %p2 143define void @phi_and_phi_cycle(ptr noalias %x, ptr noalias %y) { 144entry: 145 br label %loop 146 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 1 151 %p2.next = getelementptr i32, ptr %p1, i64 2 152 store i32 0, ptr %p1 153 store i32 0, ptr %p2 154 br label %loop 155} 156 157; CHECK-LABEL: phi_and_gep_unknown_size 158; 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 %false 163 164true: 165 br label %exit 166 167false: 168 br label %exit 169 170exit: 171 %p = phi ptr [ %x, %true ], [ %y, %false ] 172 %g = getelementptr inbounds i8, ptr %p, i64 1 173 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 void 176} 177 178declare void @llvm.memset.p0.i32(ptr, i8, i32, i1) 179 180; CHECK-LABEL: unsound_inequality 181; CHECK: MayAlias: i32* %arrayidx5, i32* %phi 182; CHECK: MayAlias: i32* %arrayidx13, i32* %phi 183; CHECK: NoAlias: i32* %arrayidx13, i32* %arrayidx5 184 185; When recursively reasoning about phis, we can't use predicates between 186; 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 16 190 br label %for.body 191 192for.body: ; preds = %for.body, %entry 193 %phi = phi ptr [ %arrayidx13, %for.body ], [ %j, %entry ] 194 load i32, ptr %phi 195 %idx = load i32, ptr %jj7, align 4 196 %arrayidx5 = getelementptr inbounds [100 x i32], ptr %oa5, i64 0, i32 %idx 197 store i32 0, ptr %arrayidx5, align 4 198 store i32 0, ptr %phi, align 4 199 %notequal = add i32 %idx, 1 200 %arrayidx13 = getelementptr inbounds [100 x i32], ptr %oa5, i64 0, i32 %notequal 201 store i32 0, ptr %arrayidx13, align 4 202 br label %for.body 203} 204 205; CHECK-LABEL: single_arg_phi 206; CHECK: NoAlias: i32* %ptr, i32* %ptr.next 207; CHECK: MustAlias: i32* %ptr, i32* %ptr.phi 208; CHECK: MustAlias: i32* %ptr.next, i32* %ptr.next.phi 209define void @single_arg_phi(ptr %ptr.base) { 210entry: 211 br label %loop 212 213loop: 214 %ptr = phi ptr [ %ptr.base, %entry ], [ %ptr.next, %split ] 215 %ptr.next = getelementptr inbounds i32, ptr %ptr, i64 1 216 load i32, ptr %ptr 217 load i32, ptr %ptr.next 218 br label %split 219 220split: 221 %ptr.phi = phi ptr [ %ptr, %loop ] 222 %ptr.next.phi = phi ptr [ %ptr.next, %loop ] 223 load i32, ptr %ptr.phi 224 load i32, ptr %ptr.next.phi 225 br label %loop 226} 227 228; CHECK-LABEL: phi_of_geps_based_on_alloca 229; CHECK: NoAlias: i32* %gep3, i32* %phi 230define void @phi_of_geps_based_on_alloca(i1 %c) { 231 %a = alloca [3 x i32] 232 br i1 %c, label %if, label %else 233 234if: 235 %gep1 = getelementptr i32, ptr %a, i64 1 236 br label %join 237 238else: 239 %gep2 = getelementptr i32, ptr %a, i64 2 240 br label %join 241 242join: 243 %phi = phi ptr [ %gep1, %if ], [ %gep2, %else ] 244 %gep3 = getelementptr i32, ptr %a, i64 3 245 load i32, ptr %phi 246 load i32, ptr %gep3 247 ret void 248} 249 250; Don't crash with an unreachable predecessor. 251; CHECK-LABEL: pr59360 252; CHECK: MayAlias: i32* %loaded.ptr, i32* %phi 253define void @pr59360() { 254entry: 255 br label %outer 256 257loopexit: ; No predecessors! 258 br label %outer 259 260outer: ; preds = %loopexit, %entry 261 %phi = phi ptr [ %loaded.ptr, %loopexit ], [ null, %entry ] 262 store i32 0, ptr %phi, align 4 263 %loaded.ptr = load ptr, ptr null, align 8 264 %0 = load i32, ptr %loaded.ptr, align 4 265 ret void 266} 267