Index: llvm/trunk/lib/Analysis/ConstantFolding.cpp =================================================================== --- llvm/trunk/lib/Analysis/ConstantFolding.cpp +++ llvm/trunk/lib/Analysis/ConstantFolding.cpp @@ -1520,8 +1520,14 @@ (Ty->isHalfTy() || Ty->isFloatTy() || Ty->isDoubleTy())) { if (V >= -0.0) return ConstantFoldFP(sqrt, V, Ty); - else // Undefined - return Constant::getNullValue(Ty); + else { + // Unlike the sqrt definitions in C/C++, POSIX, and IEEE-754 - which + // all guarantee or favor returning NaN - the square root of a + // negative number is not defined for the LLVM sqrt intrinsic. + // This is because the intrinsic should only be emitted in place of + // libm's sqrt function when using "no-nans-fp-math". + return UndefValue::get(Ty); + } } break; case 's': Index: llvm/trunk/test/Transforms/InstCombine/constant-fold-math.ll =================================================================== --- llvm/trunk/test/Transforms/InstCombine/constant-fold-math.ll +++ llvm/trunk/test/Transforms/InstCombine/constant-fold-math.ll @@ -7,6 +7,7 @@ declare double @llvm.fma.f64(double, double, double) #0 declare double @llvm.fmuladd.f64(double, double, double) #0 +declare double @llvm.sqrt.f64(double) #0 ; CHECK-LABEL: @constant_fold_fma_f32 @@ -44,4 +45,12 @@ ret double %x } +; The sqrt intrinsic is undefined for negative inputs besides -0.0. +; CHECK-LABEL: @bad_sqrt +; CHECK-NEXT: ret double undef +define double @bad_sqrt() { + %x = call double @llvm.sqrt.f64(double -2.000000e+00) + ret double %x +} + attributes #0 = { nounwind readnone }