[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