[cfe-commits] r70679 - in /cfe/trunk: lib/Sema/SemaStmt.cpp test/CodeGen/asm.c

Chris Lattner sabre at nondot.org
Sun May 3 01:32:41 PDT 2009


Author: lattner
Date: Sun May  3 03:32:32 2009
New Revision: 70679

URL: http://llvm.org/viewvc/llvm-project?rev=70679&view=rev
Log:
allow references to the larger value in a tied constraint
from the asm string, but reject references to the smaller one.


Modified:
    cfe/trunk/lib/Sema/SemaStmt.cpp
    cfe/trunk/test/CodeGen/asm.c

Modified: cfe/trunk/lib/Sema/SemaStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmt.cpp?rev=70679&r1=70678&r2=70679&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaStmt.cpp (original)
+++ cfe/trunk/lib/Sema/SemaStmt.cpp Sun May  3 03:32:32 2009
@@ -1052,26 +1052,42 @@
       // They are ok if they are the same size.  Tying void* to int is ok if
       // they are the same size, for example.  This also allows tying void* to
       // int*.
-      if (Context.getTypeSize(OutTy) == Context.getTypeSize(InTy))
+      uint64_t OutSize = Context.getTypeSize(OutTy);
+      uint64_t InSize = Context.getTypeSize(InTy);
+      if (OutSize == InSize)
         continue;
       
-      // If the input and output operands are not mentioned in the asm string,
-      // then we can promote them and the asm string won't notice.  Check this
+      // If the smaller input/output operand is not mentioned in the asm string,
+      // then we can promote it and the asm string won't notice.  Check this
       // case now.
-      bool MentionedInput = false;
-      bool MentionedOutput = false;
+      bool SmallerValueMentioned = false;
       for (unsigned p = 0, e = Pieces.size(); p != e; ++p) {
         AsmStmt::AsmStringPiece &Piece = Pieces[p];
         if (!Piece.isOperand()) continue;
-        MentionedInput |= Piece.getOperandNo() == i+NumOutputs;
-        MentionedOutput |= Piece.getOperandNo() == TiedTo;
+        
+        // If this is a reference to the input and if the input was the smaller
+        // one, then we have to reject this asm.
+        if (Piece.getOperandNo() == i+NumOutputs) {
+          if (InSize < OutSize) {
+            SmallerValueMentioned = true;
+            break;
+          }
+        }
+
+        // If this is a reference to the input and if the input was the smaller
+        // one, then we have to reject this asm.
+        if (Piece.getOperandNo() == TiedTo) {
+          if (InSize > OutSize) {
+            SmallerValueMentioned = true;
+            break;
+          }
+        }
       }
       
-      // If neither the input nor the output was mentioned in the asm string,
-      // and if the output was a register, just extend the shorter one to the
-      // size of the larger one.
-      // TODO: if only the larger one is mentioned, we could also support this.
-      if (!MentionedInput && !MentionedOutput &&
+      // If the smaller value wasn't mentioned in the asm string, and if the
+      // output was a register, just extend the shorter one to the size of the
+      // larger one.
+      if (!SmallerValueMentioned &&
           OutputConstraintInfos[TiedTo].allowsRegister())
         continue;
     }

Modified: cfe/trunk/test/CodeGen/asm.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/asm.c?rev=70679&r1=70678&r2=70679&view=diff

==============================================================================
--- cfe/trunk/test/CodeGen/asm.c (original)
+++ cfe/trunk/test/CodeGen/asm.c Sun May  3 03:32:32 2009
@@ -69,11 +69,22 @@
   return output;
 }
 
+unsigned char t13(unsigned input) {
+  unsigned char output;
+  __asm__("xyz %1"
+          : "=a" (output)
+          : "0" (input));
+  return output;
+}
+
 
+// bitfield destination of an asm.
 struct S {
   int a : 4;
 };
 
-void test13(struct S *P) {
+void t14(struct S *P) {
   __asm__("abc %0" : "=r"(P->a) );
 }
+
+





More information about the cfe-commits mailing list