https://gcc.gnu.org/g:e67cac3f380da82cff5354d898ec11dfc2492306

commit r15-10371-ge67cac3f380da82cff5354d898ec11dfc2492306
Author: Tobias Burnus <tbur...@baylibre.com>
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 <sloosem...@baylibre.com>
    (cherry picked from commit 97c1d2fa97afc59b02d2894b88069136145603e2)

Diff:
---
 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 0b7c3b9d3181..49ea86b98177 100644
--- a/gcc/omp-general.cc
+++ b/gcc/omp-general.cc
@@ -2727,7 +2727,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 000000000000..b6fc40ed46de
--- /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" } } */

Reply via email to