mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-17 03:30:28 +00:00
9c252165a7
different fields. We can show that two GEPs off of the same (possibly multidimensional) array of structs, into different fields, can't alias. Quoting: For two GEPOperators GEP1 and GEP2, if we find that: - both GEPs begin indexing from the exact same pointer; - the last indices in both GEPs are constants, indexing into a struct; - said indices are different, hence,the pointed-to fields are different; - and both GEPs only index through arrays prior to that; this lets us determine that the struct that GEP1 indexes into and the struct that GEP2 indexes into must either precisely overlap or be completely disjoint. Because they cannot partially overlap, indexing into different non-overlapping fields of the struct will never alias. The other BasicAA::aliasGEP rules worked in some cases, but not all (for example, the i32x3 struct in the testcase). We can add this simple ad-hoc rule to complement them. rdar://19717375 Differential Revision: http://reviews.llvm.org/D7453 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@228498 91177308-0d34-0410-b5e6-96231b3b80d8
165 lines
5.9 KiB
LLVM
165 lines
5.9 KiB
LLVM
; RUN: opt < %s -basicaa -aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
|
|
|
|
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
|
|
|
%struct = type { i32, i32, i32 }
|
|
|
|
; CHECK-LABEL: test_simple
|
|
|
|
; CHECK-DAG: PartialAlias: %struct* %st, i32* %x
|
|
; CHECK-DAG: PartialAlias: %struct* %st, i32* %y
|
|
; CHECK-DAG: PartialAlias: %struct* %st, i32* %z
|
|
|
|
; CHECK-DAG: NoAlias: i32* %x, i32* %y
|
|
; CHECK-DAG: NoAlias: i32* %x, i32* %z
|
|
; CHECK-DAG: NoAlias: i32* %y, i32* %z
|
|
|
|
; CHECK-DAG: PartialAlias: %struct* %st, %struct* %y_12
|
|
; CHECK-DAG: PartialAlias: %struct* %y_12, i32* %x
|
|
; CHECK-DAG: PartialAlias: i32* %x, i80* %y_10
|
|
|
|
; CHECK-DAG: PartialAlias: %struct* %st, i64* %y_8
|
|
; CHECK-DAG: PartialAlias: i32* %z, i64* %y_8
|
|
; CHECK-DAG: NoAlias: i32* %x, i64* %y_8
|
|
|
|
; CHECK-DAG: MustAlias: %struct* %y_12, i32* %y
|
|
; CHECK-DAG: MustAlias: i32* %y, i64* %y_8
|
|
; CHECK-DAG: MustAlias: i32* %y, i80* %y_10
|
|
|
|
define void @test_simple(%struct* %st, i64 %i, i64 %j, i64 %k) {
|
|
%x = getelementptr %struct* %st, i64 %i, i32 0
|
|
%y = getelementptr %struct* %st, i64 %j, i32 1
|
|
%z = getelementptr %struct* %st, i64 %k, i32 2
|
|
%y_12 = bitcast i32* %y to %struct*
|
|
%y_10 = bitcast i32* %y to i80*
|
|
%y_8 = bitcast i32* %y to i64*
|
|
ret void
|
|
}
|
|
|
|
; CHECK-LABEL: test_in_array
|
|
|
|
; CHECK-DAG: PartialAlias: [1 x %struct]* %st, i32* %x
|
|
; CHECK-DAG: PartialAlias: [1 x %struct]* %st, i32* %y
|
|
; CHECK-DAG: PartialAlias: [1 x %struct]* %st, i32* %z
|
|
|
|
; CHECK-DAG: NoAlias: i32* %x, i32* %y
|
|
; CHECK-DAG: NoAlias: i32* %x, i32* %z
|
|
; CHECK-DAG: NoAlias: i32* %y, i32* %z
|
|
|
|
; CHECK-DAG: PartialAlias: %struct* %y_12, [1 x %struct]* %st
|
|
; CHECK-DAG: PartialAlias: %struct* %y_12, i32* %x
|
|
; CHECK-DAG: PartialAlias: i32* %x, i80* %y_10
|
|
|
|
; CHECK-DAG: PartialAlias: [1 x %struct]* %st, i64* %y_8
|
|
; CHECK-DAG: PartialAlias: i32* %z, i64* %y_8
|
|
; CHECK-DAG: NoAlias: i32* %x, i64* %y_8
|
|
|
|
; CHECK-DAG: MustAlias: %struct* %y_12, i32* %y
|
|
; CHECK-DAG: MustAlias: i32* %y, i64* %y_8
|
|
; CHECK-DAG: MustAlias: i32* %y, i80* %y_10
|
|
|
|
define void @test_in_array([1 x %struct]* %st, i64 %i, i64 %j, i64 %k, i64 %i1, i64 %j1, i64 %k1) {
|
|
%x = getelementptr [1 x %struct]* %st, i64 %i, i64 %i1, i32 0
|
|
%y = getelementptr [1 x %struct]* %st, i64 %j, i64 %j1, i32 1
|
|
%z = getelementptr [1 x %struct]* %st, i64 %k, i64 %k1, i32 2
|
|
%y_12 = bitcast i32* %y to %struct*
|
|
%y_10 = bitcast i32* %y to i80*
|
|
%y_8 = bitcast i32* %y to i64*
|
|
ret void
|
|
}
|
|
|
|
; CHECK-LABEL: test_in_3d_array
|
|
|
|
; CHECK-DAG: PartialAlias: [1 x [1 x [1 x %struct]]]* %st, i32* %x
|
|
; CHECK-DAG: PartialAlias: [1 x [1 x [1 x %struct]]]* %st, i32* %y
|
|
; CHECK-DAG: PartialAlias: [1 x [1 x [1 x %struct]]]* %st, i32* %z
|
|
|
|
; CHECK-DAG: NoAlias: i32* %x, i32* %y
|
|
; CHECK-DAG: NoAlias: i32* %x, i32* %z
|
|
; CHECK-DAG: NoAlias: i32* %y, i32* %z
|
|
|
|
; CHECK-DAG: PartialAlias: %struct* %y_12, [1 x [1 x [1 x %struct]]]* %st
|
|
; CHECK-DAG: PartialAlias: %struct* %y_12, i32* %x
|
|
; CHECK-DAG: PartialAlias: i32* %x, i80* %y_10
|
|
|
|
; CHECK-DAG: PartialAlias: [1 x [1 x [1 x %struct]]]* %st, i64* %y_8
|
|
; CHECK-DAG: PartialAlias: i32* %z, i64* %y_8
|
|
; CHECK-DAG: NoAlias: i32* %x, i64* %y_8
|
|
|
|
; CHECK-DAG: MustAlias: %struct* %y_12, i32* %y
|
|
; CHECK-DAG: MustAlias: i32* %y, i64* %y_8
|
|
; CHECK-DAG: MustAlias: i32* %y, i80* %y_10
|
|
|
|
define 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) {
|
|
%x = getelementptr [1 x [1 x [1 x %struct]]]* %st, i64 %i, i64 %i1, i64 %i2, i64 %i3, i32 0
|
|
%y = getelementptr [1 x [1 x [1 x %struct]]]* %st, i64 %j, i64 %j1, i64 %j2, i64 %j3, i32 1
|
|
%z = getelementptr [1 x [1 x [1 x %struct]]]* %st, i64 %k, i64 %k1, i64 %k2, i64 %k3, i32 2
|
|
%y_12 = bitcast i32* %y to %struct*
|
|
%y_10 = bitcast i32* %y to i80*
|
|
%y_8 = bitcast i32* %y to i64*
|
|
ret void
|
|
}
|
|
|
|
; CHECK-LABEL: test_same_underlying_object_same_indices
|
|
|
|
; CHECK-DAG: NoAlias: i32* %x, i32* %x2
|
|
; CHECK-DAG: NoAlias: i32* %y, i32* %y2
|
|
; CHECK-DAG: NoAlias: i32* %z, i32* %z2
|
|
|
|
; CHECK-DAG: PartialAlias: i32* %x, i32* %y2
|
|
; CHECK-DAG: PartialAlias: i32* %x, i32* %z2
|
|
|
|
; CHECK-DAG: PartialAlias: i32* %x2, i32* %y
|
|
; CHECK-DAG: PartialAlias: i32* %y, i32* %z2
|
|
|
|
; CHECK-DAG: PartialAlias: i32* %x2, i32* %z
|
|
; CHECK-DAG: PartialAlias: i32* %y2, i32* %z
|
|
|
|
define void @test_same_underlying_object_same_indices(%struct* %st, i64 %i, i64 %j, i64 %k) {
|
|
%st2 = getelementptr %struct* %st, i32 10
|
|
%x2 = getelementptr %struct* %st2, i64 %i, i32 0
|
|
%y2 = getelementptr %struct* %st2, i64 %j, i32 1
|
|
%z2 = getelementptr %struct* %st2, i64 %k, i32 2
|
|
%x = getelementptr %struct* %st, i64 %i, i32 0
|
|
%y = getelementptr %struct* %st, i64 %j, i32 1
|
|
%z = getelementptr %struct* %st, i64 %k, i32 2
|
|
ret void
|
|
}
|
|
|
|
; CHECK-LABEL: test_same_underlying_object_different_indices
|
|
|
|
; CHECK-DAG: PartialAlias: i32* %x, i32* %x2
|
|
; CHECK-DAG: PartialAlias: i32* %y, i32* %y2
|
|
; CHECK-DAG: PartialAlias: i32* %z, i32* %z2
|
|
|
|
; CHECK-DAG: PartialAlias: i32* %x, i32* %y2
|
|
; CHECK-DAG: PartialAlias: i32* %x, i32* %z2
|
|
|
|
; CHECK-DAG: PartialAlias: i32* %x2, i32* %y
|
|
; CHECK-DAG: PartialAlias: i32* %y, i32* %z2
|
|
|
|
; CHECK-DAG: PartialAlias: i32* %x2, i32* %z
|
|
; CHECK-DAG: PartialAlias: i32* %y2, i32* %z
|
|
|
|
define void @test_same_underlying_object_different_indices(%struct* %st, i64 %i1, i64 %j1, i64 %k1, i64 %i2, i64 %k2, i64 %j2) {
|
|
%st2 = getelementptr %struct* %st, i32 10
|
|
%x2 = getelementptr %struct* %st2, i64 %i2, i32 0
|
|
%y2 = getelementptr %struct* %st2, i64 %j2, i32 1
|
|
%z2 = getelementptr %struct* %st2, i64 %k2, i32 2
|
|
%x = getelementptr %struct* %st, i64 %i1, i32 0
|
|
%y = getelementptr %struct* %st, i64 %j1, i32 1
|
|
%z = getelementptr %struct* %st, i64 %k1, i32 2
|
|
ret void
|
|
}
|
|
|
|
|
|
%struct2 = type { [1 x { i32, i32 }], [2 x { i32 }] }
|
|
|
|
; CHECK-LABEL: test_struct_in_array
|
|
; CHECK-DAG: MustAlias: i32* %x, i32* %y
|
|
define void @test_struct_in_array(%struct2* %st, i64 %i, i64 %j, i64 %k) {
|
|
%x = getelementptr %struct2* %st, i32 0, i32 1, i32 1, i32 0
|
|
%y = getelementptr %struct2* %st, i32 0, i32 0, i32 1, i32 1
|
|
ret void
|
|
}
|