[Beignet] [PATCH] Generate NAN for UNDEF value in printf parser.

Zhigang Gong zhigang.gong at linux.intel.com
Wed Mar 18 01:02:38 PDT 2015


The root cause is that LLVM won't generate NaN for some builtin functions.
LLVM 3.5 will generate 0.0 for SQRT(-1.0) case and LLVM 3.6 will generate
undef.

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));

Don't see any chance it will be fixed within LLVM soon, so I will push
this patch.

Thanks.

On Tue, Mar 17, 2015 at 06:08:40PM +0800, junyan.he at inbox.com wrote:
> From: Junyan He <junyan.he at linux.intel.com>
> 
> 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.
> 
> Signed-off-by: Junyan He <junyan.he at linux.intel.com>
> ---
>  backend/src/llvm/llvm_printf_parser.cpp |    6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/backend/src/llvm/llvm_printf_parser.cpp b/backend/src/llvm/llvm_printf_parser.cpp
> index 7800c01..2f85443 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. */
> -- 
> 1.7.9.5
> 
> _______________________________________________
> Beignet mailing list
> Beignet at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/beignet


More information about the Beignet mailing list