diff --git a/include/llvm/ADT/APInt.h b/include/llvm/ADT/APInt.h index 97fe4e9201a..01b49d0864f 100644 --- a/include/llvm/ADT/APInt.h +++ b/include/llvm/ADT/APInt.h @@ -172,7 +172,7 @@ public: /// @param numWords the number of words in bigVal /// @param bigVal a sequence of words to form the initial value of the APInt /// @brief Construct an APInt of numBits width, initialized as bigVal[]. - APInt(uint32_t numBits, uint32_t numWords, uint64_t bigVal[]); + APInt(uint32_t numBits, uint32_t numWords, const uint64_t bigVal[]); /// This constructor interprets Val as a string in the given radix. The /// interpretation stops when the first charater that is not suitable for the diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index 34fca4d6239..340125e761c 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -3215,7 +3215,8 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { const uint64_t zero[] = {0, 0}; APFloat apf = APFloat(APInt(MVT::getSizeInBits(VT), 2, zero)); uint64_t x = 1ULL << ShiftAmt; - (void)apf.convertFromInteger(&x, 1, false, APFloat::rmTowardZero); + (void)apf.convertFromInteger(&x, MVT::getSizeInBits(NVT), false, + APFloat::rmTowardZero); Tmp2 = DAG.getConstantFP(apf, VT); Tmp3 = DAG.getSetCC(TLI.getSetCCResultTy(), Node->getOperand(0), Tmp2, ISD::SETLT); diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 92c0f2445bc..042868d7bb1 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -1595,8 +1595,10 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT, case ISD::SINT_TO_FP: { const uint64_t zero[] = {0, 0}; APFloat apf = APFloat(APInt(MVT::getSizeInBits(VT), 2, zero)); - (void)apf.convertFromInteger(&Val, 1, Opcode==ISD::SINT_TO_FP, - APFloat::rmTowardZero); + (void)apf.convertFromInteger(&Val, + MVT::getSizeInBits(Operand.getValueType()), + Opcode==ISD::SINT_TO_FP, + APFloat::rmTowardZero); return getConstantFP(apf, VT); } case ISD::BIT_CONVERT: diff --git a/lib/ExecutionEngine/ExecutionEngine.cpp b/lib/ExecutionEngine/ExecutionEngine.cpp index afff142f9f5..c72663e0d4d 100644 --- a/lib/ExecutionEngine/ExecutionEngine.cpp +++ b/lib/ExecutionEngine/ExecutionEngine.cpp @@ -393,10 +393,11 @@ GenericValue ExecutionEngine::getConstantValue(const Constant *C) { GV.FloatVal = float(GV.IntVal.roundToDouble()); else if (CE->getType() == Type::DoubleTy) GV.DoubleVal = GV.IntVal.roundToDouble(); - else if (CE->getType() == Type::X86_FP80Ty) { + else if (CE->getType() == Type::X86_FP80Ty) { const uint64_t zero[] = {0, 0}; APFloat apf = APFloat(APInt(80, 2, zero)); - (void)apf.convertFromInteger(GV.IntVal.getRawData(), 2, false, + (void)apf.convertFromInteger(GV.IntVal.getRawData(), + GV.IntVal.getBitWidth(), false, APFloat::rmTowardZero); GV.IntVal = apf.convertToAPInt(); } @@ -411,7 +412,8 @@ GenericValue ExecutionEngine::getConstantValue(const Constant *C) { else if (CE->getType() == Type::X86_FP80Ty) { const uint64_t zero[] = { 0, 0}; APFloat apf = APFloat(APInt(80, 2, zero)); - (void)apf.convertFromInteger(GV.IntVal.getRawData(), 2, true, + (void)apf.convertFromInteger(GV.IntVal.getRawData(), + GV.IntVal.getBitWidth(), true, APFloat::rmTowardZero); GV.IntVal = apf.convertToAPInt(); } diff --git a/lib/Support/APFloat.cpp b/lib/Support/APFloat.cpp index d3147426cb4..1fab6cae47e 100644 --- a/lib/Support/APFloat.cpp +++ b/lib/Support/APFloat.cpp @@ -1180,7 +1180,8 @@ APFloat::mod(const APFloat &rhs, roundingMode rounding_mode) if (fs==opInvalidOp) return fs; - fs = V.convertFromInteger(x, parts, true, rmNearestTiesToEven); + fs = V.convertFromInteger(x, parts * integerPartWidth, true, + rmNearestTiesToEven); assert(fs==opOK); // should always work fs = V.multiply(rhs, rounding_mode); @@ -1459,28 +1460,30 @@ APFloat::convertFromUnsignedInteger(integerPart *parts, } APFloat::opStatus -APFloat::convertFromInteger(const integerPart *parts, - unsigned int partCount, bool isSigned, - roundingMode rounding_mode) +APFloat::convertFromInteger(const integerPart *parts, unsigned int width, + bool isSigned, roundingMode rounding_mode) { - unsigned int width; + unsigned int partCount = partCountForBits(width); opStatus status; - integerPart *copy; - - copy = new integerPart[partCount]; - APInt::tcAssign(copy, parts, partCount); - - width = partCount * integerPartWidth; + APInt api = APInt(width, partCount, parts); + integerPart *copy = new integerPart[partCount]; sign = false; - if(isSigned && APInt::tcExtractBit(parts, width - 1)) { - sign = true; - APInt::tcNegate(copy, partCount); + if(isSigned) { + if (APInt::tcExtractBit(parts, width - 1)) { + sign = true; + if (width < partCount * integerPartWidth) + api = api.sext(partCount * integerPartWidth); + } + else if (width < partCount * integerPartWidth) + api = api.zext(partCount * integerPartWidth); + } else { + if (width < partCount * integerPartWidth) + api = api.zext(partCount * integerPartWidth); } + APInt::tcAssign(copy, api.getRawData(), partCount); status = convertFromUnsignedInteger(copy, partCount, rounding_mode); - delete [] copy; - return status; } diff --git a/lib/Support/APInt.cpp b/lib/Support/APInt.cpp index 4a4474dbe7e..63bde6c4262 100644 --- a/lib/Support/APInt.cpp +++ b/lib/Support/APInt.cpp @@ -58,7 +58,7 @@ APInt::APInt(uint32_t numBits, uint64_t val, bool isSigned) clearUnusedBits(); } -APInt::APInt(uint32_t numBits, uint32_t numWords, uint64_t bigVal[]) +APInt::APInt(uint32_t numBits, uint32_t numWords, const uint64_t bigVal[]) : BitWidth(numBits), VAL(0) { assert(BitWidth >= IntegerType::MIN_INT_BITS && "bitwidth too small"); assert(BitWidth <= IntegerType::MAX_INT_BITS && "bitwidth too large");