OSDN Git Service

[FunctionAttrs] Remove readonly and writeonly assertion
authorJohannes Doerfert <jdoerfert@anl.gov>
Mon, 15 Jul 2019 17:31:26 +0000 (17:31 +0000)
committerJohannes Doerfert <jdoerfert@anl.gov>
Mon, 15 Jul 2019 17:31:26 +0000 (17:31 +0000)
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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@366090 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/IPO/FunctionAttrs.cpp
test/Transforms/FunctionAttrs/read-write-scc.ll [new file with mode: 0644]

index cfae267..5ccd8bc 100644 (file)
@@ -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!
diff --git a/test/Transforms/FunctionAttrs/read-write-scc.ll b/test/Transforms/FunctionAttrs/read-write-scc.ll
new file mode 100644 (file)
index 0000000..319aaf0
--- /dev/null
@@ -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 }