https://github.com/overmighty created https://github.com/llvm/llvm-project/pull/86742
See https://github.com/llvm/llvm-project/pull/86577#discussion_r1540069558. cc @efriedma-quic @nickdesaulniers >From c615f656153fcb1d4158548660f87d1d69960864 Mon Sep 17 00:00:00 2001 From: OverMighty <its.overmig...@gmail.com> Date: Tue, 26 Mar 2024 21:25:59 +0000 Subject: [PATCH] [clang][ExprConst] Fix second arg of __builtin_{clzg,ctzg} not always being evaluated --- clang/lib/AST/ExprConstant.cpp | 30 +++++++++----- .../constant-builtins-all-args-evaluated.cpp | 39 +++++++++++++++++++ 2 files changed, 59 insertions(+), 10 deletions(-) create mode 100644 clang/test/Sema/constant-builtins-all-args-evaluated.cpp diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 5a36621dc5cce2..dae8f32fc02951 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -12361,12 +12361,17 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, if (!EvaluateInteger(E->getArg(0), Val, Info)) return false; + std::optional<APSInt> Fallback; + if (BuiltinOp == Builtin::BI__builtin_clzg && E->getNumArgs() > 1) { + APSInt FallbackTemp; + if (!EvaluateInteger(E->getArg(1), FallbackTemp, Info)) + return false; + Fallback = FallbackTemp; + } + if (!Val) { - if (BuiltinOp == Builtin::BI__builtin_clzg && E->getNumArgs() > 1) { - if (!EvaluateInteger(E->getArg(1), Val, Info)) - return false; - return Success(Val, E); - } + if (Fallback) + return Success(*Fallback, E); // When the argument is 0, the result of GCC builtins is undefined, // whereas for Microsoft intrinsics, the result is the bit-width of the @@ -12425,12 +12430,17 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, if (!EvaluateInteger(E->getArg(0), Val, Info)) return false; + std::optional<APSInt> Fallback; + if (BuiltinOp == Builtin::BI__builtin_ctzg && E->getNumArgs() > 1) { + APSInt FallbackTemp; + if (!EvaluateInteger(E->getArg(1), FallbackTemp, Info)) + return false; + Fallback = FallbackTemp; + } + if (!Val) { - if (BuiltinOp == Builtin::BI__builtin_ctzg && E->getNumArgs() > 1) { - if (!EvaluateInteger(E->getArg(1), Val, Info)) - return false; - return Success(Val, E); - } + if (Fallback) + return Success(*Fallback, E); return Error(E); } diff --git a/clang/test/Sema/constant-builtins-all-args-evaluated.cpp b/clang/test/Sema/constant-builtins-all-args-evaluated.cpp new file mode 100644 index 00000000000000..0dee74ddf690cf --- /dev/null +++ b/clang/test/Sema/constant-builtins-all-args-evaluated.cpp @@ -0,0 +1,39 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// expected-no-diagnostics + +constexpr int increment(int& x) { + x++; + return x; +} + +constexpr int test_clzg_0() { + int x = 0; + [[maybe_unused]] int unused = __builtin_clzg(0U, increment(x)); + return x; +} + +static_assert(test_clzg_0() == 1); + +constexpr int test_clzg_1() { + int x = 0; + [[maybe_unused]] int unused = __builtin_clzg(1U, increment(x)); + return x; +} + +static_assert(test_clzg_1() == 1); + +constexpr int test_ctzg_0() { + int x = 0; + [[maybe_unused]] int unused = __builtin_ctzg(0U, increment(x)); + return x; +} + +static_assert(test_ctzg_0() == 1); + +constexpr int test_ctzg_1() { + int x = 0; + [[maybe_unused]] int unused = __builtin_ctzg(1U, increment(x)); + return x; +} + +static_assert(test_ctzg_1() == 1); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits