While working on a different patch, Sandra found out that due to tree sharing, the user condition in a context selector was only evaluated once - which is bad if it is dynamic (here: global variable) that can be changed.
The included testcase is a slightly enhanced version of hers, attached to the PR. Committed to mainline as r16-3946-g97c1d2fa97afc5 I think this is a candidate for GCC 15 backporting due to the badness vs. change size/risk [As dynamic selectors are only supported since GCC 15 [this function is new since r15-6895-g1294b819e1207c]), it is strictly GCC 15.] Thanks for the testcase and debugging Sandra! Tobias
commit 97c1d2fa97afc59b02d2894b88069136145603e2 Author: Tobias Burnus <[email protected]> Date: Thu Sep 18 11:07:50 2025 +0200 OpenMP: Unshare expr in context-selector condition [PR121922] As the testcase shows, a missing unshare_expr caused that the condition was only evaluated once instead of every time when a 'declare variant' was resolved. PR middle-end/121922 gcc/ChangeLog: * omp-general.cc (omp_dynamic_cond): Use 'unshare_expr' for the user condition. libgomp/ChangeLog: * testsuite/libgomp.c-c++-common/declare-variant-1.c: New test. Co-authored-by: Sandra Loosemore <[email protected]> --- gcc/omp-general.cc | 2 +- .../libgomp.c-c++-common/declare-variant-1.c | 40 ++++++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/gcc/omp-general.cc b/gcc/omp-general.cc index c799b8936f9..973b246cfdb 100644 --- a/gcc/omp-general.cc +++ b/gcc/omp-general.cc @@ -2733,7 +2733,7 @@ omp_dynamic_cond (tree ctx, tree supercontext) /* The user condition is not dynamic if it is constant. */ if (!tree_fits_shwi_p (expr)) - user_cond = expr; + user_cond = unshare_expr (expr); } /* Build the "target_device" part of the dynamic selector. In the diff --git a/libgomp/testsuite/libgomp.c-c++-common/declare-variant-1.c b/libgomp/testsuite/libgomp.c-c++-common/declare-variant-1.c new file mode 100644 index 00000000000..b6fc40ed46d --- /dev/null +++ b/libgomp/testsuite/libgomp.c-c++-common/declare-variant-1.c @@ -0,0 +1,40 @@ +/* { dg-do run } */ +/* { dg-additional-options "-fdump-tree-gimple" } */ + +/* PR middle-end/121922 */ + +/* Failed to re-check the global flag due to tree sharing. */ + +extern int flag; +int flag = 0; + +int +test_with_flag () +{ + return flag; +} + +#pragma omp declare variant (test_with_flag) match (user={condition(score(10): flag > 1)}) +int +test () +{ + return 0; +} + +void +doit () +{ + flag = 0; + if (test () != 0) __builtin_abort (); + flag = 1; + if (test () != 0) __builtin_abort (); + flag = 42; + if (test () != 42) __builtin_abort (); +} + +int main () +{ + doit (); +} + +/* { dg-final { scan-tree-dump-times "flag\\.\[^=\]*= flag;\[\n\r\]+ *if \\(flag\\.\[^>\]*> 1\\)" 3 "gimple" } } */
