Index: test/CodeGen/inline-asm-attr.c =================================================================== --- test/CodeGen/inline-asm-attr.c (revision 0) +++ test/CodeGen/inline-asm-attr.c (revision 0) @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -O3 -emit-llvm %s -o - | FileCheck %s + +__attribute__((const)) +static inline void **varptr(void) { + void *ptr; + asm("mov $0x12345678, %0" : "=r" (ptr)); + return ptr; +} +static inline void *getvar(void) { return *varptr(); } +static inline void setvar(void *value) { *varptr() = value; } + +void fn(void) { +// CHECK: @fn +// CHECK: entry +// CHECK: tail call i8* asm +// CHECK: if.then +// CHECK-NOT: tail call i8* asm +// CHECK-NOT: far from pukin + if (getvar()) + setvar(0); +} Index: lib/CodeGen/CGStmt.cpp =================================================================== --- lib/CodeGen/CGStmt.cpp (revision 155999) +++ lib/CodeGen/CGStmt.cpp (working copy) @@ -1633,6 +1633,13 @@ S.isVolatile() || S.getNumOutputs() == 0); llvm::CallInst *Result = Builder.CreateCall(IA, Args); Result->addAttribute(~0, llvm::Attribute::NoUnwind); + + // Allow the inline assembly to inherit the ReadNone/ReadOnly attribute. + llvm::Function *Fn = Result->getParent()->getParent(); + if (Fn->hasFnAttr(llvm::Attribute::ReadNone)) + Result->addAttribute(~0, llvm::Attribute::ReadNone); + if (Fn->hasFnAttr(llvm::Attribute::ReadOnly)) + Result->addAttribute(~0, llvm::Attribute::ReadOnly); // Slap the source location of the inline asm into a !srcloc metadata on the // call.