diff options
Diffstat (limited to 'llvm/lib/IR/ConstantFold.cpp')
| -rw-r--r-- | llvm/lib/IR/ConstantFold.cpp | 19 |
1 files changed, 14 insertions, 5 deletions
diff --git a/llvm/lib/IR/ConstantFold.cpp b/llvm/lib/IR/ConstantFold.cpp index b96d1540d71..cdfb41f7dcc 100644 --- a/llvm/lib/IR/ConstantFold.cpp +++ b/llvm/lib/IR/ConstantFold.cpp @@ -593,8 +593,13 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, Constant *V, bool ignored; uint64_t x[2]; uint32_t DestBitWidth = cast<IntegerType>(DestTy)->getBitWidth(); - (void) V.convertToInteger(x, DestBitWidth, opc==Instruction::FPToSI, - APFloat::rmTowardZero, &ignored); + if (APFloat::opInvalidOp == + V.convertToInteger(x, DestBitWidth, opc==Instruction::FPToSI, + APFloat::rmTowardZero, &ignored)) { + // Undefined behavior invoked - the destination type can't represent + // the input constant. + return UndefValue::get(DestTy); + } APInt Val(DestBitWidth, x); return ConstantInt::get(FPC->getContext(), Val); } @@ -653,9 +658,13 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, Constant *V, APInt api = CI->getValue(); APFloat apf(DestTy->getFltSemantics(), APInt::getNullValue(DestTy->getPrimitiveSizeInBits())); - (void)apf.convertFromAPInt(api, - opc==Instruction::SIToFP, - APFloat::rmNearestTiesToEven); + if (APFloat::opOverflow & + apf.convertFromAPInt(api, opc==Instruction::SIToFP, + APFloat::rmNearestTiesToEven)) { + // Undefined behavior invoked - the destination type can't represent + // the input constant. + return UndefValue::get(DestTy); + } return ConstantFP::get(V->getContext(), apf); } return nullptr; |

