zoecarver updated this revision to Diff 217973. zoecarver added a comment. - remove rint updates (rint uses runtime-defined rounding method) - add more tests (nan, overflow, round down) - use APFloat rounding methods - if rounding fails, bail out to runtime
Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D66862/new/ https://reviews.llvm.org/D66862 Files: clang/lib/AST/ExprConstant.cpp clang/test/SemaCXX/math-builtins.cpp Index: clang/test/SemaCXX/math-builtins.cpp =================================================================== --- /dev/null +++ clang/test/SemaCXX/math-builtins.cpp @@ -0,0 +1,32 @@ +// RUN: %clang_cc1 -std=c++11 %s + +int main() +{ + constexpr float f1 = 12345.6789; + constexpr float f2 = 12345.4321; + + static_assert(__builtin_llround(f1) == 12346, ""); + static_assert(__builtin_llroundf(f1) == 12346, ""); + + static_assert(__builtin_lround(f1) == 12346, ""); + static_assert(__builtin_lroundf(f1) == 12346, ""); + + static_assert(__builtin_llround(f2) == 12345, ""); + static_assert(__builtin_llroundf(f2) == 12345, ""); + + static_assert(__builtin_lround(f2) == 12345, ""); + static_assert(__builtin_lroundf(f2) == 12345, ""); + + static_assert(__builtin_llround(float()) == 0, ""); // expected-error {{static_assert expression is not an integral constant expression}} + static_assert(__builtin_llroundf(float()) == 0, ""); // expected-error {{static_assert expression is not an integral constant expression}} + + static_assert(__builtin_lround(float()) == 0, ""); // expected-error {{static_assert expression is not an integral constant expression}} + static_assert(__builtin_lroundf(float()) == 0, ""); // expected-error {{static_assert expression is not an integral constant expression}} + + // TODO: expected-error not working + static_assert(__builtin_llround(__FLT_MAX__) == 0, ""); // expected-error {{static_assert expression is not an integral constant expression}} + static_assert(__builtin_llroundf(__FLT_MAX__) == 0, ""); // expected-error {{static_assert expression is not an integral constant expression}} + + static_assert(__builtin_lround(__FLT_MAX__) == 0, ""); // expected-error {{static_assert expression is not an integral constant expression}} + static_assert(__builtin_lroundf(__FLT_MAX__) == 0, ""); // expected-error {{static_assert expression is not an integral constant expression}} +} \ No newline at end of file Index: clang/lib/AST/ExprConstant.cpp =================================================================== --- clang/lib/AST/ExprConstant.cpp +++ clang/lib/AST/ExprConstant.cpp @@ -9609,6 +9609,22 @@ return Success(N == Val.getBitWidth() ? 0 : N + 1, E); } + case Builtin::BI__builtin_lround: + case Builtin::BI__builtin_lroundf: + case Builtin::BI__builtin_llround: + case Builtin::BI__builtin_llroundf: { + APFloat FPVal(0.0); + APSInt IVal(64, 0); // TODO: dynamically get correct size here? + bool isExact = true; + + if(!EvaluateFloat(E->getArg(0), FPVal, Info)) return false; + APFloat::opStatus status = + FPVal.convertToInteger(IVal, APFloat::rmNearestTiesToAway, &isExact); + if(status != APFloat::opInexact && status != APFloat::opOK) return false; + + return Success(IVal.getExtValue(), E); + } + case Builtin::BI__builtin_fpclassify: { APFloat Val(0.0); if (!EvaluateFloat(E->getArg(5), Val, Info))
Index: clang/test/SemaCXX/math-builtins.cpp =================================================================== --- /dev/null +++ clang/test/SemaCXX/math-builtins.cpp @@ -0,0 +1,32 @@ +// RUN: %clang_cc1 -std=c++11 %s + +int main() +{ + constexpr float f1 = 12345.6789; + constexpr float f2 = 12345.4321; + + static_assert(__builtin_llround(f1) == 12346, ""); + static_assert(__builtin_llroundf(f1) == 12346, ""); + + static_assert(__builtin_lround(f1) == 12346, ""); + static_assert(__builtin_lroundf(f1) == 12346, ""); + + static_assert(__builtin_llround(f2) == 12345, ""); + static_assert(__builtin_llroundf(f2) == 12345, ""); + + static_assert(__builtin_lround(f2) == 12345, ""); + static_assert(__builtin_lroundf(f2) == 12345, ""); + + static_assert(__builtin_llround(float()) == 0, ""); // expected-error {{static_assert expression is not an integral constant expression}} + static_assert(__builtin_llroundf(float()) == 0, ""); // expected-error {{static_assert expression is not an integral constant expression}} + + static_assert(__builtin_lround(float()) == 0, ""); // expected-error {{static_assert expression is not an integral constant expression}} + static_assert(__builtin_lroundf(float()) == 0, ""); // expected-error {{static_assert expression is not an integral constant expression}} + + // TODO: expected-error not working + static_assert(__builtin_llround(__FLT_MAX__) == 0, ""); // expected-error {{static_assert expression is not an integral constant expression}} + static_assert(__builtin_llroundf(__FLT_MAX__) == 0, ""); // expected-error {{static_assert expression is not an integral constant expression}} + + static_assert(__builtin_lround(__FLT_MAX__) == 0, ""); // expected-error {{static_assert expression is not an integral constant expression}} + static_assert(__builtin_lroundf(__FLT_MAX__) == 0, ""); // expected-error {{static_assert expression is not an integral constant expression}} +} \ No newline at end of file Index: clang/lib/AST/ExprConstant.cpp =================================================================== --- clang/lib/AST/ExprConstant.cpp +++ clang/lib/AST/ExprConstant.cpp @@ -9609,6 +9609,22 @@ return Success(N == Val.getBitWidth() ? 0 : N + 1, E); } + case Builtin::BI__builtin_lround: + case Builtin::BI__builtin_lroundf: + case Builtin::BI__builtin_llround: + case Builtin::BI__builtin_llroundf: { + APFloat FPVal(0.0); + APSInt IVal(64, 0); // TODO: dynamically get correct size here? + bool isExact = true; + + if(!EvaluateFloat(E->getArg(0), FPVal, Info)) return false; + APFloat::opStatus status = + FPVal.convertToInteger(IVal, APFloat::rmNearestTiesToAway, &isExact); + if(status != APFloat::opInexact && status != APFloat::opOK) return false; + + return Success(IVal.getExtValue(), E); + } + case Builtin::BI__builtin_fpclassify: { APFloat Val(0.0); if (!EvaluateFloat(E->getArg(5), Val, Info))
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits