[clang] [clang][ExprConst] Fix second arg of __builtin_{clzg,ctzg} not always being evaluated (PR #86742)
https://github.com/efriedma-quic closed https://github.com/llvm/llvm-project/pull/86742 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][ExprConst] Fix second arg of __builtin_{clzg,ctzg} not always being evaluated (PR #86742)
overmighty wrote: Could someone merge this for me if it looks good to everyone? https://github.com/llvm/llvm-project/pull/86742 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][ExprConst] Fix second arg of __builtin_{clzg,ctzg} not always being evaluated (PR #86742)
https://github.com/nickdesaulniers approved this pull request. https://github.com/llvm/llvm-project/pull/86742 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][ExprConst] Fix second arg of __builtin_{clzg,ctzg} not always being evaluated (PR #86742)
https://github.com/overmighty updated https://github.com/llvm/llvm-project/pull/86742 >From c615f656153fcb1d4158548660f87d1d69960864 Mon Sep 17 00:00:00 2001 From: OverMighty Date: Tue, 26 Mar 2024 21:25:59 + Subject: [PATCH 1/3] [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 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 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 00..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); >From a0f90042bea48050e1e23aa95488e315fa3b40a2 Mon Sep 17 00:00:00 2001 From: OverMighty Date: Tue, 26 Mar 2024 23:09:56 + Subject: [PATCH 2/3] fixup! [clang][ExprConst] Fix second arg of __builtin_{clzg,ctzg} not always being evaluated Co-authored-by: Richard Smith --- clang/test/Sema/constant-builtins-all-args-evaluated.cpp | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/clang/test/Sema/constant-builtins-all-args-evaluated.cpp b/clang/test/Sema/constant-builtins-all-args-evaluated.cpp index 0dee74ddf690cf..f4452b1478e3fd 100644 --- a/clang/test/Sema/constant-builtins-all-args-evaluated.cpp +++ b/clang/test/Sema/constant-builtins-all-args-evaluated.cpp @@ -8,7 +8,7 @@ constexpr int increment(int& x) { constexpr int test_clzg_0() { int x = 0; - [[maybe_unused]] int unused = __builtin_clzg(0U, increment(x)); + (void)__builtin_clzg(0U, increment(x)); return x; } @@ -16,7 +16,7 @@ static_assert(test_clzg_0() == 1); constexpr int test_clzg_1() { int x = 0; - [[maybe_unused]] int unused = __builtin_clzg(1U, increment(x)); + (void)__builtin_clzg(1U, increment(x)); return x; } @@ -24,7 +24,7 @@ static_assert(test_clzg_1() == 1); constexpr int test_ctzg_0() { int x = 0; - [[maybe_unused]] int unused = __builtin_ctzg(0U, increment(x)); + (void)__builtin_ctzg(0U, increment(x)); return x; } @@ -32,7 +32,7 @@ static_assert(test_ctzg_0() == 1); constexpr int test_ctzg_1() { int x = 0; - [[maybe_unused]] int unused = __builtin_ctzg(
[clang] [clang][ExprConst] Fix second arg of __builtin_{clzg,ctzg} not always being evaluated (PR #86742)
@@ -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; + (void)__builtin_clzg(0U, increment(x)); overmighty wrote: Random thought that popped up while in bed at 2 AM: I probably could have just used `++x` as second argument. https://github.com/llvm/llvm-project/pull/86742 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][ExprConst] Fix second arg of __builtin_{clzg,ctzg} not always being evaluated (PR #86742)
https://github.com/efriedma-quic approved this pull request. LGTM https://github.com/llvm/llvm-project/pull/86742 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][ExprConst] Fix second arg of __builtin_{clzg,ctzg} not always being evaluated (PR #86742)
https://github.com/overmighty updated https://github.com/llvm/llvm-project/pull/86742 >From c615f656153fcb1d4158548660f87d1d69960864 Mon Sep 17 00:00:00 2001 From: OverMighty Date: Tue, 26 Mar 2024 21:25:59 + Subject: [PATCH 1/2] [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 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 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 00..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); >From a0f90042bea48050e1e23aa95488e315fa3b40a2 Mon Sep 17 00:00:00 2001 From: OverMighty Date: Tue, 26 Mar 2024 23:09:56 + Subject: [PATCH 2/2] fixup! [clang][ExprConst] Fix second arg of __builtin_{clzg,ctzg} not always being evaluated Co-authored-by: Richard Smith --- clang/test/Sema/constant-builtins-all-args-evaluated.cpp | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/clang/test/Sema/constant-builtins-all-args-evaluated.cpp b/clang/test/Sema/constant-builtins-all-args-evaluated.cpp index 0dee74ddf690cf..f4452b1478e3fd 100644 --- a/clang/test/Sema/constant-builtins-all-args-evaluated.cpp +++ b/clang/test/Sema/constant-builtins-all-args-evaluated.cpp @@ -8,7 +8,7 @@ constexpr int increment(int& x) { constexpr int test_clzg_0() { int x = 0; - [[maybe_unused]] int unused = __builtin_clzg(0U, increment(x)); + (void)__builtin_clzg(0U, increment(x)); return x; } @@ -16,7 +16,7 @@ static_assert(test_clzg_0() == 1); constexpr int test_clzg_1() { int x = 0; - [[maybe_unused]] int unused = __builtin_clzg(1U, increment(x)); + (void)__builtin_clzg(1U, increment(x)); return x; } @@ -24,7 +24,7 @@ static_assert(test_clzg_1() == 1); constexpr int test_ctzg_0() { int x = 0; - [[maybe_unused]] int unused = __builtin_ctzg(0U, increment(x)); + (void)__builtin_ctzg(0U, increment(x)); return x; } @@ -32,7 +32,7 @@ static_assert(test_ctzg_0() == 1); constexpr int test_ctzg_1() { int x = 0; - [[maybe_unused]] int unused = __builtin_ctzg(
[clang] [clang][ExprConst] Fix second arg of __builtin_{clzg,ctzg} not always being evaluated (PR #86742)
@@ -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)); overmighty wrote: I guess using a C-style cast is fine if it's to cast to `void`. Adding `-Wno-unused-value` sounds a bit excessive however. https://github.com/llvm/llvm-project/pull/86742 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][ExprConst] Fix second arg of __builtin_{clzg,ctzg} not always being evaluated (PR #86742)
@@ -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)); nickdesaulniers wrote: It's probably also possible to add -Wno-warn-unused-result to the RUN line. https://github.com/llvm/llvm-project/pull/86742 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][ExprConst] Fix second arg of __builtin_{clzg,ctzg} not always being evaluated (PR #86742)
@@ -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)); zygoloid wrote: Can you cast to `void` instead? ```suggestion (void)__builtin_clzg(0U, increment(x)); return x; } static_assert(test_clzg_0() == 1); constexpr int test_clzg_1() { int x = 0; (void)__builtin_clzg(1U, increment(x)); return x; } static_assert(test_clzg_1() == 1); constexpr int test_ctzg_0() { int x = 0; (void)__builtin_ctzg(0U, increment(x)); return x; } static_assert(test_ctzg_0() == 1); constexpr int test_ctzg_1() { int x = 0; (void)__builtin_ctzg(1U, increment(x)); ``` https://github.com/llvm/llvm-project/pull/86742 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][ExprConst] Fix second arg of __builtin_{clzg,ctzg} not always being evaluated (PR #86742)
@@ -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)); overmighty wrote: I can omit `[[maybe_unused]]` but not the whole `[[maybe_unused]] int unused =` part unless I add `// expected-warning ...` comments: ``` ~/projects/llvm-project clang-constexpr-builtin-clzg-ctzg-fix* ➜ cmake --build build --target check-clang-sema [0/1] Running lit suite /home/overmighty/projects/llvm-project/clang/test/Sema llvm-lit: /home/overmighty/projects/llvm-project/llvm/utils/lit/lit/llvm/config.py:502: note: using clang: /home/overmighty/projects/llvm-project/build/bin/clang FAIL: Clang :: Sema/constant-builtins-all-args-evaluated.cpp (950 of 981) TEST 'Clang :: Sema/constant-builtins-all-args-evaluated.cpp' FAILED Exit Code: 1 Command Output (stderr): -- RUN: at line 1: /home/overmighty/projects/llvm-project/build/bin/clang -cc1 -internal-isystem /home/overmighty/projects/llvm-project/build/lib/clang/19/include -nostdsysteminc -fsyntax-only -verify /home/overmighty/projects/llvm-project/clang/test/Sema/constant-builtins-all-args-evaluated.cpp + /home/overmighty/projects/llvm-project/build/bin/clang -cc1 -internal-isystem /home/overmighty/projects/llvm-project/build/lib/clang/19/include -nostdsysteminc -fsyntax-only -verify /home/overmighty/projects/llvm-project/clang/test/Sema/constant-builtins-all-args-evaluated.cpp error: 'expected-warning' diagnostics seen but not expected: File /home/overmighty/projects/llvm-project/clang/test/Sema/constant-builtins-all-args-evaluated.cpp Line 11: ignoring return value of function declared with const attribute File /home/overmighty/projects/llvm-project/clang/test/Sema/constant-builtins-all-args-evaluated.cpp Line 19: ignoring return value of function declared with const attribute File /home/overmighty/projects/llvm-project/clang/test/Sema/constant-builtins-all-args-evaluated.cpp Line 27: ignoring return value of function declared with const attribute File /home/overmighty/projects/llvm-project/clang/test/Sema/constant-builtins-all-args-evaluated.cpp Line 35: ignoring return value of function declared with const attribute 4 errors generated. -- Failed Tests (1): Clang :: Sema/constant-builtins-all-args-evaluated.cpp Testing Time: 12.72s Total Discovered Tests: 981 Unsupported: 88 (8.97%) Passed : 892 (90.93%) Failed : 1 (0.10%) FAILED: tools/clang/test/CMakeFiles/check-clang-sema /home/overmighty/projects/llvm-project/build/tools/clang/test/CMakeFiles/check-clang-sema cd /home/overmighty/projects/llvm-project/build/tools/clang/test && /usr/bin/python3.11 /home/overmighty/projects/llvm-project/build/./bin/llvm-lit -sv --param USE_Z3_SOLVER=0 /home/overmighty/projects/llvm-project/clang/test/Sema ninja: build stopped: subcommand failed. ~/projects/llvm-project clang-constexpr-builtin-clzg-ctzg-fix* ➜ ``` https://github.com/llvm/llvm-project/pull/86742 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][ExprConst] Fix second arg of __builtin_{clzg,ctzg} not always being evaluated (PR #86742)
@@ -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)); nickdesaulniers wrote: I think you can omit `[[maybe_unused]] int unused =` from each test? https://github.com/llvm/llvm-project/pull/86742 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][ExprConst] Fix second arg of __builtin_{clzg,ctzg} not always being evaluated (PR #86742)
@@ -12425,12 +12430,17 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, if (!EvaluateInteger(E->getArg(0), Val, Info)) return false; +std::optional Fallback; +if (BuiltinOp == Builtin::BI__builtin_ctzg && E->getNumArgs() > 1) { + APSInt FallbackTemp; + if (!EvaluateInteger(E->getArg(1), FallbackTemp, Info)) +return false; + Fallback = FallbackTemp; overmighty wrote: I guess using a `bool HasFallback` instead of `std::optional` would be more efficient but defaulting to `std::optional` feels like better practice. https://github.com/llvm/llvm-project/pull/86742 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][ExprConst] Fix second arg of __builtin_{clzg,ctzg} not always being evaluated (PR #86742)
llvmbot wrote: @llvm/pr-subscribers-clang Author: OverMighty (overmighty) Changes See https://github.com/llvm/llvm-project/pull/86577#discussion_r1540069558. cc @efriedma-quic @nickdesaulniers --- Full diff: https://github.com/llvm/llvm-project/pull/86742.diff 2 Files Affected: - (modified) clang/lib/AST/ExprConstant.cpp (+20-10) - (added) clang/test/Sema/constant-builtins-all-args-evaluated.cpp (+39) ``diff 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 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 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 00..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); `` https://github.com/llvm/llvm-project/pull/86742 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][ExprConst] Fix second arg of __builtin_{clzg,ctzg} not always being evaluated (PR #86742)
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 Date: Tue, 26 Mar 2024 21:25:59 + 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 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 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 00..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