[llvm-branch-commits] [Clang][OpenMP] Add codegen test for reduction capture under nested default(firstprivate) (PR #216331)

via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Fri Aug 14 07:35:45 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Julian Brown (jtb20)

<details>
<summary>Changes</summary>

Add a CodeGen regression test covering a taskloop with default(firstprivate)
and a reduction nested inside a 'taskgraph' region. It asserts the reduction
variable is captured by reference by the enclosing taskgraph (its address is
stored into the captured record) and that the caller reads the reduced value
back out of that same storage. This guards the Sema fix that consults the
capture level's default DSA rather than the innermost directive's.

Assisted-By: Claude Opus 4.8


---
Full diff: https://github.com/llvm/llvm-project/pull/216331.diff


1 Files Affected:

- (added) clang/test/OpenMP/taskgraph_default_firstprivate_reduction_codegen.cpp (+42) 


``````````diff
diff --git a/clang/test/OpenMP/taskgraph_default_firstprivate_reduction_codegen.cpp b/clang/test/OpenMP/taskgraph_default_firstprivate_reduction_codegen.cpp
new file mode 100644
index 0000000000000..75c27202ae680
--- /dev/null
+++ b/clang/test/OpenMP/taskgraph_default_firstprivate_reduction_codegen.cpp
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=60 -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=60 -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=60 -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
+// expected-no-diagnostics
+
+// A taskloop with default(firstprivate) and a reduction, nested inside a
+// 'taskgraph' region.  The reduction variable 'res' must be captured *by
+// reference* by the enclosing taskgraph region (its address stored into the
+// captured record) so the reduction result propagates back to it.  A previous
+// bug consulted the innermost directive's default(firstprivate) when deciding
+// the enclosing region's capture kind and captured 'res' by copy, severing the
+// write-back (the caller then read the unmodified original, i.e. 0).
+
+#ifndef HEADER
+#define HEADER
+
+int run(int seed) {
+  int x = seed;
+  int res = 0;
+
+#pragma omp taskgraph graph_id(1)
+  {
+#pragma omp taskloop replayable num_tasks(4) default(firstprivate) reduction(+ : res)
+    for (int i = 0; i < 8; ++i)
+      res += x + i;
+  }
+
+  return res;
+}
+
+#endif
+
+// CHECK-LABEL: define {{.*}}@_Z3runi(
+// CHECK:         %[[CAP:.*]] = alloca %struct.anon, align 8
+// The reduction variable is captured BY REFERENCE (a pointer is stored into the
+// taskgraph captured record's first field), not by copy.
+// CHECK:         %[[FIELD:.*]] = getelementptr inbounds nuw %struct.anon, ptr %[[CAP]], i32 0, i32 0
+// CHECK-NEXT:    store ptr %[[RES:.*]], ptr %[[FIELD]], align 8
+// CHECK:         call void @__kmpc_taskgraph(
+// The caller reads the (reduced) value straight back out of that same storage.
+// CHECK:         %[[RET:.*]] = load i32, ptr %[[RES]], align 4
+// CHECK-NEXT:    ret i32 %[[RET]]

``````````

</details>


https://github.com/llvm/llvm-project/pull/216331


More information about the llvm-branch-commits mailing list