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. 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 }> + +@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 +}