mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-25 10:26:06 +00:00
[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 c53e2ecf0296a55d3c33c19fb70a3aa7f81f2732. Fixes https://github.com/llvm/llvm-project/issues/76789.
This commit is contained in:
parent
55172b7005
commit
5f57ad85a1
@ -154,6 +154,8 @@ struct CaptureInfo {
|
||||
|
||||
/// Check whether Object is not captured before instruction I. If OrAt is
|
||||
/// true, captures by instruction I itself are also considered.
|
||||
///
|
||||
/// If I is nullptr, then captures at any point will be considered.
|
||||
virtual bool isNotCapturedBefore(const Value *Object, const Instruction *I,
|
||||
bool OrAt) = 0;
|
||||
};
|
||||
|
@ -883,6 +883,11 @@ bool llvm::isEscapeSource(const Value *V) {
|
||||
if (isa<IntToPtrInst>(V))
|
||||
return true;
|
||||
|
||||
// Same for inttoptr constant expressions.
|
||||
if (auto *CE = dyn_cast<ConstantExpr>(V))
|
||||
if (CE->getOpcode() == Instruction::IntToPtr)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -215,7 +215,7 @@ bool EarliestEscapeInfo::isNotCapturedBefore(const Value *Object,
|
||||
auto Iter = EarliestEscapes.insert({Object, nullptr});
|
||||
if (Iter.second) {
|
||||
Instruction *EarliestCapture = FindEarliestCapture(
|
||||
Object, *const_cast<Function *>(I->getFunction()),
|
||||
Object, *const_cast<Function *>(DT.getRoot()->getParent()),
|
||||
/*ReturnCaptures=*/false, /*StoreCaptures=*/true, DT);
|
||||
if (EarliestCapture) {
|
||||
auto Ins = Inst2Obj.insert({EarliestCapture, {}});
|
||||
@ -228,6 +228,10 @@ bool EarliestEscapeInfo::isNotCapturedBefore(const Value *Object,
|
||||
if (!Iter.first->second)
|
||||
return true;
|
||||
|
||||
// No context instruction means any use is capturing.
|
||||
if (!I)
|
||||
return false;
|
||||
|
||||
if (I == Iter.first->second) {
|
||||
if (OrAt)
|
||||
return false;
|
||||
@ -1502,11 +1506,6 @@ AliasResult BasicAAResult::aliasCheck(const Value *V1, LocationSize V1Size,
|
||||
if (isIdentifiedObject(O1) && isIdentifiedObject(O2))
|
||||
return AliasResult::NoAlias;
|
||||
|
||||
// Constant pointers can't alias with non-const isIdentifiedObject objects.
|
||||
if ((isa<Constant>(O1) && isIdentifiedObject(O2) && !isa<Constant>(O2)) ||
|
||||
(isa<Constant>(O2) && isIdentifiedObject(O1) && !isa<Constant>(O1)))
|
||||
return AliasResult::NoAlias;
|
||||
|
||||
// Function arguments can't alias with things that are known to be
|
||||
// unambigously identified at the function level.
|
||||
if ((isa<Argument>(O1) && isIdentifiedFunctionLocal(O2)) ||
|
||||
@ -1522,11 +1521,11 @@ AliasResult BasicAAResult::aliasCheck(const Value *V1, LocationSize V1Size,
|
||||
// temporary store the nocapture argument's value in a temporary memory
|
||||
// location if that memory location doesn't escape. Or it may pass a
|
||||
// nocapture value to other functions as long as they don't capture it.
|
||||
if (isEscapeSource(O1) &&
|
||||
AAQI.CI->isNotCapturedBefore(O2, cast<Instruction>(O1), /*OrAt*/ true))
|
||||
if (isEscapeSource(O1) && AAQI.CI->isNotCapturedBefore(
|
||||
O2, dyn_cast<Instruction>(O1), /*OrAt*/ true))
|
||||
return AliasResult::NoAlias;
|
||||
if (isEscapeSource(O2) &&
|
||||
AAQI.CI->isNotCapturedBefore(O1, cast<Instruction>(O2), /*OrAt*/ true))
|
||||
if (isEscapeSource(O2) && AAQI.CI->isNotCapturedBefore(
|
||||
O1, dyn_cast<Instruction>(O2), /*OrAt*/ true))
|
||||
return AliasResult::NoAlias;
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
; RUN: opt -passes=aa-eval -print-all-alias-modref-info -disable-output < %s 2>&1 | FileCheck %s
|
||||
|
||||
; CHECK: NoAlias: i8* %a, i8* %gep
|
||||
; CHECK: MayAlias: i8* %a, i8* %gep
|
||||
define void @inttoptr_alloca() {
|
||||
%a = alloca i8
|
||||
%a.int = ptrtoint ptr %a to i64
|
||||
@ -11,7 +11,7 @@ define void @inttoptr_alloca() {
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK: NoAlias: i8* %a, i8* %gep
|
||||
; CHECK: MayAlias: i8* %a, i8* %gep
|
||||
define void @inttoptr_alloca_unknown_relation(i64 %offset) {
|
||||
%a = alloca i8
|
||||
%a.int = ptrtoint ptr %a to i64
|
||||
@ -30,7 +30,7 @@ define void @inttoptr_alloca_noescape(i64 %offset) {
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK: NoAlias: i8* %a, i8* %gep
|
||||
; CHECK: MayAlias: i8* %a, i8* %gep
|
||||
define void @inttoptr_noalias(ptr noalias %a) {
|
||||
%a.int = ptrtoint ptr %a to i64
|
||||
%a.int.1 = add i64 %a.int, 1
|
||||
|
Loading…
x
Reference in New Issue
Block a user