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