llvm.org GIT mirror llvm / 33e1fb2
Fix constant folding of fp2int to large integers We make the assumption in most of our constant folding code that a fp2int will target an integer of 128-bits or less, calling the APFloat::convertToInteger with only uint64_t[2] of raw bits for the result. Fuzz testing (PR24662) showed that we don't handle other cases at all, resulting in stack overflows and all sorts of crashes. This patch uses the APSInt version of APFloat::convertToInteger instead to better handle such cases. Differential Revision: https://reviews.llvm.org/D31074 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@298226 91177308-0d34-0410-b5e6-96231b3b80d8 Simon Pilgrim 3 years ago
4 changed file(s) with 25 addition(s) and 21 deletion(s). Raw diff Collapse all Expand all
3939 //===----------------------------------------------------------------------===//
4040
4141 #include "llvm/ADT/APFloat.h"
42 #include "llvm/ADT/APInt.h"
42 #include "llvm/ADT/APSInt.h"
4343 #include "llvm/ADT/DenseMap.h"
4444 #include "llvm/ADT/Optional.h"
4545 #include "llvm/ADT/SmallPtrSet.h"
256256 // Try to emit the constant by using an integer constant with a cast.
257257 const APFloat &Flt = CF->getValueAPF();
258258 EVT IntVT = TLI.getPointerTy(DL);
259
260 uint64_t x[2];
261259 uint32_t IntBitWidth = IntVT.getSizeInBits();
260 APSInt SIntVal(IntBitWidth, /*isUnsigned=*/false);
262261 bool isExact;
263 (void)Flt.convertToInteger(x, IntBitWidth, /*isSigned=*/true,
264 APFloat::rmTowardZero, &isExact);
262 (void)Flt.convertToInteger(SIntVal, APFloat::rmTowardZero, &isExact);
265263 if (isExact) {
266 APInt IntVal(IntBitWidth, x);
267
268264 unsigned IntegerReg =
269 getRegForValue(ConstantInt::get(V->getContext(), IntVal));
265 getRegForValue(ConstantInt::get(V->getContext(), SIntVal));
270266 if (IntegerReg != 0)
271267 Reg = fastEmit_r(IntVT.getSimpleVT(), VT, ISD::SINT_TO_FP, IntegerReg,
272268 /*Kill=*/false);
34333433 }
34343434 case ISD::FP_TO_SINT:
34353435 case ISD::FP_TO_UINT: {
3436 integerPart x[2];
34373436 bool ignored;
3438 static_assert(integerPartWidth >= 64, "APFloat parts too small!");
3437 APSInt IntVal(VT.getSizeInBits(), Opcode == ISD::FP_TO_UINT);
34393438 // FIXME need to be more flexible about rounding mode.
3440 APFloat::opStatus s = V.convertToInteger(x, VT.getSizeInBits(),
3441 Opcode==ISD::FP_TO_SINT,
3442 APFloat::rmTowardZero, &ignored);
3443 if (s==APFloat::opInvalidOp) // inexact is OK, in fact usual
3439 APFloat::opStatus s =
3440 V.convertToInteger(IntVal, APFloat::rmTowardZero, &ignored);
3441 if (s == APFloat::opInvalidOp) // inexact is OK, in fact usual
34443442 break;
3445 APInt api(VT.getSizeInBits(), x);
3446 return getConstant(api, DL, VT);
3443 return getConstant(IntVal, DL, VT);
34473444 }
34483445 case ISD::BITCAST:
34493446 if (VT == MVT::i16 && C->getValueType(0) == MVT::f16)
1717 //===----------------------------------------------------------------------===//
1818
1919 #include "ConstantFold.h"
20 #include "llvm/ADT/APSInt.h"
2021 #include "llvm/ADT/SmallVector.h"
2122 #include "llvm/IR/Constants.h"
2223 #include "llvm/IR/DerivedTypes.h"
605606 if (ConstantFP *FPC = dyn_cast(V)) {
606607 const APFloat &V = FPC->getValueAPF();
607608 bool ignored;
608 uint64_t x[2];
609609 uint32_t DestBitWidth = cast(DestTy)->getBitWidth();
610 APSInt IntVal(DestBitWidth, opc == Instruction::FPToUI);
610611 if (APFloat::opInvalidOp ==
611 V.convertToInteger(x, DestBitWidth, opc==Instruction::FPToSI,
612 APFloat::rmTowardZero, &ignored)) {
612 V.convertToInteger(IntVal, APFloat::rmTowardZero, &ignored)) {
613613 // Undefined behavior invoked - the destination type can't represent
614614 // the input constant.
615615 return UndefValue::get(DestTy);
616616 }
617 APInt Val(DestBitWidth, x);
618 return ConstantInt::get(FPC->getContext(), Val);
617 return ConstantInt::get(FPC->getContext(), IntVal);
619618 }
620619 return nullptr; // Can't fold.
621620 case Instruction::IntToPtr: //always treated as unsigned
0 ; RUN: llc < %s -fast-isel
1 ; RUN: llc < %s
2
3 define i60 @PR24662a() {
4 ret i60 trunc (i670010 fptoui(float 0x400D9999A0000000 to i670010) to i60)
5 }
6
7 define i60 @PR24662b() {
8 %1 = fptoui float 0x400D9999A0000000 to i670010
9 %2 = trunc i670010 %1 to i60
10 ret i60 %2
11 }