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,20 @@ +// 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 + if (getvar()) + setvar(0); +} Index: lib/CodeGen/CGStmt.cpp =================================================================== --- lib/CodeGen/CGStmt.cpp (revision 155999) +++ lib/CodeGen/CGStmt.cpp (working copy) @@ -1595,11 +1595,14 @@ Constraints += InOutConstraints; // Clobbers + bool ClobbersOnlyRegisters = true; for (unsigned i = 0, e = S.getNumClobbers(); i != e; i++) { StringRef Clobber = S.getClobber(i)->getString(); if (Clobber != "memory" && Clobber != "cc") - Clobber = Target.getNormalizedGCCRegisterName(Clobber); + Clobber = Target.getNormalizedGCCRegisterName(Clobber); + else + ClobbersOnlyRegisters = false; if (i != 0 || NumConstraints != 0) Constraints += ','; @@ -1634,6 +1637,11 @@ llvm::CallInst *Result = Builder.CreateCall(IA, Args); Result->addAttribute(~0, llvm::Attribute::NoUnwind); + // An inline asm can be marked readonly if it doesn't clobber memory/cc and it + // isn't volatile. + if (ClobbersOnlyRegisters && !S.isVolatile()) + Result->addAttribute(~0, llvm::Attribute::ReadOnly); + // Slap the source location of the inline asm into a !srcloc metadata on the // call. Result->setMetadata("srcloc", getAsmSrcLocInfo(S.getAsmString(), *this));