From 136d97ecc48e939686f6750d532ed06c080adcde Mon Sep 17 00:00:00 2001 From: Daniel Neilson Date: Wed, 30 May 2018 14:43:39 +0000 Subject: [PATCH] [AliasSet] Teach the alias set how to handle atomic memcpy/memmove/memset Summary: The atomic variants of the memcpy/memmove/memset intrinsics can be treated the same was as the regular forms, with respect to aliasing. Update the AliasSetTracker to treat the atomic forms the same was as the regular forms. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@333551 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Analysis/AliasSetTracker.h | 8 +-- lib/Analysis/AliasSetTracker.cpp | 19 +++--- test/Analysis/AliasSet/memtransfer.ll | 77 +++++++++++++++++++++++++ 3 files changed, 92 insertions(+), 12 deletions(-) diff --git a/include/llvm/Analysis/AliasSetTracker.h b/include/llvm/Analysis/AliasSetTracker.h index 2a11d64f042..c9680ff40d1 100644 --- a/include/llvm/Analysis/AliasSetTracker.h +++ b/include/llvm/Analysis/AliasSetTracker.h @@ -37,8 +37,8 @@ namespace llvm { class AliasSetTracker; class BasicBlock; class LoadInst; -class MemSetInst; -class MemTransferInst; +class AnyMemSetInst; +class AnyMemTransferInst; class raw_ostream; class StoreInst; class VAArgInst; @@ -367,8 +367,8 @@ public: void add(LoadInst *LI); void add(StoreInst *SI); void add(VAArgInst *VAAI); - void add(MemSetInst *MSI); - void add(MemTransferInst *MTI); + void add(AnyMemSetInst *MSI); + void add(AnyMemTransferInst *MTI); void add(Instruction *I); // Dispatch to one of the other add methods... void add(BasicBlock &BB); // Add all instructions in basic block void add(const AliasSetTracker &AST); // Add alias relations from another AST diff --git a/lib/Analysis/AliasSetTracker.cpp b/lib/Analysis/AliasSetTracker.cpp index e4b805aca91..7ed23af5589 100644 --- a/lib/Analysis/AliasSetTracker.cpp +++ b/lib/Analysis/AliasSetTracker.cpp @@ -389,7 +389,7 @@ void AliasSetTracker::add(VAArgInst *VAAI) { AliasSet::ModRefAccess); } -void AliasSetTracker::add(MemSetInst *MSI) { +void AliasSetTracker::add(AnyMemSetInst *MSI) { AAMDNodes AAInfo; MSI->getAAMetadata(AAInfo); @@ -402,11 +402,12 @@ void AliasSetTracker::add(MemSetInst *MSI) { AliasSet &AS = addPointer(MSI->getRawDest(), Len, AAInfo, AliasSet::ModAccess); - if (MSI->isVolatile()) + auto *MS = dyn_cast(MSI); + if (MS && MS->isVolatile()) AS.setVolatile(); } -void AliasSetTracker::add(MemTransferInst *MTI) { +void AliasSetTracker::add(AnyMemTransferInst *MTI) { AAMDNodes AAInfo; MTI->getAAMetadata(AAInfo); @@ -418,13 +419,15 @@ void AliasSetTracker::add(MemTransferInst *MTI) { AliasSet &ASSrc = addPointer(MTI->getRawSource(), Len, AAInfo, AliasSet::RefAccess); - if (MTI->isVolatile()) - ASSrc.setVolatile(); AliasSet &ASDst = addPointer(MTI->getRawDest(), Len, AAInfo, AliasSet::ModAccess); - if (MTI->isVolatile()) + + auto* MT = dyn_cast(MTI); + if (MT && MT->isVolatile()) { + ASSrc.setVolatile(); ASDst.setVolatile(); + } } void AliasSetTracker::addUnknown(Instruction *Inst) { @@ -464,9 +467,9 @@ void AliasSetTracker::add(Instruction *I) { return add(SI); if (VAArgInst *VAAI = dyn_cast(I)) return add(VAAI); - if (MemSetInst *MSI = dyn_cast(I)) + if (AnyMemSetInst *MSI = dyn_cast(I)) return add(MSI); - if (MemTransferInst *MTI = dyn_cast(I)) + if (AnyMemTransferInst *MTI = dyn_cast(I)) return add(MTI); return addUnknown(I); } diff --git a/test/Analysis/AliasSet/memtransfer.ll b/test/Analysis/AliasSet/memtransfer.ll index c1940fcd8cd..0d7e601a8f5 100644 --- a/test/Analysis/AliasSet/memtransfer.ll +++ b/test/Analysis/AliasSet/memtransfer.ll @@ -19,6 +19,22 @@ entry: ret void } +; CHECK: Alias sets for function 'test1_atomic': +; CHECK: Alias Set Tracker: 3 alias sets for 4 pointer values. +; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (i8* %a, 1) +; CHECK-NOT: 1 Unknown instructions +; CHECK: AliasSet[0x{{[0-9a-f]+}}, 2] may alias, Mod/Ref Pointers: (i8* %s, 1), (i8* %d, 1) +; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (i8* %b, 1) +define void @test1_atomic(i8* %s, i8* %d) { +entry: + %a = alloca i8, align 1 + %b = alloca i8, align 1 + store atomic i8 1, i8* %a unordered, align 1 + call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %d, i8* align 1 %s, i64 1, i32 1) + store atomic i8 1, i8* %b unordered, align 1 + ret void +} + ; CHECK: Alias sets for function 'test2': ; CHECK: Alias Set Tracker: 3 alias sets for 4 pointer values. ; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (i8* %a, 1) @@ -51,6 +67,22 @@ entry: ret void } +; CHECK: Alias sets for function 'test3_atomic': +; CHECK: Alias Set Tracker: 3 alias sets for 4 pointer values. +; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (i8* %a, 1) +; CHECK-NOT: 1 Unknown instructions +; CHECK: AliasSet[0x{{[0-9a-f]+}}, 2] may alias, Mod/Ref Pointers: (i8* %s, 1), (i8* %d, 1) +; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (i8* %b, 1) +define void @test3_atomic(i8* %s, i8* %d) { +entry: + %a = alloca i8, align 1 + %b = alloca i8, align 1 + store atomic i8 1, i8* %a unordered, align 1 + call void @llvm.memmove.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %d, i8* align 1 %s, i64 1, i32 1) + store atomic i8 1, i8* %b unordered, align 1 + ret void +} + ; CHECK: Alias sets for function 'test4': ; CHECK: Alias Set Tracker: 3 alias sets for 4 pointer values. ; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (i8* %a, 1) @@ -81,6 +113,20 @@ entry: ret void } +; CHECK: Alias sets for function 'test5_atomic': +; CHECK: Alias Set Tracker: 2 alias sets for 2 pointer values. +; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod/Ref Pointers: (i8* %a, 1) +; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (i8* %b, 1) +define void @test5_atomic() { +entry: + %a = alloca i8, align 1 + %b = alloca i8, align 1 + store atomic i8 1, i8* %a unordered, align 1 + call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %b, i8* align 1 %a, i64 1, i32 1) + store atomic i8 1, i8* %b unordered, align 1 + ret void +} + ; CHECK: Alias sets for function 'test6': ; CHECK: Alias Set Tracker: 2 alias sets for 2 pointer values. ; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod/Ref Pointers: (i8* %a, 1) @@ -95,6 +141,20 @@ entry: ret void } +; CHECK: Alias sets for function 'test6_atomic': +; CHECK: Alias Set Tracker: 2 alias sets for 2 pointer values. +; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod/Ref Pointers: (i8* %a, 1) +; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (i8* %b, 1) +define void @test6_atomic() { +entry: + %a = alloca i8, align 1 + %b = alloca i8, align 1 + store atomic i8 1, i8* %a unordered, align 1 + call void @llvm.memmove.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %b, i8* align 1 %a, i64 1, i32 1) + store atomic i8 1, i8* %b unordered, align 1 + ret void +} + ; CHECK: Alias sets for function 'test7': ; CHECK: Alias Set Tracker: 2 alias sets for 2 pointer values. ; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod/Ref Pointers: (i8* %a, 1) @@ -110,5 +170,22 @@ entry: ret void } +; CHECK: Alias sets for function 'test7_atomic': +; CHECK: Alias Set Tracker: 2 alias sets for 2 pointer values. +; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod/Ref Pointers: (i8* %a, 1) +; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod/Ref Pointers: (i8* %b, 1) +define void @test7_atomic() { +entry: + %a = alloca i8, align 1 + %b = alloca i8, align 1 + store atomic i8 1, i8* %a unordered, align 1 + call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %b, i8* align 1 %a, i64 1, i32 1) + call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %a, i8* align 1 %b, i64 1, i32 1) + store atomic i8 1, i8* %b unordered, align 1 + ret void +} + declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture writeonly, i8* nocapture readonly, i64, i1) +declare void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* nocapture writeonly, i8* nocapture readonly, i64, i32) declare void @llvm.memmove.p0i8.p0i8.i64(i8* nocapture, i8* nocapture readonly, i64, i1) +declare void @llvm.memmove.element.unordered.atomic.p0i8.p0i8.i64(i8* nocapture writeonly, i8* nocapture readonly, i64, i32)