[llvm-commits] [llvm-gcc-4.2] r80465 - /llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp

Dan Gohman gohman at apple.com
Sat Aug 29 17:28:20 PDT 2009


Author: djg
Date: Sat Aug 29 19:28:20 2009
New Revision: 80465

URL: http://llvm.org/viewvc/llvm-project?rev=80465&view=rev
Log:
Revert r80449 and add a big comment explaining why the seemingly
obvious fix is not actually correct. Thanks Eli for pointing this out!

Modified:
    llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp

Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=80465&r1=80464&r2=80465&view=diff

==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Sat Aug 29 19:28:20 2009
@@ -4487,25 +4487,23 @@
           }
           unsigned OTyBits = TD.getTypeSizeInBits(OTy);
           unsigned OpTyBits = TD.getTypeSizeInBits(OpTy);
-          if (OTyBits == 0 || OpTyBits == 0) {
+          if (OTyBits == 0 || OpTyBits == 0 || OTyBits < OpTyBits) {
+            // It's tempting to implement the OTyBits < OpTyBits case by truncating
+            // Op down to OTy, however that breaks in the case of an inline asm
+            // constraint that corresponds to a single register, because the
+            // user can write code that assumes the whole register is defined,
+            // despite the output operand being only a subset of the register. For
+            // example:
+            //
+            //   asm ("sarl $10, %%eax" : "=a"(c) : "0"(1000000));
+            //
+            // The expected behavior is for %eax to be fully defined with the value
+            // 1000000 immediately before the asm.
             error("%Hunsupported inline asm: input constraint with a matching "
                   "output constraint of incompatible type!",
                   &EXPR_LOCATION(exp));
             return 0;
-          } else if (OTyBits < OpTyBits) {
-            // Truncate the input to match the output.
-            Op = CastToAnyType(Op, !TYPE_UNSIGNED(type),
-                               OTy, CallResultIsSigned[Match]);
-            // Big endian may be doable; I just don't know what the
-            // behavior is supposed to be.
-            if (BYTES_BIG_ENDIAN) {
-              error("%Hunsupported inline asm: input constraint with a "
-                    "matching output constraint of incompatible type!",
-                    &EXPR_LOCATION(exp));
-            }
-            OpTy = Op->getType();
           } else if (OTyBits > OpTyBits) {
-            // Extend the input to match the output.
             Op = CastToAnyType(Op, !TYPE_UNSIGNED(type),
                                OTy, CallResultIsSigned[Match]);
             if (BYTES_BIG_ENDIAN) {





More information about the llvm-commits mailing list