Skip to content

Commit 70e3c9a

Browse files
committed
[BasicAA] Always strip single-argument phi nodes
We can always look through single-argument (LCSSA) phi nodes when performing alias analysis. getUnderlyingObject() already does this, but stripPointerCastsAndInvariantGroups() does not. We still look through these phi nodes with the usual aliasPhi() logic, but sometimes get sub-optimal results due to the restrictions on value equivalence when looking through arbitrary phi nodes. I think it's generally beneficial to keep the underlying object logic and the pointer cast stripping logic in sync, insofar as it is possible. With this patch we get marginally better results: aa.NumMayAlias | 5010069 | 5009861 aa.NumMustAlias | 347518 | 347674 aa.NumNoAlias | 27201336 | 27201528 ... licm.NumPromoted | 1293 | 1296 I've renamed the relevant strip method to stripPointerCastsForAliasAnalysis(), as we're past the point where we can explicitly spell out everything that's getting stripped. Differential Revision: https://reviews.llvm.org/D96668
1 parent b006902 commit 70e3c9a

File tree

7 files changed

+27
-17
lines changed

7 files changed

+27
-17
lines changed

llvm/include/llvm/IR/Value.h

+5-4
Original file line numberDiff line numberDiff line change
@@ -654,15 +654,16 @@ class Value {
654654
->stripPointerCastsSameRepresentation());
655655
}
656656

657-
/// Strip off pointer casts, all-zero GEPs and invariant group info.
657+
/// Strip off pointer casts, all-zero GEPs, single-argument phi nodes and
658+
/// invariant group info.
658659
///
659660
/// Returns the original uncasted value. If this is called on a non-pointer
660661
/// value, it returns 'this'. This function should be used only in
661662
/// Alias analysis.
662-
const Value *stripPointerCastsAndInvariantGroups() const;
663-
Value *stripPointerCastsAndInvariantGroups() {
663+
const Value *stripPointerCastsForAliasAnalysis() const;
664+
Value *stripPointerCastsForAliasAnalysis() {
664665
return const_cast<Value *>(static_cast<const Value *>(this)
665-
->stripPointerCastsAndInvariantGroups());
666+
->stripPointerCastsForAliasAnalysis());
666667
}
667668

668669
/// Strip off pointer casts and all-constant inbounds GEPs.

llvm/lib/Analysis/BasicAliasAnalysis.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -1470,8 +1470,8 @@ AliasResult BasicAAResult::aliasCheck(const Value *V1, LocationSize V1Size,
14701470
return NoAlias;
14711471

14721472
// Strip off any casts if they exist.
1473-
V1 = V1->stripPointerCastsAndInvariantGroups();
1474-
V2 = V2->stripPointerCastsAndInvariantGroups();
1473+
V1 = V1->stripPointerCastsForAliasAnalysis();
1474+
V2 = V2->stripPointerCastsForAliasAnalysis();
14751475

14761476
// If V1 or V2 is undef, the result is NoAlias because we can always pick a
14771477
// value for undef that aliases nothing in the program.

llvm/lib/Analysis/GlobalsModRef.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -828,9 +828,9 @@ AliasResult GlobalsAAResult::alias(const MemoryLocation &LocA,
828828
AAQueryInfo &AAQI) {
829829
// Get the base object these pointers point to.
830830
const Value *UV1 =
831-
getUnderlyingObject(LocA.Ptr->stripPointerCastsAndInvariantGroups());
831+
getUnderlyingObject(LocA.Ptr->stripPointerCastsForAliasAnalysis());
832832
const Value *UV2 =
833-
getUnderlyingObject(LocB.Ptr->stripPointerCastsAndInvariantGroups());
833+
getUnderlyingObject(LocB.Ptr->stripPointerCastsForAliasAnalysis());
834834

835835
// If either of the underlying values is a global, they may be non-addr-taken
836836
// globals, which we can answer queries about.

llvm/lib/IR/Value.cpp

+8-5
Original file line numberDiff line numberDiff line change
@@ -551,7 +551,7 @@ enum PointerStripKind {
551551
PSK_ZeroIndices,
552552
PSK_ZeroIndicesAndAliases,
553553
PSK_ZeroIndicesSameRepresentation,
554-
PSK_ZeroIndicesAndInvariantGroups,
554+
PSK_ForAliasAnalysis,
555555
PSK_InBoundsConstantIndices,
556556
PSK_InBounds
557557
};
@@ -577,7 +577,7 @@ static const Value *stripPointerCastsAndOffsets(
577577
case PSK_ZeroIndices:
578578
case PSK_ZeroIndicesAndAliases:
579579
case PSK_ZeroIndicesSameRepresentation:
580-
case PSK_ZeroIndicesAndInvariantGroups:
580+
case PSK_ForAliasAnalysis:
581581
if (!GEP->hasAllZeroIndices())
582582
return V;
583583
break;
@@ -602,6 +602,9 @@ static const Value *stripPointerCastsAndOffsets(
602602
V = cast<Operator>(V)->getOperand(0);
603603
} else if (StripKind == PSK_ZeroIndicesAndAliases && isa<GlobalAlias>(V)) {
604604
V = cast<GlobalAlias>(V)->getAliasee();
605+
} else if (StripKind == PSK_ForAliasAnalysis && isa<PHINode>(V) &&
606+
cast<PHINode>(V)->getNumIncomingValues() == 1) {
607+
V = cast<PHINode>(V)->getIncomingValue(0);
605608
} else {
606609
if (const auto *Call = dyn_cast<CallBase>(V)) {
607610
if (const Value *RV = Call->getReturnedArgOperand()) {
@@ -611,7 +614,7 @@ static const Value *stripPointerCastsAndOffsets(
611614
// The result of launder.invariant.group must alias it's argument,
612615
// but it can't be marked with returned attribute, that's why it needs
613616
// special case.
614-
if (StripKind == PSK_ZeroIndicesAndInvariantGroups &&
617+
if (StripKind == PSK_ForAliasAnalysis &&
615618
(Call->getIntrinsicID() == Intrinsic::launder_invariant_group ||
616619
Call->getIntrinsicID() == Intrinsic::strip_invariant_group)) {
617620
V = Call->getArgOperand(0);
@@ -643,8 +646,8 @@ const Value *Value::stripInBoundsConstantOffsets() const {
643646
return stripPointerCastsAndOffsets<PSK_InBoundsConstantIndices>(this);
644647
}
645648

646-
const Value *Value::stripPointerCastsAndInvariantGroups() const {
647-
return stripPointerCastsAndOffsets<PSK_ZeroIndicesAndInvariantGroups>(this);
649+
const Value *Value::stripPointerCastsForAliasAnalysis() const {
650+
return stripPointerCastsAndOffsets<PSK_ForAliasAnalysis>(this);
648651
}
649652

650653
const Value *Value::stripAndAccumulateConstantOffsets(

llvm/lib/Target/AMDGPU/AMDGPUAliasAnalysis.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ AliasResult AMDGPUAAResult::alias(const MemoryLocation &LocA,
8787
if (asA == AMDGPUAS::FLAT_ADDRESS &&
8888
(asB == AMDGPUAS::LOCAL_ADDRESS || asB == AMDGPUAS::PRIVATE_ADDRESS)) {
8989
const auto *ObjA =
90-
getUnderlyingObject(A.Ptr->stripPointerCastsAndInvariantGroups());
90+
getUnderlyingObject(A.Ptr->stripPointerCastsForAliasAnalysis());
9191
if (const LoadInst *LI = dyn_cast<LoadInst>(ObjA)) {
9292
// If a generic pointer is loaded from the constant address space, it
9393
// could only be a GLOBAL or CONSTANT one as that address space is soley

llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp

+7-1
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,13 @@ static Instruction *simplifyInvariantGroupIntrinsic(IntrinsicInst &II,
390390
InstCombinerImpl &IC) {
391391
auto *Arg = II.getArgOperand(0);
392392
auto *StrippedArg = Arg->stripPointerCasts();
393-
auto *StrippedInvariantGroupsArg = Arg->stripPointerCastsAndInvariantGroups();
393+
auto *StrippedInvariantGroupsArg = StrippedArg;
394+
while (auto *Intr = dyn_cast<IntrinsicInst>(StrippedInvariantGroupsArg)) {
395+
if (Intr->getIntrinsicID() != Intrinsic::launder_invariant_group &&
396+
Intr->getIntrinsicID() != Intrinsic::strip_invariant_group)
397+
break;
398+
StrippedInvariantGroupsArg = Intr->getArgOperand(0)->stripPointerCasts();
399+
}
394400
if (StrippedArg == StrippedInvariantGroupsArg)
395401
return nullptr; // No launders/strips to remove.
396402

llvm/test/Analysis/BasicAA/phi-aa.ll

+2-2
Original file line numberDiff line numberDiff line change
@@ -199,9 +199,9 @@ for.body: ; preds = %for.body, %entry
199199
}
200200

201201
; CHECK-LABEL: single_arg_phi
202-
; CHECK: MayAlias: i32* %ptr, i32* %ptr.next
202+
; CHECK: NoAlias: i32* %ptr, i32* %ptr.next
203+
; CHECK: MustAlias: i32* %ptr, i32* %ptr.phi
203204
; CHECK: MustAlias: i32* %ptr.next, i32* %ptr.next.phi
204-
; TODO: The first one could be MustAlias as well.
205205
define void @single_arg_phi(i32* %ptr.base) {
206206
entry:
207207
br label %loop

0 commit comments

Comments
 (0)