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
}
}
+ // 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!
--- /dev/null
+; 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 }