Skip to content

Commit 6f3217a

Browse files
committed
Add a new helper getModRefInfo for two Instructions and update
1 parent 28dfc43 commit 6f3217a

File tree

4 files changed

+34
-51
lines changed

4 files changed

+34
-51
lines changed

llvm/include/llvm/Analysis/AliasAnalysis.h

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -381,14 +381,6 @@ class AAResults {
381381
MemoryLocation::getBeforeOrAfter(V2));
382382
}
383383

384-
/// A convenience wrapper around the \c isNoAlias for two instructions.
385-
bool isNoAlias(const Instruction *I1, const Instruction *I2) {
386-
return getModRefInfo(&*I1, MemoryLocation::getOrNone(&*I2)) ==
387-
ModRefInfo::NoModRef &&
388-
getModRefInfo(&*I2, MemoryLocation::getOrNone(&*I1)) ==
389-
ModRefInfo::NoModRef;
390-
}
391-
392384
/// A trivial helper function to check to see if the specified pointers are
393385
/// must-alias.
394386
bool isMustAlias(const MemoryLocation &LocA, const MemoryLocation &LocB) {
@@ -608,6 +600,7 @@ class AAResults {
608600
ModRefInfo getModRefInfo(const Instruction *I,
609601
const std::optional<MemoryLocation> &OptLoc,
610602
AAQueryInfo &AAQIP);
603+
ModRefInfo getModRefInfo(const Instruction *I1, const Instruction *I2);
611604
ModRefInfo callCapturesBefore(const Instruction *I,
612605
const MemoryLocation &MemLoc, DominatorTree *DT,
613606
AAQueryInfo &AAQIP);

llvm/lib/Analysis/AliasAnalysis.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,22 @@ ModRefInfo AAResults::getModRefInfo(const CallBase *Call1,
369369
return Result;
370370
}
371371

372+
// Check whether two instructions may read or write the same memory location.
373+
ModRefInfo AAResults::getModRefInfo(const Instruction *I1,
374+
const Instruction *I2) {
375+
SimpleAAQueryInfo AAQIP(*this);
376+
377+
// Early-exit if either instruction does not read or write memory.
378+
if (!I1->mayReadOrWriteMemory() || !I2->mayReadOrWriteMemory())
379+
return ModRefInfo::NoModRef;
380+
381+
if (const auto *Call2 = dyn_cast<CallBase>(I2))
382+
return getModRefInfo(I1, Call2, AAQIP);
383+
384+
ModRefInfo MR = getModRefInfo(I1, MemoryLocation::getOrNone(I2), AAQIP);
385+
return isModOrRefSet(MR) ? ModRefInfo::ModRef : ModRefInfo::NoModRef;
386+
}
387+
372388
MemoryEffects AAResults::getMemoryEffects(const CallBase *Call,
373389
AAQueryInfo &AAQI) {
374390
MemoryEffects Result = MemoryEffects::unknown();

llvm/lib/Transforms/Utils/FlattenCFG.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -356,8 +356,8 @@ bool FlattenCFGOpt::CompareIfRegionBlock(BasicBlock *Block1, BasicBlock *Block2,
356356
if (iter1->mayWriteToMemory()) {
357357
for (BasicBlock::iterator BI(PBI2), BE(PTI2); BI != BE; ++BI) {
358358
if (BI->mayReadFromMemory() || BI->mayWriteToMemory()) {
359-
// Check alias with Head2.
360-
if (!AA || !AA->isNoAlias(&*iter1, &*BI))
359+
// Check whether iter1 and BI may access the same memory location.
360+
if (!AA || AA->getModRefInfo(&*iter1, &*BI) != ModRefInfo::NoModRef)
361361
return false;
362362
}
363363
}

llvm/unittests/Analysis/AliasAnalysisTest.cpp

Lines changed: 15 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,14 @@ TEST_F(AliasAnalysisTest, getModRefInfo) {
186186
AtomicRMWInst::Xchg, Addr, ConstantInt::get(IntType, 1), Alignment,
187187
AtomicOrdering::Monotonic, SyncScope::System, BB);
188188

189+
FunctionType *FooBarTy = FunctionType::get(Type::getVoidTy(C), {}, false);
190+
Function::Create(FooBarTy, Function::ExternalLinkage, "foo", &M);
191+
auto *BarF = Function::Create(FooBarTy, Function::ExternalLinkage, "bar", &M);
192+
BarF->setDoesNotAccessMemory();
193+
194+
const Instruction *Foo = CallInst::Create(M.getFunction("foo"), {}, BB);
195+
const Instruction *Bar = CallInst::Create(M.getFunction("bar"), {}, BB);
196+
189197
ReturnInst::Create(C, nullptr, BB);
190198

191199
auto &AA = getAAResults(*F);
@@ -203,6 +211,13 @@ TEST_F(AliasAnalysisTest, getModRefInfo) {
203211
EXPECT_EQ(AA.getModRefInfo(CmpXChg1, std::nullopt), ModRefInfo::ModRef);
204212
EXPECT_EQ(AA.getModRefInfo(AtomicRMW, MemoryLocation()), ModRefInfo::ModRef);
205213
EXPECT_EQ(AA.getModRefInfo(AtomicRMW, std::nullopt), ModRefInfo::ModRef);
214+
EXPECT_EQ(AA.getModRefInfo(Store1, Load1), ModRefInfo::ModRef);
215+
EXPECT_EQ(AA.getModRefInfo(Store1, Store1), ModRefInfo::ModRef);
216+
EXPECT_EQ(AA.getModRefInfo(Store1, Add1), ModRefInfo::NoModRef);
217+
EXPECT_EQ(AA.getModRefInfo(Store1, Foo), ModRefInfo::ModRef);
218+
EXPECT_EQ(AA.getModRefInfo(Store1, Bar), ModRefInfo::NoModRef);
219+
EXPECT_EQ(AA.getModRefInfo(Foo, Bar), ModRefInfo::NoModRef);
220+
EXPECT_EQ(AA.getModRefInfo(Foo, Foo), ModRefInfo::ModRef);
206221
}
207222

208223
static Instruction *getInstructionByName(Function &F, StringRef Name) {
@@ -364,47 +379,6 @@ TEST_F(AliasAnalysisTest, PartialAliasOffsetSign) {
364379
EXPECT_EQ(AR, AliasResult::PartialAlias);
365380
EXPECT_EQ(-1, AR.getOffset());
366381
}
367-
368-
TEST_F(AliasAnalysisTest, IsNoAliasForInstructions) {
369-
// Create global variable
370-
auto *GlobalVar = new GlobalVariable(
371-
M, Type::getInt32Ty(C), false, GlobalValue::ExternalLinkage,
372-
ConstantInt::get(Type::getInt32Ty(C), 0), "g");
373-
GlobalVar->setAlignment(Align(4));
374-
375-
// Create function declarations
376-
FunctionType *VoidFnTy = FunctionType::get(Type::getVoidTy(C), false);
377-
Function::Create(VoidFnTy, Function::ExternalLinkage, "foo", M);
378-
Function::Create(VoidFnTy, Function::ExternalLinkage, "bar", M);
379-
380-
// Create test function
381-
FunctionType *TestFnTy = FunctionType::get(Type::getInt32Ty(C), false);
382-
Function *TestFn =
383-
Function::Create(TestFnTy, Function::ExternalLinkage, "test", M);
384-
385-
// Create basic block
386-
BasicBlock *BB = BasicBlock::Create(C, "entry", TestFn);
387-
388-
// Create instructions
389-
auto *Alloca = new AllocaInst(Type::getInt32Ty(C), 0, "p", BB);
390-
auto *Store1 =
391-
new StoreInst(ConstantInt::get(Type::getInt32Ty(C), 42), Alloca, BB);
392-
auto *Store2 =
393-
new StoreInst(ConstantInt::get(Type::getInt32Ty(C), 100), GlobalVar, BB);
394-
auto *Call1 = CallInst::Create(M.getFunction("foo"), {}, BB);
395-
auto *Call2 = CallInst::Create(M.getFunction("bar"), {}, BB);
396-
auto *Load = new LoadInst(Type::getInt32Ty(C), Alloca, "val", BB);
397-
ReturnInst::Create(C, Load, BB);
398-
399-
auto &AA = getAAResults(*TestFn);
400-
EXPECT_EQ(true, AA.isNoAlias(Store1, Store2));
401-
EXPECT_EQ(false, AA.isNoAlias(Store1, Call1));
402-
EXPECT_EQ(false, AA.isNoAlias(Store1, Load));
403-
EXPECT_EQ(false, AA.isNoAlias(Store2, Call1));
404-
EXPECT_EQ(false, AA.isNoAlias(Call1, Call2));
405-
EXPECT_EQ(true, AA.isNoAlias(Store2, Load));
406-
}
407-
408382
class AAPassInfraTest : public testing::Test {
409383
protected:
410384
LLVMContext C;

0 commit comments

Comments
 (0)