Skip to content

Commit

Permalink
[FunctionAttrs] Remove readonly and writeonly assertion
Browse files Browse the repository at this point in the history
There are scenarios where mutually recursive functions may cause the SCC
to contain both read only and write only functions. This removes an
assertion when adding read attributes which caused a crash with a the
provided test case, and instead just doesn't add the attributes.

Patch by Luke Lau <luke.lau@intel.com>

Differential Revision: https://reviews.llvm.org/D60761

llvm-svn: 366090
  • Loading branch information
Johannes Doerfert committed Jul 15, 2019
1 parent 8e7eee6 commit 3dcd799
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 2 deletions.
7 changes: 5 additions & 2 deletions llvm/lib/Transforms/IPO/FunctionAttrs.cpp
Expand Up @@ -261,12 +261,15 @@ static bool addReadAttrs(const SCCNodeSet &SCCNodes, AARGetterT &&AARGetter) {
}
}

// If the SCC contains both functions that read and functions that write, then
// we cannot add readonly attributes.
if (ReadsMemory && WritesMemory)
return false;

// Success! Functions in this SCC do not access memory, or only read memory.
// Give them the appropriate attribute.
bool MadeChange = false;

assert(!(ReadsMemory && WritesMemory) &&
"Function marked read-only and write-only");
for (Function *F : SCCNodes) {
if (F->doesNotAccessMemory())
// Already perfect!
Expand Down
20 changes: 20 additions & 0 deletions llvm/test/Transforms/FunctionAttrs/read-write-scc.ll
@@ -0,0 +1,20 @@
; RUN: opt -S -functionattrs < %s | FileCheck %s
; RUN: opt -S -passes=function-attrs < %s | FileCheck %s

@i = global i32 0

define void @foo() {
; CHECK-LABEL: define void @foo() #0 {
store i32 1, i32* @i
call void @bar()
ret void
}

define void @bar() {
; CHECK-LABEL: define void @bar() #0 {
%i = load i32, i32* @i
call void @foo()
ret void
}

; CHECK: attributes #0 = { nofree nounwind }

0 comments on commit 3dcd799

Please sign in to comment.