1; RUN: opt < %s -aa-pipeline=basic-aa -passes='require<phi-values>,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 i32* [ @X, %bb ], [ @Y, %bb1 ] 28 %tmp1 = load i32, i32* @Z, align 4 29 store i32 123, i32* %P, align 4 30 %tmp2 = load i32, i32* @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(i32* %jj7, i32* %j) { 45entry: 46 %oa5 = alloca [100 x i32], align 16 47 br label %codeRepl 48 49codeRepl: 50 %0 = phi i32* [ %arrayidx13, %for.body ], [ %j, %entry ] 51 %targetBlock = call i1 @cond(i32* %jj7) 52 br i1 %targetBlock, label %for.body, label %bye 53 54for.body: 55 %1 = load i32, i32* %jj7, align 4 56 %idxprom4 = zext i32 %1 to i64 57 %arrayidx5 = getelementptr inbounds [100 x i32], [100 x i32]* %oa5, i64 0, i64 %idxprom4 58 %2 = load i32, i32* %arrayidx5, align 4 59 %sub6 = sub i32 %2, 6 60 store i32 %sub6, i32* %arrayidx5, align 4 61 ; %0 and %arrayidx5 can alias! It is not safe to DSE the above store. 62 %3 = load i32, i32* %0, align 4 63 store i32 %3, i32* %arrayidx5, align 4 64 %sub11 = add i32 %1, -1 65 %idxprom12 = zext i32 %sub11 to i64 66 %arrayidx13 = getelementptr inbounds [100 x i32], [100 x i32]* %oa5, i64 0, i64 %idxprom12 67 load i32, i32* %arrayidx13 68 call void @inc(i32* %jj7) 69 br label %codeRepl 70 71bye: 72 %.reload = load i32, i32* %jj7, align 4 73 ret i32 %.reload 74} 75 76declare i1 @cond(i32*) 77 78declare void @inc(i32*) 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; CHECK-LABEL: loop_phi_chain 84; CHECK: NoAlias: i32* %val1, i32* @Y 85; CHECK: NoAlias: i32* %val2, i32* @Y 86; CHECK: NoAlias: i32* %val3, i32* @Y 87define void @loop_phi_chain(i32 %a, i32 %b, i32 %c) { 88entry: 89 br label %loop1 90 91loop1: 92 %n1 = phi i32 [ 0, %entry ], [ %add1, %loop2 ] 93 %val1 = phi i32* [ @X, %entry ], [ %val2, %loop2 ] 94 load i32, i32* %val1 95 %add1 = add i32 %n1, 1 96 %cmp1 = icmp ne i32 %n1, 32 97 br i1 %cmp1, label %loop2, label %end 98 99loop2: 100 %n2 = phi i32 [ 0, %loop1 ], [ %add2, %loop3 ] 101 %val2 = phi i32* [ %val1, %loop1 ], [ %val3, %loop3 ] 102 load i32, i32* %val2 103 %add2 = add i32 %n2, 1 104 %cmp2 = icmp ne i32 %n2, 32 105 br i1 %cmp2, label %loop3, label %loop1 106 107loop3: 108 %n3 = phi i32 [ 0, %loop2 ], [ %add3, %loop3 ] 109 %val3 = phi i32* [ %val2, %loop2 ], [ %val3, %loop3 ] 110 store i32 0, i32* %val3, align 4 111 store i32 0, i32* @Y, align 4 112 %add3 = add i32 %n3, 1 113 %cmp3 = icmp ne i32 %n3, 32 114 br i1 %cmp3, label %loop3, label %loop2 115 116end: 117 ret void 118} 119 120; CHECK-LABEL: phi_and_select 121; CHECK: MustAlias: i32* %p, i32* %s 122define void @phi_and_select(i1 %c, i1 %c2, i32* %x, i32* %y) { 123entry: 124 br i1 %c, label %true, label %false 125 126true: 127 br label %exit 128 129false: 130 br label %exit 131 132exit: 133 %p = phi i32* [ %x, %true ], [ %y, %false ] 134 %s = select i1 %c2, i32* %p, i32* %p 135 store i32 0, i32* %p 136 store i32 0, i32* %s 137 ret void 138} 139 140; CHECK-LABEL: phi_and_phi_cycle 141; CHECK: NoAlias: i32* %p1, i32* %p2 142define void @phi_and_phi_cycle(i32* noalias %x, i32* noalias %y) { 143entry: 144 br label %loop 145 146loop: 147 %p1 = phi i32* [ %x, %entry ], [ %p1.next, %loop ] 148 %p2 = phi i32* [ %y, %entry ], [ %p2.next, %loop ] 149 %p1.next = getelementptr i32, i32* %p1, i64 1 150 %p2.next = getelementptr i32, i32* %p1, i64 2 151 store i32 0, i32* %p1 152 store i32 0, i32* %p2 153 br label %loop 154} 155 156; CHECK-LABEL: phi_and_gep_unknown_size 157; CHECK: Just Mod: call void @llvm.memset.p0i8.i32(i8* %g, i8 0, i32 %size, i1 false) <-> call void @llvm.memset.p0i8.i32(i8* %z, i8 0, i32 %size, i1 false) 158; TODO: This should be NoModRef. 159define void @phi_and_gep_unknown_size(i1 %c, i8* %x, i8* %y, i8* noalias %z, i32 %size) { 160entry: 161 br i1 %c, label %true, label %false 162 163true: 164 br label %exit 165 166false: 167 br label %exit 168 169exit: 170 %p = phi i8* [ %x, %true ], [ %y, %false ] 171 %g = getelementptr inbounds i8, i8* %p, i64 1 172 call void @llvm.memset.p0i8.i32(i8* %g, i8 0, i32 %size, i1 false) 173 call void @llvm.memset.p0i8.i32(i8* %z, i8 0, i32 %size, i1 false) 174 ret void 175} 176 177declare void @llvm.memset.p0i8.i32(i8*, i8, i32, i1) 178 179; CHECK-LABEL: unsound_inequality 180; CHECK: MayAlias: i32* %arrayidx5, i32* %phi 181; CHECK: MayAlias: i32* %arrayidx13, i32* %phi 182; CHECK: NoAlias: i32* %arrayidx13, i32* %arrayidx5 183 184; When recursively reasoning about phis, we can't use predicates between 185; two values as we might be comparing the two from different iterations. 186define i32 @unsound_inequality(i32* %jj7, i32* %j) { 187entry: 188 %oa5 = alloca [100 x i32], align 16 189 br label %for.body 190 191for.body: ; preds = %for.body, %entry 192 %phi = phi i32* [ %arrayidx13, %for.body ], [ %j, %entry ] 193 load i32, i32* %phi 194 %idx = load i32, i32* %jj7, align 4 195 %arrayidx5 = getelementptr inbounds [100 x i32], [100 x i32]* %oa5, i64 0, i32 %idx 196 store i32 0, i32* %arrayidx5, align 4 197 store i32 0, i32* %phi, align 4 198 %notequal = add i32 %idx, 1 199 %arrayidx13 = getelementptr inbounds [100 x i32], [100 x i32]* %oa5, i64 0, i32 %notequal 200 store i32 0, i32* %arrayidx13, align 4 201 br label %for.body 202} 203 204; CHECK-LABEL: single_arg_phi 205; CHECK: NoAlias: i32* %ptr, i32* %ptr.next 206; CHECK: MustAlias: i32* %ptr, i32* %ptr.phi 207; CHECK: MustAlias: i32* %ptr.next, i32* %ptr.next.phi 208define void @single_arg_phi(i32* %ptr.base) { 209entry: 210 br label %loop 211 212loop: 213 %ptr = phi i32* [ %ptr.base, %entry ], [ %ptr.next, %split ] 214 %ptr.next = getelementptr inbounds i32, i32* %ptr, i64 1 215 load i32, i32* %ptr 216 load i32, i32* %ptr.next 217 br label %split 218 219split: 220 %ptr.phi = phi i32* [ %ptr, %loop ] 221 %ptr.next.phi = phi i32* [ %ptr.next, %loop ] 222 load i32, i32* %ptr.phi 223 load i32, i32* %ptr.next.phi 224 br label %loop 225} 226