summaryrefslogtreecommitdiff
path: root/backend
diff options
context:
space:
mode:
authorJunyan He <junyan.he@linux.intel.com>2015-03-17 18:08:40 +0800
committerZhigang Gong <zhigang.gong@intel.com>2015-03-18 16:04:00 +0800
commitacfc2a2799b9cb4153b7581f66a78b046fbb97ec (patch)
treeb1e91877c2fd77b8de3364ebf4f1db5ceec2e232 /backend
parentdbd0677d8571c0fa808d2cfe1bf5cc53e306c35a (diff)
Generate NAN for UNDEF value in printf parser.
llvm 3.6 will give a UNDEF value for NAN. The will cause the store instruction for UNDEF to be ignored. We need to modify it to NAN here. Comments from Zhigang: " The related commit of why LLVM won't just simply return NaN for such case is at: Make the sqrt intrinsic return undef for a negative input. As discussed here: http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20140609/220598.html And again here: http://lists.cs.uiuc.edu/pipermail/llvmdev/2014-September/077168.html The sqrt of a negative number when using the llvm intrinsic is undefined. We should return undef rather than 0.0 to match the definition in the LLVM IR lang ref. This change should not affect any code that isn't using "no-nans-fp-math"; ie, no-nans is a requirement for generating the llvm intrinsic in place of a sqrt function call. Unfortunately, the behavior introduced by this patch will not match current gcc, xlc, icc, and possibly other compilers. The current clang/llvm behavior of returning 0.0 doesn't either. We knowingly approve of this difference with the other compilers in an attempt to flag code that is invoking undefined behavior. A front-end warning should also try to convince the user that the program will fail: http://llvm.org/bugs/show_bug.cgi?id=21093 Differential Revision: http://reviews.llvm.org/D5527 This patch is a workaround for the following scenario: printf("%f \n", sqrt(-1.0f)); " Signed-off-by: Junyan He <junyan.he@linux.intel.com> Reviewed-by: Zhigang Gong <zhigang.gong@linux.intel.com>
Diffstat (limited to 'backend')
-rw-r--r--backend/src/llvm/llvm_printf_parser.cpp6
1 files changed, 6 insertions, 0 deletions
diff --git a/backend/src/llvm/llvm_printf_parser.cpp b/backend/src/llvm/llvm_printf_parser.cpp
index 7800c019..2f854430 100644
--- a/backend/src/llvm/llvm_printf_parser.cpp
+++ b/backend/src/llvm/llvm_printf_parser.cpp
@@ -831,6 +831,12 @@ error:
case Type::DoubleTyID:
case Type::FloatTyID: {
+ /* llvm 3.6 will give a undef value for NAN. */
+ if (dyn_cast<llvm::UndefValue>(arg)) {
+ APFloat nan = APFloat::getNaN(APFloat::IEEEsingle, false);
+ arg = ConstantFP::get(module->getContext(), nan);
+ }
+
/* Because the printf is a variable parameter function, it does not have the
function prototype, so the compiler will always promote the arg to the
longest precise type for float. So here, we can always find it is double. */