1; RUN: opt < %s -aa-pipeline=basic-aa -passes=aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s 2 3target datalayout = "e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128" 4target triple = "i386-unknown-linux-gnu" 5 6declare i32* @random.i32(i32* %ptr) 7declare i8* @random.i8(i32* %ptr) 8 9; CHECK-LABEL: Function: arr: 10; CHECK-DAG: MayAlias: i32* %alloca, i32* %p0 11; CHECK-DAG: NoAlias: i32* %alloca, i32* %p1 12define void @arr() { 13 %alloca = alloca i32, i32 4 14 %random = call i32* @random.i32(i32* %alloca) 15 %p0 = getelementptr inbounds i32, i32* %random, i32 0 16 %p1 = getelementptr inbounds i32, i32* %random, i32 1 17 load i32, i32* %alloca 18 load i32, i32* %p0 19 load i32, i32* %p1 20 ret void 21} 22 23; CHECK-LABEL: Function: arg: 24; CHECK-DAG: MayAlias: i32* %arg, i32* %p0 25; CHECK-DAG: MayAlias: i32* %arg, i32* %p1 26define void @arg(i32* %arg) { 27 %random = call i32* @random.i32(i32* %arg) 28 %p0 = getelementptr inbounds i32, i32* %random, i32 0 29 %p1 = getelementptr inbounds i32, i32* %random, i32 1 30 load i32, i32* %arg 31 load i32, i32* %p0 32 load i32, i32* %p1 33 ret void 34} 35 36@gv = global i32 1 37; CHECK-LABEL: Function: global: 38; CHECK-DAG: MayAlias: i32* %p0, i32* @gv 39; CHECK-DAG: NoAlias: i32* %p1, i32* @gv 40define void @global() { 41 %random = call i32* @random.i32(i32* @gv) 42 %p0 = getelementptr inbounds i32, i32* %random, i32 0 43 %p1 = getelementptr inbounds i32, i32* %random, i32 1 44 load i32, i32* @gv 45 load i32, i32* %p0 46 load i32, i32* %p1 47 ret void 48} 49 50; CHECK-LABEL: Function: struct: 51; CHECK-DAG: MayAlias: i32* %f0, i32* %p0 52; CHECK-DAG: MayAlias: i32* %f1, i32* %p0 53; CHECK-DAG: NoAlias: i32* %f0, i32* %p1 54; CHECK-DAG: MayAlias: i32* %f1, i32* %p1 55%struct = type { i32, i32, i32 } 56define void @struct() { 57 %alloca = alloca %struct 58 %alloca.i32 = bitcast %struct* %alloca to i32* 59 %random = call i32* @random.i32(i32* %alloca.i32) 60 %f0 = getelementptr inbounds %struct, %struct* %alloca, i32 0, i32 0 61 %f1 = getelementptr inbounds %struct, %struct* %alloca, i32 0, i32 1 62 %p0 = getelementptr inbounds i32, i32* %random, i32 0 63 %p1 = getelementptr inbounds i32, i32* %random, i32 1 64 load i32, i32* %f0 65 load i32, i32* %f1 66 load i32, i32* %p0 67 load i32, i32* %p1 68 ret void 69} 70 71; CHECK-LABEL: Function: complex1: 72; CHECK-DAG: MayAlias: i32* %a2.0, i32* %r2.0 73; CHECK-DAG: NoAlias: i32* %a2.0, i32* %r2.1 74; CHECK-DAG: MayAlias: i32* %a2.0, i32* %r2.i 75; CHECK-DAG: MayAlias: i32* %a2.0, i32* %r2.1i 76; CHECK-DAG: NoAlias: i32* %a1, i32* %r2.0 77; CHECK-DAG: NoAlias: i32* %a1, i32* %r2.1 78; CHECK-DAG: MayAlias: i32* %a1, i32* %r2.i 79; CHECK-DAG: MayAlias: i32* %a1, i32* %r2.1i 80%complex = type { i32, i32, [4 x i32] } 81define void @complex1(i32 %i) { 82 %alloca = alloca %complex 83 %alloca.i32 = bitcast %complex* %alloca to i32* 84 %r.i32 = call i32* @random.i32(i32* %alloca.i32) 85 %random = bitcast i32* %r.i32 to %complex* 86 %a1 = getelementptr inbounds %complex, %complex* %alloca, i32 0, i32 1 87 %a2.0 = getelementptr inbounds %complex, %complex* %alloca, i32 0, i32 2, i32 0 88 %r2.0 = getelementptr inbounds %complex, %complex* %random, i32 0, i32 2, i32 0 89 %r2.1 = getelementptr inbounds %complex, %complex* %random, i32 0, i32 2, i32 1 90 %r2.i = getelementptr inbounds %complex, %complex* %random, i32 0, i32 2, i32 %i 91 %r2.1i = getelementptr inbounds i32, i32* %r2.1, i32 %i 92 load i32, i32* %a2.0 93 load i32, i32* %a1 94 load i32, i32* %r2.0 95 load i32, i32* %r2.1 96 load i32, i32* %r2.i 97 load i32, i32* %r2.1i 98 ret void 99} 100 101; CHECK-LABEL: Function: complex2: 102; CHECK-DAG: NoAlias: i32* %alloca, i32* %p120 103; CHECK-DAG: MayAlias: i32* %alloca, i32* %pi20 104; CHECK-DAG: MayAlias: i32* %alloca, i32* %pij1 105; CHECK-DAG: MayAlias: i32* %a3, i32* %pij1 106%inner = type { i32, i32 } 107%outer = type { i32, i32, [10 x %inner] } 108declare %outer* @rand_outer(i32* %p) 109define void @complex2(i32 %i, i32 %j) { 110 %alloca = alloca i32, i32 128 111 %a3 = getelementptr inbounds i32, i32* %alloca, i32 3 112 %random = call %outer* @rand_outer(i32* %alloca) 113 %p120 = getelementptr inbounds %outer, %outer* %random, i32 1, i32 2, i32 2, i32 0 114 %pi20 = getelementptr inbounds %outer, %outer* %random, i32 %i, i32 2, i32 2, i32 0 115 %pij1 = getelementptr inbounds %outer, %outer* %random, i32 %i, i32 2, i32 %j, i32 1 116 load i32, i32* %alloca 117 load i32, i32* %a3 118 load i32, i32* %p120 119 load i32, i32* %pi20 120 load i32, i32* %pij1 121 ret void 122} 123 124; CHECK-LABEL: Function: pointer_offset: 125; CHECK-DAG: MayAlias: i32** %add.ptr, i32** %p1 126; CHECK-DAG: MayAlias: i32** %add.ptr, i32** %q2 127%struct.X = type { i32*, i32* } 128define i32 @pointer_offset(i32 signext %i, i32 signext %j, i32 zeroext %off) { 129entry: 130 %i.addr = alloca i32 131 %j.addr = alloca i32 132 %x = alloca %struct.X 133 store i32 %i, i32* %i.addr 134 store i32 %j, i32* %j.addr 135 %0 = bitcast %struct.X* %x to i8* 136 %p1 = getelementptr inbounds %struct.X, %struct.X* %x, i32 0, i32 0 137 store i32* %i.addr, i32** %p1 138 %q2 = getelementptr inbounds %struct.X, %struct.X* %x, i32 0, i32 1 139 store i32* %j.addr, i32** %q2 140 %add.ptr = getelementptr inbounds i32*, i32** %q2, i32 %off 141 %1 = load i32*, i32** %add.ptr 142 %2 = load i32, i32* %1 143 ret i32 %2 144} 145 146; CHECK-LABEL: Function: one_size_unknown: 147; CHECK: NoModRef: Ptr: i8* %p.minus1 <-> call void @llvm.memset.p0i8.i32(i8* %p, i8 0, i32 %size, i1 false) 148define void @one_size_unknown(i8* %p, i32 %size) { 149 %p.minus1 = getelementptr inbounds i8, i8* %p, i32 -1 150 call void @llvm.memset.p0i8.i32(i8* %p, i8 0, i32 %size, i1 false) 151 load i8, i8* %p.minus1 152 ret void 153} 154 155 156; If part of the addressing is done with non-inbounds GEPs, we can't use 157; properties implied by the last gep w/the whole offset. In this case, 158; %random = %alloc - 4 bytes is well defined, and results in %step == %alloca, 159; leaving %p as an entirely inbounds gep pointing inside %alloca 160; CHECK-LABEL: Function: all_inbounds: 161; CHECK: MayAlias: i32* %alloca, i8* %p0 162; CHECK: MayAlias: i32* %alloca, i8* %p1 163define void @all_inbounds() { 164 %alloca = alloca i32, i32 4 165 %random = call i8* @random.i8(i32* %alloca) 166 %p0 = getelementptr inbounds i8, i8* %random, i8 0 167 %step = getelementptr i8, i8* %random, i8 4 168 %p1 = getelementptr inbounds i8, i8* %step, i8 2 169 load i32, i32* %alloca 170 load i8, i8* %p0 171 load i8, i8* %p1 172 ret void 173} 174 175 176; For all values of %x, %p0 and %p1 can't alias because %random would 177; have to be out of bounds (and thus a contradiction) for them to be equal. 178; CHECK-LABEL: Function: common_factor: 179; CHECK: NoAlias: i32* %p0, i32* %p1 180define void @common_factor(i32 %x) { 181 %alloca = alloca i32, i32 4 182 %random = call i8* @random.i8(i32* %alloca) 183 %p0 = getelementptr inbounds i32, i32* %alloca, i32 %x 184 %step = getelementptr inbounds i8, i8* %random, i8 4 185 %step.bitcast = bitcast i8* %step to i32* 186 %p1 = getelementptr inbounds i32, i32* %step.bitcast, i32 %x 187 load i32, i32* %p0 188 load i32, i32* %p1 189 ret void 190} 191 192 193declare void @llvm.memset.p0i8.i32(i8*, i8, i32, i1) 194