llvm.org GIT mirror llvm / dc5a8f2
[BasicAA] Non-equal indices in a GEP of a SequentialType don't overlap If the final indices of two GEPs can be proven to not be equal, and the GEP is of a SequentialType (not a StructType), then the two GEPs do not alias. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@251016 91177308-0d34-0410-b5e6-96231b3b80d8 James Molloy 4 years ago
2 changed file(s) with 82 addition(s) and 9 deletion(s). Raw diff Collapse all Expand all
775775 ConstantInt *C2 =
776776 dyn_cast(GEP2->getOperand(GEP2->getNumOperands() - 1));
777777
778 // If the last (struct) indices aren't constants, we can't say anything.
779 // If they're identical, the other indices might be also be dynamically
780 // equal, so the GEPs can alias.
781 if (!C1 || !C2 || C1 == C2)
778 // If the last (struct) indices are constants and are equal, the other indices
779 // might be also be dynamically equal, so the GEPs can alias.
780 if (C1 && C2 && C1 == C2)
782781 return MayAlias;
783782
784783 // Find the last-indexed type of the GEP, i.e., the type you'd get if
801800 IntermediateIndices.push_back(GEP1->getOperand(i + 1));
802801 }
803802
804 StructType *LastIndexedStruct =
805 dyn_cast(GetElementPtrInst::getIndexedType(
806 GEP1->getSourceElementType(), IntermediateIndices));
807
808 if (!LastIndexedStruct)
803 auto *Ty = GetElementPtrInst::getIndexedType(
804 GEP1->getSourceElementType(), IntermediateIndices);
805 StructType *LastIndexedStruct = dyn_cast(Ty);
806
807 if (isa(Ty)) {
808 // We know that:
809 // - both GEPs begin indexing from the exact same pointer;
810 // - the last indices in both GEPs are constants, indexing into a sequential
811 // type (array or pointer);
812 // - both GEPs only index through arrays prior to that.
813 //
814 // Because array indices greater than the number of elements are valid in
815 // GEPs, unless we know the intermediate indices are identical between
816 // GEP1 and GEP2 we cannot guarantee that the last indexed arrays don't
817 // partially overlap.
818 for (unsigned i = 0, e = GEP1->getNumIndices() - 1; i != e; ++i)
819 if (GEP1->getOperand(i + 1) != GEP2->getOperand(i + 1))
820 return MayAlias;
821
822 // Now we know that the array/pointer that GEP1 indexes into and that
823 // that GEP2 indexes into must either precisely overlap or be disjoint.
824 // Because they cannot partially overlap and because fields in an array
825 // cannot overlap, if we can prove the final indices are different between
826 // GEP1 and GEP2, we can conclude GEP1 and GEP2 don't alias.
827
828 // If the last indices are constants, we've already checked they don't
829 // equal each other so we can exit early.
830 if (C1 && C2)
831 return NoAlias;
832 if (isKnownNonEqual(GEP1->getOperand(GEP1->getNumOperands() - 1),
833 GEP2->getOperand(GEP2->getNumOperands() - 1),
834 DL))
835 return NoAlias;
809836 return MayAlias;
837 } else if (!LastIndexedStruct || !C1 || !C2) {
838 return MayAlias;
839 }
810840
811841 // We know that:
812842 // - both GEPs begin indexing from the exact same pointer;
0 ; RUN: opt < %s -basicaa -aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
1
2 ; CHECK: Function: t1
3 ; CHECK: NoAlias: i32* %gep1, i32* %gep2
4 define void @t1([8 x i32]* %p, i32 %addend, i32* %q) {
5 %knownnonzero = load i32, i32* %q, !range !0
6 %add = add nsw nuw i32 %addend, %knownnonzero
7 %gep1 = getelementptr [8 x i32], [8 x i32]* %p, i32 2, i32 %addend
8 %gep2 = getelementptr [8 x i32], [8 x i32]* %p, i32 2, i32 %add
9 ret void
10 }
11
12 ; CHECK: Function: t2
13 ; CHECK: PartialAlias: i32* %gep1, i32* %gep2
14 define void @t2([8 x i32]* %p, i32 %addend, i32* %q) {
15 %knownnonzero = load i32, i32* %q, !range !0
16 %add = add nsw nuw i32 %addend, %knownnonzero
17 %gep1 = getelementptr [8 x i32], [8 x i32]* %p, i32 1, i32 %addend
18 %gep2 = getelementptr [8 x i32], [8 x i32]* %p, i32 0, i32 %add
19 ret void
20 }
21
22 ; CHECK: Function: t3
23 ; CHECK: MustAlias: i32* %gep1, i32* %gep2
24 define void @t3([8 x i32]* %p, i32 %addend, i32* %q) {
25 %knownnonzero = load i32, i32* %q, !range !0
26 %add = add nsw nuw i32 %addend, %knownnonzero
27 %gep1 = getelementptr [8 x i32], [8 x i32]* %p, i32 0, i32 %add
28 %gep2 = getelementptr [8 x i32], [8 x i32]* %p, i32 0, i32 %add
29 ret void
30 }
31
32 ; CHECK: Function: t4
33 ; CHECK: PartialAlias: i32* %gep1, i32* %gep2
34 define void @t4([8 x i32]* %p, i32 %addend, i32* %q) {
35 %knownnonzero = load i32, i32* %q, !range !0
36 %add = add nsw nuw i32 %addend, %knownnonzero
37 %gep1 = getelementptr [8 x i32], [8 x i32]* %p, i32 1, i32 %addend
38 %gep2 = getelementptr [8 x i32], [8 x i32]* %p, i32 %add, i32 %add
39 ret void
40 }
41
42 !0 = !{ i32 1, i32 5 }