r183889 - Towards PR12457: constant expression evaluation support for __builtin_parity{, l, ll}, __builtin_ffs{, l, ll}, and __builtin_fpclassify.

Richard Smith richard-llvm at metafoo.co.uk
Wed Jun 12 23:26:33 PDT 2013


Author: rsmith
Date: Thu Jun 13 01:26:32 2013
New Revision: 183889

URL: http://llvm.org/viewvc/llvm-project?rev=183889&view=rev
Log:
Towards PR12457: constant expression evaluation support for __builtin_parity{,l,ll}, __builtin_ffs{,l,ll}, and __builtin_fpclassify.

Modified:
    cfe/trunk/lib/AST/ExprConstant.cpp
    cfe/trunk/test/Sema/constant-builtins-2.c

Modified: cfe/trunk/lib/AST/ExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=183889&r1=183888&r2=183889&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ExprConstant.cpp (original)
+++ cfe/trunk/lib/AST/ExprConstant.cpp Thu Jun 13 01:26:32 2013
@@ -5691,6 +5691,13 @@ bool IntExprEvaluator::VisitCallExpr(con
     return Success(Val.byteSwap(), E);
   }
 
+  case Builtin::BI__builtin_classify_type:
+    return Success(EvaluateBuiltinClassifyType(E), E);
+
+  // FIXME: BI__builtin_clrsb
+  // FIXME: BI__builtin_clrsbl
+  // FIXME: BI__builtin_clrsbll
+
   case Builtin::BI__builtin_clz:
   case Builtin::BI__builtin_clzl:
   case Builtin::BI__builtin_clzll: {
@@ -5703,6 +5710,9 @@ bool IntExprEvaluator::VisitCallExpr(con
     return Success(Val.countLeadingZeros(), E);
   }
 
+  case Builtin::BI__builtin_constant_p:
+    return Success(EvaluateBuiltinConstantP(Info.Ctx, E->getArg(0)), E);
+
   case Builtin::BI__builtin_ctz:
   case Builtin::BI__builtin_ctzl:
   case Builtin::BI__builtin_ctzll: {
@@ -5715,30 +5725,65 @@ bool IntExprEvaluator::VisitCallExpr(con
     return Success(Val.countTrailingZeros(), E);
   }
 
-  case Builtin::BI__builtin_popcount:
-  case Builtin::BI__builtin_popcountl:
-  case Builtin::BI__builtin_popcountll: {
+  case Builtin::BI__builtin_eh_return_data_regno: {
+    int Operand = E->getArg(0)->EvaluateKnownConstInt(Info.Ctx).getZExtValue();
+    Operand = Info.Ctx.getTargetInfo().getEHDataRegisterNumber(Operand);
+    return Success(Operand, E);
+  }
+
+  case Builtin::BI__builtin_expect:
+    return Visit(E->getArg(0));
+
+  case Builtin::BI__builtin_ffs:
+  case Builtin::BI__builtin_ffsl:
+  case Builtin::BI__builtin_ffsll: {
     APSInt Val;
     if (!EvaluateInteger(E->getArg(0), Val, Info))
       return false;
 
-    return Success(Val.countPopulation(), E);
+    unsigned N = Val.countTrailingZeros();
+    return Success(N == Val.getBitWidth() ? 0 : N + 1, E);
   }
 
-  case Builtin::BI__builtin_classify_type:
-    return Success(EvaluateBuiltinClassifyType(E), E);
+  case Builtin::BI__builtin_fpclassify: {
+    APFloat Val(0.0);
+    if (!EvaluateFloat(E->getArg(5), Val, Info))
+      return false;
+    unsigned Arg;
+    switch (Val.getCategory()) {
+    case APFloat::fcNaN: Arg = 0; break;
+    case APFloat::fcInfinity: Arg = 1; break;
+    case APFloat::fcNormal: Arg = Val.isDenormal() ? 3 : 2; break;
+    case APFloat::fcZero: Arg = 4; break;
+    }
+    return Visit(E->getArg(Arg));
+  }
 
-  case Builtin::BI__builtin_constant_p:
-    return Success(EvaluateBuiltinConstantP(Info.Ctx, E->getArg(0)), E);
+  case Builtin::BI__builtin_isinf_sign: {
+    APFloat Val(0.0);
+    return EvaluateFloat(E->getArg(5), Val, Info) &&
+           Success(Val.isInfinity() ? (Val.isNegative() ? -1 : 1) : 0, E);
+  }
 
-  case Builtin::BI__builtin_eh_return_data_regno: {
-    int Operand = E->getArg(0)->EvaluateKnownConstInt(Info.Ctx).getZExtValue();
-    Operand = Info.Ctx.getTargetInfo().getEHDataRegisterNumber(Operand);
-    return Success(Operand, E);
+  case Builtin::BI__builtin_parity:
+  case Builtin::BI__builtin_parityl:
+  case Builtin::BI__builtin_parityll: {
+    APSInt Val;
+    if (!EvaluateInteger(E->getArg(0), Val, Info))
+      return false;
+
+    return Success(Val.countPopulation() % 2, E);
   }
 
-  case Builtin::BI__builtin_expect:
-    return Visit(E->getArg(0));
+  case Builtin::BI__builtin_popcount:
+  case Builtin::BI__builtin_popcountl:
+  case Builtin::BI__builtin_popcountll: {
+    APSInt Val;
+    if (!EvaluateInteger(E->getArg(0), Val, Info))
+      return false;
+
+    return Success(Val.countPopulation(), E);
+  }
 
   case Builtin::BIstrlen:
     // A call to strlen is not a constant expression.
@@ -6941,6 +6986,10 @@ bool FloatExprEvaluator::VisitCallExpr(c
       Result.changeSign();
     return true;
 
+  // FIXME: Builtin::BI__builtin_powi
+  // FIXME: Builtin::BI__builtin_powif
+  // FIXME: Builtin::BI__builtin_powil
+
   case Builtin::BI__builtin_copysign:
   case Builtin::BI__builtin_copysignf:
   case Builtin::BI__builtin_copysignl: {

Modified: cfe/trunk/test/Sema/constant-builtins-2.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/constant-builtins-2.c?rev=183889&r1=183888&r2=183889&view=diff
==============================================================================
--- cfe/trunk/test/Sema/constant-builtins-2.c (original)
+++ cfe/trunk/test/Sema/constant-builtins-2.c Thu Jun 13 01:26:32 2013
@@ -37,6 +37,17 @@ float        g16 = __builtin_copysign(1.
 double       g17 = __builtin_copysignf(1.0f, -1.0f);
 long double  g18 = __builtin_copysignl(1.0L, -1.0L);
 
+char classify_nan     [__builtin_fpclassify(+1, -1, -1, -1, -1, __builtin_nan(""))];
+char classify_snan    [__builtin_fpclassify(+1, -1, -1, -1, -1, __builtin_nans(""))];
+char classify_inf     [__builtin_fpclassify(-1, +1, -1, -1, -1, __builtin_inf())];
+char classify_neg_inf [__builtin_fpclassify(-1, +1, -1, -1, -1, -__builtin_inf())];
+char classify_normal  [__builtin_fpclassify(-1, -1, +1, -1, -1, 1.539)];
+char classify_normal2 [__builtin_fpclassify(-1, -1, +1, -1, -1, 1e-307)];
+char classify_denorm  [__builtin_fpclassify(-1, -1, -1, +1, -1, 1e-308)];
+char classify_denorm2 [__builtin_fpclassify(-1, -1, -1, +1, -1, -1e-308)];
+char classify_zero    [__builtin_fpclassify(-1, -1, -1, -1, +1, 0.0)];
+char classify_neg_zero[__builtin_fpclassify(-1, -1, -1, -1, +1, -0.0)];
+
 //double       g19 = __builtin_powi(2.0, 4);
 //float        g20 = __builtin_powif(2.0f, 4);
 //long double  g21 = __builtin_powil(2.0L, 4);
@@ -66,6 +77,25 @@ char g40[__builtin_popcountl(~0L) == BIT
 char g41[__builtin_popcountll(0LL) == 0 ? 1 : -1];
 char g42[__builtin_popcountll(0xF0F0LL) == 8 ? 1 : -1];
 char g43[__builtin_popcountll(~0LL) == BITSIZE(long long) ? 1 : -1];
+
+char g44[__builtin_parity(0) == 0 ? 1 : -1];
+char g45[__builtin_parity(0xb821) == 0 ? 1 : -1];
+char g46[__builtin_parity(0xb822) == 0 ? 1 : -1];
+char g47[__builtin_parity(0xb823) == 1 ? 1 : -1];
+char g48[__builtin_parity(0xb824) == 0 ? 1 : -1];
+char g49[__builtin_parity(0xb825) == 1 ? 1 : -1];
+char g50[__builtin_parity(0xb826) == 1 ? 1 : -1];
+char g51[__builtin_parity(~0) == 0 ? 1 : -1];
+char g52[__builtin_parityl(1L << (BITSIZE(long) - 1)) == 1 ? 1 : -1];
+char g53[__builtin_parityll(1LL << (BITSIZE(long long) - 1)) == 1 ? 1 : -1];
+
+char g54[__builtin_ffs(0) == 0 ? 1 : -1];
+char g55[__builtin_ffs(1) == 1 ? 1 : -1];
+char g56[__builtin_ffs(0xfbe71) == 1 ? 1 : -1];
+char g57[__builtin_ffs(0xfbe70) == 5 ? 1 : -1];
+char g58[__builtin_ffs(1U << (BITSIZE(int) - 1)) == BITSIZE(int) ? 1 : -1];
+char g59[__builtin_ffsl(0x10L) == 5 ? 1 : -1];
+char g60[__builtin_ffsll(0x100LL) == 9 ? 1 : -1];
 #undef BITSIZE
 
 // GCC misc stuff





More information about the cfe-commits mailing list