llvm.org GIT mirror llvm / 3d5f96e
BasicAA: Recognize cyclic NoAlias phis Enhances basic alias analysis to recognize phis whose first incoming values are NoAlias and whose other incoming values are just the phi node itself through some amount of recursion. Example: With this change basicaa reports that ptr_phi and ptr_phi2 do not alias each other. bb: ptr = ptr2 + 1 loop: ptr_phi = phi [bb, ptr], [loop, ptr_plus_one] ptr2_phi = phi [bb, ptr2], [loop, ptr2_plus_one] ... ptr_plus_one = gep ptr_phi, 1 ptr2_plus_one = gep ptr2_phi, 1 This enables the elimination of one load in code like the following: extern int foo; int test_noalias(int *ptr, int num, int* coeff) { int *ptr2 = ptr; int result = (*ptr++) * (*coeff--); while (num--) { *ptr2++ = *ptr; result += (*coeff--) * (*ptr++); } *ptr = foo; return result; } Part 2/2 of fix for PR13564. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163319 91177308-0d34-0410-b5e6-96231b3b80d8 Arnold Schwaighofer 8 years ago
2 changed file(s) with 68 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
10591059 // on corresponding edges.
10601060 if (const PHINode *PN2 = dyn_cast(V2))
10611061 if (PN2->getParent() == PN->getParent()) {
1062 LocPair Locs(Location(PN, PNSize, PNTBAAInfo),
1063 Location(V2, V2Size, V2TBAAInfo));
1064 if (PN > V2)
1065 std::swap(Locs.first, Locs.second);
1066
10621067 AliasResult Alias =
10631068 aliasCheck(PN->getIncomingValue(0), PNSize, PNTBAAInfo,
10641069 PN2->getIncomingValueForBlock(PN->getIncomingBlock(0)),
10651070 V2Size, V2TBAAInfo);
10661071 if (Alias == MayAlias)
10671072 return MayAlias;
1073
1074 // If the first source of the PHI nodes NoAlias and the other inputs are
1075 // the PHI node itself through some amount of recursion this does not add
1076 // any new information so just return NoAlias.
1077 // bb:
1078 // ptr = ptr2 + 1
1079 // loop:
1080 // ptr_phi = phi [bb, ptr], [loop, ptr_plus_one]
1081 // ptr2_phi = phi [bb, ptr2], [loop, ptr2_plus_one]
1082 // ...
1083 // ptr_plus_one = gep ptr_phi, 1
1084 // ptr2_plus_one = gep ptr2_phi, 1
1085 // We assume for the recursion that the the phis (ptr_phi, ptr2_phi) do
1086 // not alias each other.
1087 bool ArePhisAssumedNoAlias = false;
1088 AliasResult OrigAliasResult;
1089 if (Alias == NoAlias) {
1090 // Pretend the phis do not alias.
1091 assert(AliasCache.count(Locs) &&
1092 "There must exist an entry for the phi node");
1093 OrigAliasResult = AliasCache[Locs];
1094 AliasCache[Locs] = NoAlias;
1095 ArePhisAssumedNoAlias = true;
1096 }
1097
10681098 for (unsigned i = 1, e = PN->getNumIncomingValues(); i != e; ++i) {
10691099 AliasResult ThisAlias =
10701100 aliasCheck(PN->getIncomingValue(i), PNSize, PNTBAAInfo,
10741104 if (Alias == MayAlias)
10751105 break;
10761106 }
1107
1108 // Reset if speculation failed.
1109 if (ArePhisAssumedNoAlias && Alias != NoAlias)
1110 AliasCache[Locs] = OrigAliasResult;
1111
10771112 return Alias;
10781113 }
10791114
0 target datalayout =
1 "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
2
3 ; RUN: opt < %s -basicaa -aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
4
5 ; ptr_phi and ptr2_phi do not alias.
6 ; CHECK: NoAlias: i32* %ptr2_phi, i32* %ptr_phi
7
8 define i32 @test_noalias(i32* %ptr2, i32 %count, i32* %coeff) {
9 entry:
10 %ptr = getelementptr inbounds i32* %ptr2, i64 1
11 br label %while.body
12
13 while.body:
14 %num = phi i32 [ %count, %entry ], [ %dec, %while.body ]
15 %ptr_phi = phi i32* [ %ptr, %entry ], [ %ptr_inc, %while.body ]
16 %ptr2_phi = phi i32* [ %ptr2, %entry ], [ %ptr2_inc, %while.body ]
17 %result.09 = phi i32 [ 0 , %entry ], [ %add, %while.body ]
18 %dec = add nsw i32 %num, -1
19 %0 = load i32* %ptr_phi, align 4
20 store i32 %0, i32* %ptr2_phi, align 4
21 %1 = load i32* %coeff, align 4
22 %2 = load i32* %ptr_phi, align 4
23 %mul = mul nsw i32 %1, %2
24 %add = add nsw i32 %mul, %result.09
25 %tobool = icmp eq i32 %dec, 0
26 %ptr_inc = getelementptr inbounds i32* %ptr_phi, i64 1
27 %ptr2_inc = getelementptr inbounds i32* %ptr2_phi, i64 1
28 br i1 %tobool, label %the_exit, label %while.body
29
30 the_exit:
31 ret i32 %add
32 }