The attached patches (one for clang and another for llvm) add support for the 
const type-qualifier for inline assembly.

The syntax is the same as when using the volatile keyword:

asm const("mov $0x0, %0" : "=r" (ptr));

Here is what the resulting IR looks like:
%0 = tail call i8* asm constant "mov $$0x12345678, $0", 
"=r,~{dirflag},~{fpsr},~{flags}"() nounwind readnone

Note that the constant keyword as been added as well as the call has been 
marked as readnone.  The former indicates the inline assembly has no effects 
except the return value.  The readnone attribute allows CSE to eliminate 
redundant inline assembly calls that have been marked const (see test cases).

The patch makes changes to the clang parser, llvm asm parser/writer, as well as 
the bitcode reader/writer (without breaking backward compatibility).

 Chad

Index: test/CodeGen/asm-const-type-qualifier.c
===================================================================
--- test/CodeGen/asm-const-type-qualifier.c     (revision 0)
+++ test/CodeGen/asm-const-type-qualifier.c     (revision 0)
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -O3 -triple x86_64-apple-darwin10 -emit-llvm %s -o - | 
FileCheck %s
+
+void **foo(void) {
+    void *ptr;
+    asm const("mov $0x12345678, %0" : "=r" (ptr));
+    return ptr;
+}
+// Check for the constant type-qualifier and readnone attribute
+// CHECK: @foo
+// CHECK: entry:
+// CHECK: call i8* asm constant "mov $$0x12345678, $0", 
"=r,~{dirflag},~{fpsr},~{flags}"() nounwind readnone
+// CHECK: ret
+
+static inline void **varptr(void) {
+    void *ptr;
+    asm const("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) { if (getvar()) setvar(0); }
+
+// Check to see if the second inline asm is CSE'ed after inlining
+// CHECK: @fn
+// CHECK: entry:
+// CHECK: call i8* asm constant "mov $$0x12345678, $0", 
"=r,~{dirflag},~{fpsr},~{flags}"() nounwind readnone
+// CHECK-NOT: call i8* asm constant "mov $$0x12345678, $0", 
"=r,~{dirflag},~{fpsr},~{flags}"() nounwind readnone
+// CHECK: ret
+
Index: include/clang/Sema/Sema.h
===================================================================
--- include/clang/Sema/Sema.h   (revision 156383)
+++ include/clang/Sema/Sema.h   (working copy)
@@ -2490,7 +2490,7 @@
   StmtResult ActOnCapScopeReturnStmt(SourceLocation ReturnLoc, Expr 
*RetValExp);
 
   StmtResult ActOnAsmStmt(SourceLocation AsmLoc,
-                          bool IsSimple, bool IsVolatile,
+                          bool IsSimple, bool IsVolatile, bool IsConst,
                           unsigned NumOutputs, unsigned NumInputs,
                           IdentifierInfo **Names,
                           MultiExprArg Constraints,
Index: include/clang/AST/Stmt.h
===================================================================
--- include/clang/AST/Stmt.h    (revision 156383)
+++ include/clang/AST/Stmt.h    (working copy)
@@ -1366,6 +1366,7 @@
 
   bool IsSimple;
   bool IsVolatile;
+  bool IsConst;
   bool MSAsm;
 
   unsigned NumOutputs;
@@ -1380,7 +1381,7 @@
 
 public:
   AsmStmt(ASTContext &C, SourceLocation asmloc, bool issimple, bool isvolatile,
-          bool msasm, unsigned numoutputs, unsigned numinputs,
+          bool isconst, bool msasm, unsigned numoutputs, unsigned numinputs,
           IdentifierInfo **names, StringLiteral **constraints,
           Expr **exprs, StringLiteral *asmstr, unsigned numclobbers,
           StringLiteral **clobbers, SourceLocation rparenloc);
@@ -1396,6 +1397,8 @@
 
   bool isVolatile() const { return IsVolatile; }
   void setVolatile(bool V) { IsVolatile = V; }
+  bool isConst() const { return IsConst; }
+  void setConst(bool C) { IsConst = C; }
   bool isSimple() const { return IsSimple; }
   void setSimple(bool V) { IsSimple = V; }
   bool isMSAsm() const { return MSAsm; }
Index: lib/Sema/TreeTransform.h
===================================================================
--- lib/Sema/TreeTransform.h    (revision 156383)
+++ lib/Sema/TreeTransform.h    (working copy)
@@ -1164,6 +1164,7 @@
   StmtResult RebuildAsmStmt(SourceLocation AsmLoc,
                                   bool IsSimple,
                                   bool IsVolatile,
+                                  bool IsConst,
                                   unsigned NumOutputs,
                                   unsigned NumInputs,
                                   IdentifierInfo **Names,
@@ -1173,9 +1174,9 @@
                                   MultiExprArg Clobbers,
                                   SourceLocation RParenLoc,
                                   bool MSAsm) {
-    return getSema().ActOnAsmStmt(AsmLoc, IsSimple, IsVolatile, NumOutputs, 
-                                  NumInputs, Names, move(Constraints),
-                                  Exprs, AsmString, Clobbers,
+    return getSema().ActOnAsmStmt(AsmLoc, IsSimple, IsVolatile, IsConst,
+                                  NumOutputs, NumInputs, Names, 
+                                  move(Constraints), Exprs, AsmString, 
Clobbers,
                                   RParenLoc, MSAsm);
   }
 
@@ -5591,6 +5592,7 @@
   return getDerived().RebuildAsmStmt(S->getAsmLoc(),
                                      S->isSimple(),
                                      S->isVolatile(),
+                                     S->isConst(),
                                      S->getNumOutputs(),
                                      S->getNumInputs(),
                                      Names.data(),
Index: lib/Sema/SemaStmt.cpp
===================================================================
--- lib/Sema/SemaStmt.cpp       (revision 156383)
+++ lib/Sema/SemaStmt.cpp       (working copy)
@@ -2420,7 +2420,7 @@
 }
 
 StmtResult Sema::ActOnAsmStmt(SourceLocation AsmLoc, bool IsSimple,
-                              bool IsVolatile, unsigned NumOutputs,
+                              bool IsVolatile, bool IsConst,unsigned 
NumOutputs,
                               unsigned NumInputs, IdentifierInfo **Names,
                               MultiExprArg constraints, MultiExprArg exprs,
                               Expr *asmString, MultiExprArg clobbers,
@@ -2529,7 +2529,7 @@
   }
 
   AsmStmt *NS =
-    new (Context) AsmStmt(Context, AsmLoc, IsSimple, IsVolatile, MSAsm,
+    new (Context) AsmStmt(Context, AsmLoc, IsSimple, IsVolatile, IsConst, 
MSAsm,
                           NumOutputs, NumInputs, Names, Constraints, Exprs,
                           AsmString, NumClobbers, Clobbers, RParenLoc);
   // Validate the asm string, ensuring it makes sense given the operands we
Index: lib/AST/Stmt.cpp
===================================================================
--- lib/AST/Stmt.cpp    (revision 156383)
+++ lib/AST/Stmt.cpp    (working copy)
@@ -526,13 +526,13 @@
 
//===----------------------------------------------------------------------===//
 
 AsmStmt::AsmStmt(ASTContext &C, SourceLocation asmloc, bool issimple, 
-                 bool isvolatile, bool msasm, 
+                 bool isvolatile, bool isconst, bool msasm, 
                  unsigned numoutputs, unsigned numinputs,
                  IdentifierInfo **names, StringLiteral **constraints,
                  Expr **exprs, StringLiteral *asmstr, unsigned numclobbers,
                  StringLiteral **clobbers, SourceLocation rparenloc)
   : Stmt(AsmStmtClass), AsmLoc(asmloc), RParenLoc(rparenloc), AsmStr(asmstr)
-  , IsSimple(issimple), IsVolatile(isvolatile), MSAsm(msasm)
+  , IsSimple(issimple), IsVolatile(isvolatile), IsConst(isconst), MSAsm(msasm)
   , NumOutputs(numoutputs), NumInputs(numinputs), NumClobbers(numclobbers) {
 
   unsigned NumExprs = NumOutputs +NumInputs;
Index: lib/CodeGen/CGStmt.cpp
===================================================================
--- lib/CodeGen/CGStmt.cpp      (revision 156383)
+++ lib/CodeGen/CGStmt.cpp      (working copy)
@@ -1630,9 +1630,12 @@
 
   llvm::InlineAsm *IA =
     llvm::InlineAsm::get(FTy, AsmString, Constraints,
-                         S.isVolatile() || S.getNumOutputs() == 0);
+                         S.isVolatile() || S.getNumOutputs() == 0, 
+                         /* isAlignStack */false, S.isConst());
   llvm::CallInst *Result = Builder.CreateCall(IA, Args);
   Result->addAttribute(~0, llvm::Attribute::NoUnwind);
+  if (S.isConst())
+    Result->addAttribute(~0, llvm::Attribute::ReadNone);
 
   // Slap the source location of the inline asm into a !srcloc metadata on the
   // call.
Index: lib/Parse/ParseStmt.cpp
===================================================================
--- lib/Parse/ParseStmt.cpp     (revision 156383)
+++ lib/Parse/ParseStmt.cpp     (working copy)
@@ -1733,7 +1733,7 @@
   ExprVector Constraints(Actions);
   ExprVector Exprs(Actions);
   ExprVector Clobbers(Actions);
-  return Actions.ActOnAsmStmt(AsmLoc, true, true, 0, 0, 0,
+  return Actions.ActOnAsmStmt(AsmLoc, true, true, false, 0, 0, 0,
                               move_arg(Constraints), move_arg(Exprs),
                               AsmString.take(), move_arg(Clobbers),
                               EndLoc, true);
@@ -1783,12 +1783,12 @@
   ParseTypeQualifierListOpt(DS, true, false);
 
   // GNU asms accept, but warn, about type-qualifiers other than volatile.
-  if (DS.getTypeQualifiers() & DeclSpec::TQ_const)
-    Diag(Loc, diag::w_asm_qualifier_ignored) << "const";
+  // However, clang does support the const type-qualifier.
   if (DS.getTypeQualifiers() & DeclSpec::TQ_restrict)
     Diag(Loc, diag::w_asm_qualifier_ignored) << "restrict";
 
-  // Remember if this was a volatile asm.
+  // Remember if this was a const/volatile asm.
+  bool isConst = DS.getTypeQualifiers() & DeclSpec::TQ_const;
   bool isVolatile = DS.getTypeQualifiers() & DeclSpec::TQ_volatile;
   if (Tok.isNot(tok::l_paren)) {
     Diag(Tok, diag::err_expected_lparen_after) << "asm";
@@ -1813,7 +1813,7 @@
   if (Tok.is(tok::r_paren)) {
     // We have a simple asm expression like 'asm("foo")'.
     T.consumeClose();
-    return Actions.ActOnAsmStmt(AsmLoc, /*isSimple*/ true, isVolatile,
+    return Actions.ActOnAsmStmt(AsmLoc, /*isSimple*/ true, isVolatile, isConst,
                                 /*NumOutputs*/ 0, /*NumInputs*/ 0, 0,
                                 move_arg(Constraints), move_arg(Exprs),
                                 AsmString.take(), move_arg(Clobbers),
@@ -1878,7 +1878,7 @@
   }
 
   T.consumeClose();
-  return Actions.ActOnAsmStmt(AsmLoc, false, isVolatile,
+  return Actions.ActOnAsmStmt(AsmLoc, false, isVolatile, isConst,
                               NumOutputs, NumInputs, Names.data(),
                               move_arg(Constraints), move_arg(Exprs),
                               AsmString.take(), move_arg(Clobbers),
Index: test/Transforms/EarlyCSE/asm-const-type-qualifier.ll
===================================================================
--- test/Transforms/EarlyCSE/asm-const-type-qualifier.ll        (revision 0)
+++ test/Transforms/EarlyCSE/asm-const-type-qualifier.ll        (revision 0)
@@ -0,0 +1,24 @@
+; RUN: opt < %s -S -early-cse | FileCheck %s
+
+; Check to make sure the second inline asm is CSE'ed.
+; CHECK: @fn
+; CHECK: %0 = tail call i8* asm constant "mov $$0x12345678, $0", 
"=r,~{dirflag},~{fpsr},~{flags}"() nounwind readnone
+; CHECK-NOT: call i8* asm constant "mov $$0x12345678, $0", 
"=r,~{dirflag},~{fpsr},~{flags}"() nounwind readnone
+define void @fn() nounwind ssp {
+entry:
+  %0 = tail call i8* asm constant "mov $$0x12345678, $0", 
"=r,~{dirflag},~{fpsr},~{flags}"() nounwind readnone
+  %1 = bitcast i8* %0 to i8**
+  %2 = load i8** %1, align 8
+  %tobool = icmp eq i8* %2, null
+  br i1 %tobool, label %if.end, label %if.then
+
+if.then:                                          ; preds = %entry
+  %3 = tail call i8* asm constant "mov $$0x12345678, $0", 
"=r,~{dirflag},~{fpsr},~{flags}"() nounwind readnone
+  %4 = bitcast i8* %3 to i8**
+  store i8* null, i8** %4, align 8
+  br label %if.end
+
+if.end:                                           ; preds = %entry, %if.then
+  ret void
+}
+
Index: test/Assembler/alignstack.ll
===================================================================
--- test/Assembler/alignstack.ll        (revision 156383)
+++ test/Assembler/alignstack.ll        (working copy)
@@ -5,6 +5,7 @@
 define void @test1() nounwind {
 ; CHECK: test1
 ; CHECK: sideeffect
+; CHECK-NOT: constant
 ; CHECK-NOT: alignstack
        tail call void asm sideeffect "mov", "~{dirflag},~{fpsr},~{flags}"() 
nounwind
        ret void
@@ -13,6 +14,7 @@
 define void @test2() nounwind {
 ; CHECK: test2
 ; CHECK: sideeffect
+; CHECK-NOT: constant
 ; CHECK: alignstack
        tail call void asm sideeffect alignstack "mov", 
"~{dirflag},~{fpsr},~{flags}"() nounwind
        ret void
@@ -21,6 +23,7 @@
 define void @test3() nounwind {
 ; CHECK: test3
 ; CHECK-NOT: sideeffect
+; CHECK-NOT: constant
 ; CHECK: alignstack
        tail call void asm alignstack "mov", "~{dirflag},~{fpsr},~{flags}"() 
nounwind
        ret void
@@ -29,8 +32,27 @@
 define void @test4() nounwind {
 ; CHECK: test4
 ; CHECK-NOT: sideeffect
+; CHECK-NOT: constant
 ; CHECK-NOT: alignstack
        tail call void asm  "mov", "~{dirflag},~{fpsr},~{flags}"() nounwind
        ret void
 ; CHECK: ret
 }
+define void @test5() nounwind {
+; CHECK: test5
+; CHECK-NOT: sideeffect
+; CHECK: constant
+; CHECK-NOT: alignstack
+       tail call void asm constant "mov", "~{dirflag},~{fpsr},~{flags}"() 
nounwind readnone
+       ret void
+; CHECK: ret
+}
+define void @test6() nounwind {
+; CHECK: test6
+; CHECK-NOT: sideeffect
+; CHECK: constant
+; CHECK: alignstack
+       tail call void asm constant alignstack "mov", 
"~{dirflag},~{fpsr},~{flags}"() nounwind readnone
+       ret void
+; CHECK: ret
+}
Index: include/llvm/InlineAsm.h
===================================================================
--- include/llvm/InlineAsm.h    (revision 156383)
+++ include/llvm/InlineAsm.h    (working copy)
@@ -43,10 +43,11 @@
   std::string AsmString, Constraints;
   bool HasSideEffects;
   bool IsAlignStack;
-  
+  bool IsConst;
+
   InlineAsm(PointerType *Ty, const std::string &AsmString,
             const std::string &Constraints, bool hasSideEffects,
-            bool isAlignStack);
+            bool isAlignStack, bool isConst);
   virtual ~InlineAsm();
 
   /// When the ConstantUniqueMap merges two types and makes two InlineAsms
@@ -58,10 +59,11 @@
   ///
   static InlineAsm *get(FunctionType *Ty, StringRef AsmString,
                         StringRef Constraints, bool hasSideEffects,
-                        bool isAlignStack = false);
+                        bool isAlignStack = false, bool isConst = false);
   
   bool hasSideEffects() const { return HasSideEffects; }
   bool isAlignStack() const { return IsAlignStack; }
+  bool isConst() const { return IsConst; }
   
   /// getType - InlineAsm's are always pointers.
   ///
@@ -193,17 +195,18 @@
     Op_InputChain = 0,
     Op_AsmString = 1,
     Op_MDNode = 2,
-    Op_ExtraInfo = 3,    // HasSideEffects, IsAlignStack
+    Op_ExtraInfo = 3,    // HasSideEffects, IsAlignStack, IsConst
     Op_FirstOperand = 4,
 
     // Fixed operands on an INLINEASM MachineInstr.
     MIOp_AsmString = 0,
-    MIOp_ExtraInfo = 1,    // HasSideEffects, IsAlignStack
+    MIOp_ExtraInfo = 1,    // HasSideEffects, IsAlignStack, IsConst
     MIOp_FirstOperand = 2,
 
     // Interpretation of the MIOp_ExtraInfo bit field.
     Extra_HasSideEffects = 1,
     Extra_IsAlignStack = 2,
+    Extra_IsConst = 3,
 
     // Inline asm operands map to multiple SDNode / MachineInstr operands.
     // The first operand is an immediate describing the asm operand, the low
Index: lib/VMCore/AsmWriter.cpp
===================================================================
--- lib/VMCore/AsmWriter.cpp    (revision 156383)
+++ lib/VMCore/AsmWriter.cpp    (working copy)
@@ -1014,6 +1014,8 @@
     Out << "asm ";
     if (IA->hasSideEffects())
       Out << "sideeffect ";
+    if (IA->isConst())
+      Out << "constant ";
     if (IA->isAlignStack())
       Out << "alignstack ";
     Out << '"';
Index: lib/VMCore/InlineAsm.cpp
===================================================================
--- lib/VMCore/InlineAsm.cpp    (revision 156383)
+++ lib/VMCore/InlineAsm.cpp    (working copy)
@@ -27,19 +27,20 @@
 
 InlineAsm *InlineAsm::get(FunctionType *Ty, StringRef AsmString,
                           StringRef Constraints, bool hasSideEffects,
-                          bool isAlignStack) {
-  InlineAsmKeyType Key(AsmString, Constraints, hasSideEffects, isAlignStack);
+                          bool isAlignStack, bool isConst) {
+  InlineAsmKeyType Key(AsmString, Constraints, hasSideEffects, isAlignStack,
+                       isConst);
   LLVMContextImpl *pImpl = Ty->getContext().pImpl;
   return pImpl->InlineAsms.getOrCreate(PointerType::getUnqual(Ty), Key);
 }
 
 InlineAsm::InlineAsm(PointerType *Ty, const std::string &asmString,
                      const std::string &constraints, bool hasSideEffects,
-                     bool isAlignStack)
+                     bool isAlignStack, bool isConst)
   : Value(Ty, Value::InlineAsmVal),
     AsmString(asmString), 
-    Constraints(constraints), HasSideEffects(hasSideEffects), 
-    IsAlignStack(isAlignStack) {
+    Constraints(constraints), HasSideEffects(hasSideEffects),
+    IsAlignStack(isAlignStack), IsConst(isConst) {
 
   // Do various checks on the constraint string and type.
   assert(Verify(getFunctionType(), constraints) &&
Index: lib/VMCore/ConstantsContext.h
===================================================================
--- lib/VMCore/ConstantsContext.h       (revision 156383)
+++ lib/VMCore/ConstantsContext.h       (working copy)
@@ -352,18 +352,21 @@
 struct InlineAsmKeyType {
   InlineAsmKeyType(StringRef AsmString,
                    StringRef Constraints, bool hasSideEffects,
-                   bool isAlignStack)
+                   bool isAlignStack, bool isConst)
     : asm_string(AsmString), constraints(Constraints),
-      has_side_effects(hasSideEffects), is_align_stack(isAlignStack) {}
+      has_side_effects(hasSideEffects), is_align_stack(isAlignStack),
+      is_const(isConst) {}
   std::string asm_string;
   std::string constraints;
   bool has_side_effects;
   bool is_align_stack;
+  bool is_const;
   bool operator==(const InlineAsmKeyType& that) const {
     return this->asm_string == that.asm_string &&
            this->constraints == that.constraints &&
            this->has_side_effects == that.has_side_effects &&
-           this->is_align_stack == that.is_align_stack;
+           this->is_align_stack == that.is_align_stack &&
+           this->is_const == that.is_const;
   }
   bool operator<(const InlineAsmKeyType& that) const {
     if (this->asm_string != that.asm_string)
@@ -374,6 +377,8 @@
       return this->has_side_effects < that.has_side_effects;
     if (this->is_align_stack != that.is_align_stack)
       return this->is_align_stack < that.is_align_stack;
+    if (this->is_const != that.is_const)
+      return this->is_const < that.is_const;
     return false;
   }
 
@@ -490,7 +495,7 @@
 struct ConstantCreator<InlineAsm, PointerType, InlineAsmKeyType> {
   static InlineAsm *create(PointerType *Ty, const InlineAsmKeyType &Key) {
     return new InlineAsm(Ty, Key.asm_string, Key.constraints,
-                         Key.has_side_effects, Key.is_align_stack);
+                         Key.has_side_effects, 
Key.is_align_stack,Key.is_const);
   }
 };
 
@@ -499,7 +504,8 @@
   typedef InlineAsmKeyType ValType;
   static ValType getValType(InlineAsm *Asm) {
     return InlineAsmKeyType(Asm->getAsmString(), Asm->getConstraintString(),
-                            Asm->hasSideEffects(), Asm->isAlignStack());
+                            Asm->hasSideEffects(), Asm->isAlignStack(),
+                            Asm->isConst());
   }
 };
 
Index: lib/AsmParser/LLParser.cpp
===================================================================
--- lib/AsmParser/LLParser.cpp  (revision 156383)
+++ lib/AsmParser/LLParser.cpp  (working copy)
@@ -2025,17 +2025,20 @@
     return false;
 
   case lltok::kw_asm: {
-    // ValID ::= 'asm' SideEffect? AlignStack? STRINGCONSTANT ',' 
STRINGCONSTANT
-    bool HasSideEffect, AlignStack;
+    // ValID ::= 'asm' [SideEffect|IsConst]? AlignStack? STRINGCONSTANT ','
+    //                                                     STRINGCONSTANT
+    bool HasSideEffect, AlignStack, IsConst;
     Lex.Lex();
     if (ParseOptionalToken(lltok::kw_sideeffect, HasSideEffect) ||
+        ParseOptionalToken(lltok::kw_constant, IsConst) ||
         ParseOptionalToken(lltok::kw_alignstack, AlignStack) ||
         ParseStringConstant(ID.StrVal) ||
         ParseToken(lltok::comma, "expected comma in inline asm expression") ||
         ParseToken(lltok::StringConstant, "expected constraint string"))
       return true;
     ID.StrVal2 = Lex.getStrVal();
-    ID.UIntVal = unsigned(HasSideEffect) | (unsigned(AlignStack)<<1);
+    ID.UIntVal = unsigned(HasSideEffect) | (unsigned(AlignStack)<<1) |
+      (unsigned(IsConst)<<2);
     ID.Kind = ValID::t_InlineAsm;
     return false;
   }
@@ -2452,7 +2455,8 @@
       PTy ? dyn_cast<FunctionType>(PTy->getElementType()) : 0;
     if (!FTy || !InlineAsm::Verify(FTy, ID.StrVal2))
       return Error(ID.Loc, "invalid type for inline asm constraint string");
-    V = InlineAsm::get(FTy, ID.StrVal, ID.StrVal2, ID.UIntVal&1, 
ID.UIntVal>>1);
+    V = InlineAsm::get(FTy, ID.StrVal, ID.StrVal2, ID.UIntVal & 1,
+                       (ID.UIntVal >> 1) & 1, (ID.UIntVal >> 2) & 1);
     return false;
   }
   case ValID::t_MDNode:
Index: lib/Bitcode/Reader/BitcodeReader.cpp
===================================================================
--- lib/Bitcode/Reader/BitcodeReader.cpp        (revision 156383)
+++ lib/Bitcode/Reader/BitcodeReader.cpp        (working copy)
@@ -1274,7 +1274,8 @@
       if (Record.size() < 2) return Error("Invalid INLINEASM record");
       std::string AsmStr, ConstrStr;
       bool HasSideEffects = Record[0] & 1;
-      bool IsAlignStack = Record[0] >> 1;
+      bool IsAlignStack = (Record[0] >> 1) & 1;
+      bool IsConst = (Record[0] >> 2) & 1;
       unsigned AsmStrSize = Record[1];
       if (2+AsmStrSize >= Record.size())
         return Error("Invalid INLINEASM record");
@@ -1288,7 +1289,7 @@
         ConstrStr += (char)Record[3+AsmStrSize+i];
       PointerType *PTy = cast<PointerType>(CurTy);
       V = InlineAsm::get(cast<FunctionType>(PTy->getElementType()),
-                         AsmStr, ConstrStr, HasSideEffects, IsAlignStack);
+                         AsmStr, ConstrStr, HasSideEffects, IsAlignStack, 
IsConst);
       break;
     }
     case bitc::CST_CODE_BLOCKADDRESS:{
Index: lib/Bitcode/Writer/BitcodeWriter.cpp
===================================================================
--- lib/Bitcode/Writer/BitcodeWriter.cpp        (revision 156383)
+++ lib/Bitcode/Writer/BitcodeWriter.cpp        (working copy)
@@ -776,7 +776,8 @@
 
     if (const InlineAsm *IA = dyn_cast<InlineAsm>(V)) {
       Record.push_back(unsigned(IA->hasSideEffects()) |
-                       unsigned(IA->isAlignStack()) << 1);
+                       (unsigned(IA->isAlignStack()) << 1) |
+                       (unsigned(IA->isConst()) << 2));
 
       // Add the asm string.
       const std::string &AsmStr = IA->getAsmString();
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to