Skip to content
This repository was archived by the owner on Jan 20, 2024. It is now read-only.

Commit 5f57ad8

Browse files
authored
[BasicAA] Remove incorrect rule about constant pointers (#76815)
BasicAA currently says that any Constant cannot alias an identified local object. This is not correct if the local object escaped, as it's possible to create a pointer to the escaped object using an inttoptr constant expression base. To compensate for this, make sure that inttoptr constant expressions are treated as escape sources, just like inttoptr instructions. This ensures that the optimization can still be applied if the local object is non-escaping. This is sufficient to still optimize the original motivating case from c53e2ec. Fixes llvm/llvm-project#76789.
1 parent 55172b7 commit 5f57ad8

File tree

4 files changed

+19
-13
lines changed

4 files changed

+19
-13
lines changed

llvm/include/llvm/Analysis/AliasAnalysis.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,8 @@ struct CaptureInfo {
154154

155155
/// Check whether Object is not captured before instruction I. If OrAt is
156156
/// true, captures by instruction I itself are also considered.
157+
///
158+
/// If I is nullptr, then captures at any point will be considered.
157159
virtual bool isNotCapturedBefore(const Value *Object, const Instruction *I,
158160
bool OrAt) = 0;
159161
};

llvm/lib/Analysis/AliasAnalysis.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -883,6 +883,11 @@ bool llvm::isEscapeSource(const Value *V) {
883883
if (isa<IntToPtrInst>(V))
884884
return true;
885885

886+
// Same for inttoptr constant expressions.
887+
if (auto *CE = dyn_cast<ConstantExpr>(V))
888+
if (CE->getOpcode() == Instruction::IntToPtr)
889+
return true;
890+
886891
return false;
887892
}
888893

llvm/lib/Analysis/BasicAliasAnalysis.cpp

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ bool EarliestEscapeInfo::isNotCapturedBefore(const Value *Object,
215215
auto Iter = EarliestEscapes.insert({Object, nullptr});
216216
if (Iter.second) {
217217
Instruction *EarliestCapture = FindEarliestCapture(
218-
Object, *const_cast<Function *>(I->getFunction()),
218+
Object, *const_cast<Function *>(DT.getRoot()->getParent()),
219219
/*ReturnCaptures=*/false, /*StoreCaptures=*/true, DT);
220220
if (EarliestCapture) {
221221
auto Ins = Inst2Obj.insert({EarliestCapture, {}});
@@ -228,6 +228,10 @@ bool EarliestEscapeInfo::isNotCapturedBefore(const Value *Object,
228228
if (!Iter.first->second)
229229
return true;
230230

231+
// No context instruction means any use is capturing.
232+
if (!I)
233+
return false;
234+
231235
if (I == Iter.first->second) {
232236
if (OrAt)
233237
return false;
@@ -1502,11 +1506,6 @@ AliasResult BasicAAResult::aliasCheck(const Value *V1, LocationSize V1Size,
15021506
if (isIdentifiedObject(O1) && isIdentifiedObject(O2))
15031507
return AliasResult::NoAlias;
15041508

1505-
// Constant pointers can't alias with non-const isIdentifiedObject objects.
1506-
if ((isa<Constant>(O1) && isIdentifiedObject(O2) && !isa<Constant>(O2)) ||
1507-
(isa<Constant>(O2) && isIdentifiedObject(O1) && !isa<Constant>(O1)))
1508-
return AliasResult::NoAlias;
1509-
15101509
// Function arguments can't alias with things that are known to be
15111510
// unambigously identified at the function level.
15121511
if ((isa<Argument>(O1) && isIdentifiedFunctionLocal(O2)) ||
@@ -1522,11 +1521,11 @@ AliasResult BasicAAResult::aliasCheck(const Value *V1, LocationSize V1Size,
15221521
// temporary store the nocapture argument's value in a temporary memory
15231522
// location if that memory location doesn't escape. Or it may pass a
15241523
// nocapture value to other functions as long as they don't capture it.
1525-
if (isEscapeSource(O1) &&
1526-
AAQI.CI->isNotCapturedBefore(O2, cast<Instruction>(O1), /*OrAt*/ true))
1524+
if (isEscapeSource(O1) && AAQI.CI->isNotCapturedBefore(
1525+
O2, dyn_cast<Instruction>(O1), /*OrAt*/ true))
15271526
return AliasResult::NoAlias;
1528-
if (isEscapeSource(O2) &&
1529-
AAQI.CI->isNotCapturedBefore(O1, cast<Instruction>(O2), /*OrAt*/ true))
1527+
if (isEscapeSource(O2) && AAQI.CI->isNotCapturedBefore(
1528+
O1, dyn_cast<Instruction>(O2), /*OrAt*/ true))
15301529
return AliasResult::NoAlias;
15311530
}
15321531

llvm/test/Analysis/BasicAA/inttoptr_constexpr.ll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
; RUN: opt -passes=aa-eval -print-all-alias-modref-info -disable-output < %s 2>&1 | FileCheck %s
22

3-
; CHECK: NoAlias: i8* %a, i8* %gep
3+
; CHECK: MayAlias: i8* %a, i8* %gep
44
define void @inttoptr_alloca() {
55
%a = alloca i8
66
%a.int = ptrtoint ptr %a to i64
@@ -11,7 +11,7 @@ define void @inttoptr_alloca() {
1111
ret void
1212
}
1313

14-
; CHECK: NoAlias: i8* %a, i8* %gep
14+
; CHECK: MayAlias: i8* %a, i8* %gep
1515
define void @inttoptr_alloca_unknown_relation(i64 %offset) {
1616
%a = alloca i8
1717
%a.int = ptrtoint ptr %a to i64
@@ -30,7 +30,7 @@ define void @inttoptr_alloca_noescape(i64 %offset) {
3030
ret void
3131
}
3232

33-
; CHECK: NoAlias: i8* %a, i8* %gep
33+
; CHECK: MayAlias: i8* %a, i8* %gep
3434
define void @inttoptr_noalias(ptr noalias %a) {
3535
%a.int = ptrtoint ptr %a to i64
3636
%a.int.1 = add i64 %a.int, 1

0 commit comments

Comments
 (0)