Add constant evaluation support for __builtin_isinf, __builtin_isfinite,
authorRichard Smith <richard-llvm@metafoo.co.uk>
Tue, 15 Oct 2013 19:07:14 +0000 (19:07 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Tue, 15 Oct 2013 19:07:14 +0000 (19:07 +0000)
__builtin_isnan, and __builtin_isnormal. Patch by Karthik Bhat! Tests by me.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@192729 91177308-0d34-0410-b5e6-96231b3b80d8

lib/AST/ExprConstant.cpp
test/Sema/constant-builtins-2.c

index fc35f49baa23e9072ee3c5335812f9a6aaa14e66..5953355cc64271d352dbb4668591630fee4f0eb3 100644 (file)
@@ -5985,6 +5985,30 @@ bool IntExprEvaluator::VisitCallExpr(const CallExpr *E) {
            Success(Val.isInfinity() ? (Val.isNegative() ? -1 : 1) : 0, E);
   }
 
+  case Builtin::BI__builtin_isinf: {
+    APFloat Val(0.0);
+    return EvaluateFloat(E->getArg(0), Val, Info) &&
+           Success(Val.isInfinity() ? 1 : 0, E);
+  }
+
+  case Builtin::BI__builtin_isfinite: {
+    APFloat Val(0.0);
+    return EvaluateFloat(E->getArg(0), Val, Info) &&
+           Success(Val.isFinite() ? 1 : 0, E);
+  }
+
+  case Builtin::BI__builtin_isnan: {
+    APFloat Val(0.0);
+    return EvaluateFloat(E->getArg(0), Val, Info) &&
+           Success(Val.isNaN() ? 1 : 0, E);
+  }
+
+  case Builtin::BI__builtin_isnormal: {
+    APFloat Val(0.0);
+    return EvaluateFloat(E->getArg(0), Val, Info) &&
+           Success(Val.isNormal() ? 1 : 0, E);
+  }
+
   case Builtin::BI__builtin_parity:
   case Builtin::BI__builtin_parityl:
   case Builtin::BI__builtin_parityll: {
index 0e63ad3e8b76bfff88600bc97e07154875edecac..d2d221c5e12b445949926bfd1b330b833261a628 100644 (file)
@@ -55,6 +55,58 @@ char isinf_sign_noninf4[__builtin_isinf_sign(-436.) == 0 ? 1 : -1];
 char isinf_sign_inf    [__builtin_isinf_sign(__builtin_inf()) == 1 ? 1 : -1];
 char isinf_sign_neg_inf[__builtin_isinf_sign(-__builtin_inf()) == -1 ? 1 : -1];
 
+char isinf_inf_pos[__builtin_isinf(__builtin_inf()) ? 1 : -1];
+char isinf_pos    [!__builtin_isinf(1.0) ? 1 : -1];
+char isinf_normf  [!__builtin_isinf(1e-37f) ? 1 : -1];
+char isinf_denormf[!__builtin_isinf(1e-38f) ? 1 : -1];
+char isinf_norm   [!__builtin_isinf(1e-307) ? 1 : -1];
+char isinf_denorm [!__builtin_isinf(1e-308) ? 1 : -1];
+char isinf_zero   [!__builtin_isinf(0.0) ? 1 : -1];
+char isinf_negzero[!__builtin_isinf(-0.0) ? 1 : -1];
+char isinf_neg    [!__builtin_isinf(-1.0) ? 1 : -1];
+char isinf_inf_neg[__builtin_isinf(-__builtin_inf()) ? 1 : -1];
+char isinf_nan    [!__builtin_isinf(__builtin_nan("")) ? 1 : -1];
+char isinf_snan   [!__builtin_isinf(__builtin_nans("")) ? 1 : -1];
+
+char isfinite_inf_pos[!__builtin_isfinite(__builtin_inf()) ? 1 : -1];
+char isfinite_pos    [__builtin_isfinite(1.0) ? 1 : -1];
+char isfinite_normf  [__builtin_isfinite(1e-37f) ? 1 : -1];
+char isfinite_denormf[__builtin_isfinite(1e-38f) ? 1 : -1];
+char isfinite_norm   [__builtin_isfinite(1e-307) ? 1 : -1];
+char isfinite_denorm [__builtin_isfinite(1e-308) ? 1 : -1];
+char isfinite_zero   [__builtin_isfinite(0.0) ? 1 : -1];
+char isfinite_negzero[__builtin_isfinite(-0.0) ? 1 : -1];
+char isfinite_neg    [__builtin_isfinite(-1.0) ? 1 : -1];
+char isfinite_inf_neg[!__builtin_isfinite(-__builtin_inf()) ? 1 : -1];
+char isfinite_nan    [!__builtin_isfinite(__builtin_nan("")) ? 1 : -1];
+char isfinite_snan   [!__builtin_isfinite(__builtin_nans("")) ? 1 : -1];
+
+char isnan_inf_pos[!__builtin_isnan(__builtin_inf()) ? 1 : -1];
+char isnan_pos    [!__builtin_isnan(1.0) ? 1 : -1];
+char isnan_normf  [!__builtin_isnan(1e-37f) ? 1 : -1];
+char isnan_denormf[!__builtin_isnan(1e-38f) ? 1 : -1];
+char isnan_norm   [!__builtin_isnan(1e-307) ? 1 : -1];
+char isnan_denorm [!__builtin_isnan(1e-308) ? 1 : -1];
+char isnan_zero   [!__builtin_isnan(0.0) ? 1 : -1];
+char isnan_negzero[!__builtin_isnan(-0.0) ? 1 : -1];
+char isnan_neg    [!__builtin_isnan(-1.0) ? 1 : -1];
+char isnan_inf_neg[!__builtin_isnan(-__builtin_inf()) ? 1 : -1];
+char isnan_nan    [__builtin_isnan(__builtin_nan("")) ? 1 : -1];
+char isnan_snan   [__builtin_isnan(__builtin_nans("")) ? 1 : -1];
+
+char isnormal_inf_pos[!__builtin_isnormal(__builtin_inf()) ? 1 : -1];
+char isnormal_pos    [__builtin_isnormal(1.0) ? 1 : -1];
+char isnormal_normf  [__builtin_isnormal(1e-37f) ? 1 : -1];
+char isnormal_denormf[!__builtin_isnormal(1e-38f) ? 1 : -1];
+char isnormal_norm   [__builtin_isnormal(1e-307) ? 1 : -1];
+char isnormal_denorm [!__builtin_isnormal(1e-308) ? 1 : -1];
+char isnormal_zero   [!__builtin_isnormal(0.0) ? 1 : -1];
+char isnormal_negzero[!__builtin_isnormal(-0.0) ? 1 : -1];
+char isnormal_neg    [__builtin_isnormal(-1.0) ? 1 : -1];
+char isnormal_inf_neg[!__builtin_isnormal(-__builtin_inf()) ? 1 : -1];
+char isnormal_nan    [!__builtin_isnormal(__builtin_nan("")) ? 1 : -1];
+char isnormal_snan   [!__builtin_isnormal(__builtin_nans("")) ? 1 : -1];
+
 //double       g19 = __builtin_powi(2.0, 4);
 //float        g20 = __builtin_powif(2.0f, 4);
 //long double  g21 = __builtin_powil(2.0L, 4);