aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/IR/ConstantFold.cpp
diff options
context:
space:
mode:
authorSanjay Patel <spatel@rotateright.com>2014-10-10 23:00:21 +0000
committerSanjay Patel <spatel@rotateright.com>2014-10-10 23:00:21 +0000
commitad8b666624e17bfc89a684cf060d96c3b6905d92 (patch)
tree8f776fe2544701055f7ac30509ff975313ab3252 /llvm/lib/IR/ConstantFold.cpp
parent96983b89b01e65a96919760557f3b6e90a32408a (diff)
downloadllvm-ad8b666624e17bfc89a684cf060d96c3b6905d92.zip
llvm-ad8b666624e17bfc89a684cf060d96c3b6905d92.tar.gz
llvm-ad8b666624e17bfc89a684cf060d96c3b6905d92.tar.bz2
Return undef on FP <-> Int conversions that overflow (PR21330).
The LLVM Lang Ref states for signed/unsigned int to float conversions: "If the value cannot fit in the floating point value, the results are undefined." And for FP to signed/unsigned int: "If the value cannot fit in ty2, the results are undefined." This matches the C definitions. The existing behavior pins to infinity or a max int value, but that may just lead to more confusion as seen in: http://llvm.org/bugs/show_bug.cgi?id=21130 Returning undef will hopefully lead to a less silent failure. Differential Revision: http://reviews.llvm.org/D5603 llvm-svn: 219542
Diffstat (limited to 'llvm/lib/IR/ConstantFold.cpp')
-rw-r--r--llvm/lib/IR/ConstantFold.cpp19
1 files changed, 14 insertions, 5 deletions
diff --git a/llvm/lib/IR/ConstantFold.cpp b/llvm/lib/IR/ConstantFold.cpp
index b96d154..cdfb41f 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;