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-i64:64-f80:128-n8:16:32:64-S128" 4 5%struct = type { i32, i32, i32 } 6 7; CHECK-LABEL: test_simple 8 9; CHECK-DAG: MayAlias: %struct* %st, i32* %x 10; CHECK-DAG: MayAlias: %struct* %st, i32* %y 11; CHECK-DAG: MayAlias: %struct* %st, i32* %z 12 13; CHECK-DAG: NoAlias: i32* %x, i32* %y 14; CHECK-DAG: NoAlias: i32* %x, i32* %z 15; CHECK-DAG: NoAlias: i32* %y, i32* %z 16 17; CHECK-DAG: MayAlias: %struct* %st, %struct* %y 18; CHECK-DAG: MayAlias: i32* %x, %struct* %y 19; CHECK-DAG: MayAlias: i32* %x, i80* %y 20 21; CHECK-DAG: MayAlias: %struct* %st, i64* %y 22; CHECK-DAG: MayAlias: i64* %y, i32* %z 23; CHECK-DAG: NoAlias: i32* %x, i64* %y 24 25; CHECK-DAG: MustAlias: %struct* %y, i32* %y 26; CHECK-DAG: MustAlias: i64* %y, i32* %y 27; CHECK-DAG: MustAlias: i80* %y, i32* %y 28 29define void @test_simple(ptr %st, i64 %i, i64 %j, i64 %k) { 30 %x = getelementptr inbounds %struct, ptr %st, i64 %i, i32 0 31 %y = getelementptr inbounds %struct, ptr %st, i64 %j, i32 1 32 %z = getelementptr inbounds %struct, ptr %st, i64 %k, i32 2 33 load %struct, ptr %st 34 load i32, ptr %x 35 load i32, ptr %y 36 load i32, ptr %z 37 load %struct, ptr %y 38 load i80, ptr %y 39 load i64, ptr %y 40 ret void 41} 42 43; As the GEP is not inbounds, these pointers may alias due to overflow. 44; CHECK-LABEL: test_not_inbounds 45; CHECK: MayAlias: i32* %x, i32* %y 46define void @test_not_inbounds(ptr %st, i64 %i, i64 %j, i64 %k) { 47 %x = getelementptr %struct, ptr %st, i64 %i, i32 0 48 %y = getelementptr %struct, ptr %st, i64 %j, i32 1 49 load i32, ptr %x 50 load i32, ptr %y 51 ret void 52} 53 54; It is sufficient to have nusw instead of inbounds. 55; CHECK-LABEL: test_nusw 56; CHECK: NoAlias: i32* %x, i32* %y 57define void @test_nusw(ptr %st, i64 %i, i64 %j, i64 %k) { 58 %x = getelementptr nusw %struct, ptr %st, i64 %i, i32 0 59 %y = getelementptr nusw %struct, ptr %st, i64 %j, i32 1 60 load i32, ptr %x 61 load i32, ptr %y 62 ret void 63} 64 65; CHECK-LABEL: test_in_array 66 67; CHECK-DAG: MayAlias: [1 x %struct]* %st, i32* %x 68; CHECK-DAG: MayAlias: [1 x %struct]* %st, i32* %y 69; CHECK-DAG: MayAlias: [1 x %struct]* %st, i32* %z 70 71; CHECK-DAG: NoAlias: i32* %x, i32* %y 72; CHECK-DAG: NoAlias: i32* %x, i32* %z 73; CHECK-DAG: NoAlias: i32* %y, i32* %z 74 75; CHECK-DAG: MayAlias: [1 x %struct]* %st, %struct* %y 76; CHECK-DAG: MayAlias: i32* %x, %struct* %y 77; CHECK-DAG: MayAlias: i32* %x, i80* %y 78 79; CHECK-DAG: MayAlias: [1 x %struct]* %st, i64* %y 80; CHECK-DAG: MayAlias: i64* %y, i32* %z 81; CHECK-DAG: NoAlias: i32* %x, i64* %y 82 83; CHECK-DAG: MustAlias: %struct* %y, i32* %y 84; CHECK-DAG: MustAlias: i64* %y, i32* %y 85; CHECK-DAG: MustAlias: i80* %y, i32* %y 86 87define void @test_in_array(ptr %st, i64 %i, i64 %j, i64 %k, i64 %i1, i64 %j1, i64 %k1) { 88 %x = getelementptr inbounds [1 x %struct], ptr %st, i64 %i, i64 %i1, i32 0 89 %y = getelementptr inbounds [1 x %struct], ptr %st, i64 %j, i64 %j1, i32 1 90 %z = getelementptr inbounds [1 x %struct], ptr %st, i64 %k, i64 %k1, i32 2 91 load [1 x %struct], ptr %st 92 load i32, ptr %x 93 load i32, ptr %y 94 load i32, ptr %z 95 load %struct, ptr %y 96 load i80, ptr %y 97 load i64, ptr %y 98 ret void 99} 100 101; CHECK-LABEL: test_in_3d_array 102 103; CHECK-DAG: MayAlias: [1 x [1 x [1 x %struct]]]* %st, i32* %x 104; CHECK-DAG: MayAlias: [1 x [1 x [1 x %struct]]]* %st, i32* %y 105; CHECK-DAG: MayAlias: [1 x [1 x [1 x %struct]]]* %st, i32* %z 106 107; CHECK-DAG: NoAlias: i32* %x, i32* %y 108; CHECK-DAG: NoAlias: i32* %x, i32* %z 109; CHECK-DAG: NoAlias: i32* %y, i32* %z 110 111; CHECK-DAG: MayAlias: [1 x [1 x [1 x %struct]]]* %st, %struct* %y 112; CHECK-DAG: MayAlias: i32* %x, %struct* %y 113; CHECK-DAG: MayAlias: i32* %x, i80* %y 114 115; CHECK-DAG: MayAlias: [1 x [1 x [1 x %struct]]]* %st, i64* %y 116; CHECK-DAG: MayAlias: i64* %y, i32* %z 117; CHECK-DAG: NoAlias: i32* %x, i64* %y 118 119; CHECK-DAG: MustAlias: %struct* %y, i32* %y 120; CHECK-DAG: MustAlias: i64* %y, i32* %y 121; CHECK-DAG: MustAlias: i80* %y, i32* %y 122 123define void @test_in_3d_array(ptr %st, i64 %i, i64 %j, i64 %k, i64 %i1, i64 %j1, i64 %k1, i64 %i2, i64 %j2, i64 %k2, i64 %i3, i64 %j3, i64 %k3) { 124 %x = getelementptr inbounds [1 x [1 x [1 x %struct]]], ptr %st, i64 %i, i64 %i1, i64 %i2, i64 %i3, i32 0 125 %y = getelementptr inbounds [1 x [1 x [1 x %struct]]], ptr %st, i64 %j, i64 %j1, i64 %j2, i64 %j3, i32 1 126 %z = getelementptr inbounds [1 x [1 x [1 x %struct]]], ptr %st, i64 %k, i64 %k1, i64 %k2, i64 %k3, i32 2 127 load [1 x [1 x [1 x %struct]]], ptr %st 128 load i32, ptr %x 129 load i32, ptr %y 130 load i32, ptr %z 131 load %struct, ptr %y 132 load i80, ptr %y 133 load i64, ptr %y 134 ret void 135} 136 137; CHECK-LABEL: test_same_underlying_object_same_indices 138 139; CHECK-DAG: NoAlias: i32* %x, i32* %x2 140; CHECK-DAG: NoAlias: i32* %y, i32* %y2 141; CHECK-DAG: NoAlias: i32* %z, i32* %z2 142 143; CHECK-DAG: NoAlias: i32* %x, i32* %y2 144; CHECK-DAG: NoAlias: i32* %x, i32* %z2 145 146; CHECK-DAG: NoAlias: i32* %x2, i32* %y 147; CHECK-DAG: NoAlias: i32* %y, i32* %z2 148 149; CHECK-DAG: NoAlias: i32* %x2, i32* %z 150; CHECK-DAG: NoAlias: i32* %y2, i32* %z 151 152define void @test_same_underlying_object_same_indices(ptr %st, i64 %i, i64 %j, i64 %k) { 153 %st2 = getelementptr inbounds %struct, ptr %st, i32 10 154 %x2 = getelementptr inbounds %struct, ptr %st2, i64 %i, i32 0 155 %y2 = getelementptr inbounds %struct, ptr %st2, i64 %j, i32 1 156 %z2 = getelementptr inbounds %struct, ptr %st2, i64 %k, i32 2 157 %x = getelementptr inbounds %struct, ptr %st, i64 %i, i32 0 158 %y = getelementptr inbounds %struct, ptr %st, i64 %j, i32 1 159 %z = getelementptr inbounds %struct, ptr %st, i64 %k, i32 2 160 load i32, ptr %x 161 load i32, ptr %y 162 load i32, ptr %z 163 load i32, ptr %x2 164 load i32, ptr %y2 165 load i32, ptr %z2 166 ret void 167} 168 169; CHECK-LABEL: test_same_underlying_object_different_indices 170 171; CHECK-DAG: MayAlias: i32* %x, i32* %x2 172; CHECK-DAG: MayAlias: i32* %y, i32* %y2 173; CHECK-DAG: MayAlias: i32* %z, i32* %z2 174 175; CHECK-DAG: NoAlias: i32* %x, i32* %y2 176; CHECK-DAG: NoAlias: i32* %x, i32* %z2 177 178; CHECK-DAG: NoAlias: i32* %x2, i32* %y 179; CHECK-DAG: NoAlias: i32* %y, i32* %z2 180 181; CHECK-DAG: NoAlias: i32* %x2, i32* %z 182; CHECK-DAG: NoAlias: i32* %y2, i32* %z 183 184define void @test_same_underlying_object_different_indices(ptr %st, i64 %i1, i64 %j1, i64 %k1, i64 %i2, i64 %k2, i64 %j2) { 185 %st2 = getelementptr inbounds %struct, ptr %st, i32 10 186 %x2 = getelementptr inbounds %struct, ptr %st2, i64 %i2, i32 0 187 %y2 = getelementptr inbounds %struct, ptr %st2, i64 %j2, i32 1 188 %z2 = getelementptr inbounds %struct, ptr %st2, i64 %k2, i32 2 189 %x = getelementptr inbounds %struct, ptr %st, i64 %i1, i32 0 190 %y = getelementptr inbounds %struct, ptr %st, i64 %j1, i32 1 191 %z = getelementptr inbounds %struct, ptr %st, i64 %k1, i32 2 192 load i32, ptr %x 193 load i32, ptr %y 194 load i32, ptr %z 195 load i32, ptr %x2 196 load i32, ptr %y2 197 load i32, ptr %z2 198 ret void 199} 200 201 202%struct2 = type { [1 x { i32, i32 }], [2 x { i32 }] } 203 204; CHECK-LABEL: test_struct_in_array 205; CHECK-DAG: MustAlias: i32* %x, i32* %y 206define void @test_struct_in_array(ptr %st, i64 %i, i64 %j, i64 %k) { 207 %x = getelementptr inbounds %struct2, ptr %st, i32 0, i32 1, i32 1, i32 0 208 %y = getelementptr inbounds %struct2, ptr %st, i32 0, i32 0, i32 1, i32 1 209 load i32, ptr %x 210 load i32, ptr %y 211 ret void 212} 213 214; PR27418 - Treat GEP indices with the same value but different types the same 215; CHECK-LABEL: test_different_index_types 216; CHECK: MustAlias: i16* %tmp1, i16* %tmp2 217define void @test_different_index_types(ptr %arr) { 218 %tmp1 = getelementptr inbounds [2 x i16], ptr %arr, i16 0, i32 1 219 %tmp2 = getelementptr inbounds [2 x i16], ptr %arr, i16 0, i16 1 220 load i16, ptr %tmp1 221 load i16, ptr %tmp2 222 ret void 223} 224