[cfe-commits] r126148 - in /cfe/trunk: include/clang/AST/Stmt.h lib/AST/Stmt.cpp lib/Sema/SemaStmt.cpp test/CodeGen/asm-inout.c

Chris Lattner sabre at nondot.org
Mon Feb 21 14:09:30 PST 2011


Author: lattner
Date: Mon Feb 21 16:09:29 2011
New Revision: 126148

URL: http://llvm.org/viewvc/llvm-project?rev=126148&view=rev
Log:
add one more case of mismatched input/output constraints.  
When the mismatch is due to a larger input operand that is
a constant, truncate it down to the size of the output.  This
allows us to accept some cases in the linux kernel and elsewhere.
Pedantically speaking, we generate different code than GCC, though
I can't imagine how it would matter:

Clang:
	movb	$-1, %al
	frob %al

GCC:

	movl	$255, %eax
	frob %al


Modified:
    cfe/trunk/include/clang/AST/Stmt.h
    cfe/trunk/lib/AST/Stmt.cpp
    cfe/trunk/lib/Sema/SemaStmt.cpp
    cfe/trunk/test/CodeGen/asm-inout.c

Modified: cfe/trunk/include/clang/AST/Stmt.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Stmt.h?rev=126148&r1=126147&r2=126148&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Stmt.h (original)
+++ cfe/trunk/include/clang/AST/Stmt.h Mon Feb 21 16:09:29 2011
@@ -1328,7 +1328,8 @@
   }
 
   Expr *getInputExpr(unsigned i);
-
+  void setInputExpr(unsigned i, Expr *E);
+  
   const Expr *getInputExpr(unsigned i) const {
     return const_cast<AsmStmt*>(this)->getInputExpr(i);
   }

Modified: cfe/trunk/lib/AST/Stmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Stmt.cpp?rev=126148&r1=126147&r2=126148&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Stmt.cpp (original)
+++ cfe/trunk/lib/AST/Stmt.cpp Mon Feb 21 16:09:29 2011
@@ -218,6 +218,10 @@
 Expr *AsmStmt::getInputExpr(unsigned i) {
   return cast<Expr>(Exprs[i + NumOutputs]);
 }
+void AsmStmt::setInputExpr(unsigned i, Expr *E) {
+  Exprs[i + NumOutputs] = E;
+}
+
 
 /// getInputConstraint - Return the specified input constraint.  Unlike output
 /// constraints, these can be empty.

Modified: cfe/trunk/lib/Sema/SemaStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmt.cpp?rev=126148&r1=126147&r2=126148&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaStmt.cpp (original)
+++ cfe/trunk/lib/Sema/SemaStmt.cpp Mon Feb 21 16:09:29 2011
@@ -1542,8 +1542,9 @@
     if (!Info.hasTiedOperand()) continue;
 
     unsigned TiedTo = Info.getTiedOperand();
+    unsigned InputOpNo = i+NumOutputs;
     Expr *OutputExpr = Exprs[TiedTo];
-    Expr *InputExpr = Exprs[i+NumOutputs];
+    Expr *InputExpr = Exprs[InputOpNo];
     QualType InTy = InputExpr->getType();
     QualType OutTy = OutputExpr->getType();
     if (Context.hasSameType(InTy, OutTy))
@@ -1588,7 +1589,7 @@
     
     // If this is a reference to the input and if the input was the smaller
     // one, then we have to reject this asm.
-    if (isOperandMentioned(i+NumOutputs, Pieces)) {
+    if (isOperandMentioned(InputOpNo, Pieces)) {
       // This is a use in the asm string of the smaller operand.  Since we
       // codegen this by promoting to a wider value, the asm will get printed
       // "wrong".
@@ -1607,6 +1608,19 @@
         OutputConstraintInfos[TiedTo].allowsRegister())
       continue;
     
+    // Either both of the operands were mentioned or the smaller one was
+    // mentioned.  One more special case that we'll allow: if the tied input is
+    // integer, unmentioned, and is a constant, then we'll allow truncating it
+    // down to the size of the destination.
+    if (InputDomain == AD_Int && OutputDomain == AD_Int &&
+        !isOperandMentioned(InputOpNo, Pieces) &&
+        InputExpr->isEvaluatable(Context)) {
+      ImpCastExprToType(InputExpr, OutTy, CK_IntegralCast);
+      Exprs[InputOpNo] = InputExpr;
+      NS->setInputExpr(i, InputExpr);
+      continue;
+    }
+    
     Diag(InputExpr->getLocStart(),
          diag::err_asm_tying_incompatible_types)
       << InTy << OutTy << OutputExpr->getSourceRange()

Modified: cfe/trunk/test/CodeGen/asm-inout.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/asm-inout.c?rev=126148&r1=126147&r2=126148&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/asm-inout.c (original)
+++ cfe/trunk/test/CodeGen/asm-inout.c Mon Feb 21 16:09:29 2011
@@ -29,3 +29,12 @@
 		: "edi"
 		);
 }
+
+// PR8959 - This should implicitly truncate the immediate to a byte.
+int test4(volatile int *addr) {
+  unsigned char oldval;
+  __asm__ ("frob %0" : "=r"(oldval) : "0"(0xff));
+  return (int)oldval;
+// CHECK: call i8 asm "frob $0", "=r,0{{.*}}"(i8 -1)
+}
+





More information about the cfe-commits mailing list