__builtin_nan support

Attached patch implements __builtin_nan, __builtin_nanf, and __builtin_nanl. When given a string literal as an argument, the expression becomes an FP literal that is a quiet NaN with the appropriate significand. When the argument is not a string literal, we let the code for handling builtin math library functions just turn the builtin into a call to the appropriate libm nan()/nanf()/nanl() call, which performs the same conversion. This behavior is similar to GCC, although I believe GCC's __builtin_nan does not call nan() if the argument is not a string literal.

builtin_nan.patch (3.66 KB)

@@ -58,6 +57,10 @@
     if (SemaBuiltinUnorderedCompare(TheCall.get()))
       return true;
     return TheCall.take();
+ case Builtin::BI__builtin_nan:
+ case Builtin::BI__builtin_nanf:
+ case Builtin::BI__builtin_nanl:
+ return SemaBuiltinNaN(FnInfo->getBuiltinID(), TheCall.get());
   case Builtin::BI__builtin_shufflevector:
     return SemaBuiltinShuffleVector(TheCall.get());
   }

This is unsafe; in the case where SemaBuiltinNaN doesn't find a string
literal, you end up with a dangling pointer.

+ llvm::APInt Val(64, 0x7ff8000000000000ULL, false);

Attached patch implements __builtin_nan, __builtin_nanf, and __builtin_nanl.

@@ -58,6 +57,10 @@
    if (SemaBuiltinUnorderedCompare(TheCall.get()))
      return true;
    return TheCall.take();
+ case Builtin::BI__builtin_nan:
+ case Builtin::BI__builtin_nanf:
+ case Builtin::BI__builtin_nanl:
+ return SemaBuiltinNaN(FnInfo->getBuiltinID(), TheCall.get());
  case Builtin::BI__builtin_shufflevector:
    return SemaBuiltinShuffleVector(TheCall.get());
  }

This is unsafe; in the case where SemaBuiltinNaN doesn't find a string
literal, you end up with a dangling pointer.

Sure enough, need a take vs. get

+ llvm::APInt Val(64, 0x7ff8000000000000ULL, false);
+
+ char *endp = 0;
+ uint64_t Significand = strtoull(data, &endp, 0);

Windows doesn't have strtoull.

What's the suggested replacement?

Nate

Nate Begeman wrote:-

>
>
> + llvm::APInt Val(64, 0x7ff8000000000000ULL, false);
> +
> + char *endp = 0;
> + uint64_t Significand = strtoull(data, &endp, 0);
>
> Windows doesn't have strtoull.

What's the suggested replacement?

I suggest you make a constructor in APFloat to take this kind of
input, rather than indirecting through APInt. It can already
convert decimals very efficiently (used for decimal->binary) and
then you nail the long-double case too, without stroull and friends.

Neil.