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)); _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits