From: Richard Smith Date: Thu, 13 Jun 2013 06:26:32 +0000 (+0000) Subject: Towards PR12457: constant expression evaluation support for __builtin_parity{,l,ll... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=acaf72adaed7b320fdec8c09f70ec9ac46df3563;p=clang Towards PR12457: constant expression evaluation support for __builtin_parity{,l,ll}, __builtin_ffs{,l,ll}, and __builtin_fpclassify. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@183889 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp index 84f7bfdf82..ad4816a24f 100644 --- a/lib/AST/ExprConstant.cpp +++ b/lib/AST/ExprConstant.cpp @@ -5691,6 +5691,13 @@ bool IntExprEvaluator::VisitCallExpr(const CallExpr *E) { 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(const CallExpr *E) { 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(const CallExpr *E) { 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(const CallExpr *E) { 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: { diff --git a/test/Sema/constant-builtins-2.c b/test/Sema/constant-builtins-2.c index 14afe3e31a..7da899b62e 100644 --- a/test/Sema/constant-builtins-2.c +++ b/test/Sema/constant-builtins-2.c @@ -37,6 +37,17 @@ float g16 = __builtin_copysign(1.0, -1.0); 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) == BITSIZE(long) ? 1 : -1]; 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