[PATCH] D58694: LLVM: Optimization Pass: Function Attribute: No read-attribute should be added if the argument is WriteOnly
Anh Tuyen Tran via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Tue Feb 26 12:45:00 PST 2019
anhtuyen created this revision.
anhtuyen added reviewers: nicholas, rnk, chandlerc, majnemer.
anhtuyen added a project: LLVM.
Herald added subscribers: llvm-commits, jdoerfert, hiraditya.
Update optimization pass to fix attribute deduction error
When determining read attributes for pointer arguments, the attribute **readnone** will be deduced/added to an argument even if the argument was explicitly marked **writeonly**. This deduction of the attribute caused an incompatible error. Despite its name, the **readnone** attribute has implied semantics about write operations: "If a function reads from or writes to a readnone pointer argument, the behavior is undefined." This explains why the two attributes **readnone** and **writeonly** are considered incompatible.
This can be demonstrated via the following snippet.
$ cat x.ll
; ModuleID = 'x.bc'
%_type_of_d-ccc = type <{ i8*, i8, i8, i8, i8 }>
@d-ccc = internal global %_type_of_d-ccc <{ i8* null, i8 1, i8 13, i8 0, i8 -127 }>, align 8
define void @foo(i32* writeonly %.aaa) {
foo_entry:
%_param_.aaa = alloca i32*, align 8
store i32* %.aaa, i32** %_param_.aaa, align 8
store i8 0, i8* getelementptr inbounds (%_type_of_d-ccc, %_type_of_d-ccc* @d-ccc, i32 0, i32 3)
ret void
}
$ opt -O3 x.ll
Attributes 'readnone and writeonly' are incompatible!
void (i32*)* @foo
in function foo
LLVM ERROR: Broken function found, compilation aborted!
The purpose of this changeset is to fix the above error.
Repository:
rL LLVM
https://reviews.llvm.org/D58694
Files:
llvm/lib/Transforms/IPO/FunctionAttrs.cpp
llvm/test/Transforms/FunctionAttrs/writeonly.ll
Index: llvm/test/Transforms/FunctionAttrs/writeonly.ll
===================================================================
--- /dev/null
+++ llvm/test/Transforms/FunctionAttrs/writeonly.ll
@@ -0,0 +1,16 @@
+; RUN: opt < %s -O1 -S | FileCheck %s
+; RUN: opt < %s -O2 -S | FileCheck %s
+; RUN: opt < %s -O3 -S | FileCheck %s
+
+%_type = type <{ i8*, i8, i8, i8, i8 }>
+
+ at d = internal global %_type <{ i8* null, i8 1, i8 13, i8 0, i8 -127 }>, align 8
+
+; CHECK: define void @foo(i32* nocapture writeonly %.aaa)
+define void @foo(i32* writeonly %.aaa) {
+foo_entry:
+ %_param_.aaa = alloca i32*, align 8
+ store i32* %.aaa, i32** %_param_.aaa, align 8
+ store i8 0, i8* getelementptr inbounds (%_type, %_type* @d, i32 0, i32 3)
+ ret void
+}
Index: llvm/lib/Transforms/IPO/FunctionAttrs.cpp
===================================================================
--- llvm/lib/Transforms/IPO/FunctionAttrs.cpp
+++ llvm/lib/Transforms/IPO/FunctionAttrs.cpp
@@ -445,6 +445,10 @@
if (A->hasInAllocaAttr())
return Attribute::None;
+ // If the argument is WriteOnly, no read-attribute should be added.
+ if (A->hasAttribute(Attribute::WriteOnly))
+ return Attribute::None;
+
bool IsRead = false;
// We don't need to track IsWritten. If A is written to, return immediately.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D58694.188436.patch
Type: text/x-patch
Size: 1288 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190226/7b2312ba/attachment.bin>
More information about the llvm-commits
mailing list