[llvm-commits] [llvm-gcc-4.0] r45737 - /llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp

Chris Lattner sabre at nondot.org
Mon Jan 7 20:59:40 PST 2008


Author: lattner
Date: Mon Jan  7 22:59:40 2008
New Revision: 45737

URL: http://llvm.org/viewvc/llvm-project?rev=45737&view=rev
Log:
Fix PR1721 with a minimal hack: if we see that we are codegen'ing something
with a smaller precision than the llvm register for it, do the zext/sext 
explicitly in the llvm IR.  This mirrors what GCC does in its expr.c.

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

Modified: llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp?rev=45737&r1=45736&r2=45737&view=diff

==============================================================================
--- llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp (original)
+++ llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp Mon Jan  7 22:59:40 2008
@@ -940,6 +940,30 @@
     break;
   }
   
+  // If this is an operation on an integer value in a precision smaller than
+  // the LLVM value we are computing it in, reduce the excess precision here.
+  // This happens with odd-sized bitfields (e.g. i33) that are evaluated in the
+  // next size power-of-two register (e.g. i64).  This should be reevaluated
+  // when we have good support for unusual sized integers in the code generator.
+  if (Result && TREE_CODE(TREE_TYPE(exp)) == INTEGER_TYPE) {
+    unsigned LLVMWidth = cast<IntegerType>(Result->getType())->getBitWidth();
+    unsigned TreeWidth = TYPE_PRECISION(TREE_TYPE(exp));
+    if (LLVMWidth > TreeWidth && lang_hooks.reduce_bit_field_operations) {
+      if (TYPE_UNSIGNED(TREE_TYPE(exp))) {
+        // Use an 'and' to clear excess top bits.
+        Constant *Mask =
+          ConstantInt::get(APInt::getLowBitsSet(LLVMWidth, TreeWidth));
+        Result = Builder.CreateAnd(Result, Mask, "mask");
+      } else {
+        // Shift Left then shift right.
+        Constant *ShAmt = ConstantInt::get(Result->getType(), 
+                                           LLVMWidth-TreeWidth);
+        Result = Builder.CreateShl(Result, ShAmt, "sextl");
+        Result = Builder.CreateAShr(Result, ShAmt, "sextr");
+      }
+    }
+  }
+  
   if (TheDebugInfo && EXPR_HAS_LOCATION(exp)) {
     // Restore location back down the tree.
     TheDebugInfo->setLocationFile(EXPR_FILENAME(exp));





More information about the llvm-commits mailing list