[llvm-commits] [llvm-gcc-4.2] r45740 - /llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp
Chris Lattner
sabre at nondot.org
Mon Jan 7 21:18:46 PST 2008
Author: lattner
Date: Mon Jan 7 23:18:45 2008
New Revision: 45740
URL: http://llvm.org/viewvc/llvm-project?rev=45740&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.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=45740&r1=45739&r2=45740&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Mon Jan 7 23:18:45 2008
@@ -982,6 +982,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