https://github.com/zahiraam updated 
https://github.com/llvm/llvm-project/pull/222401

>From 4534a764eb60f89e4c38ca14e4b7a43f2e037f61 Mon Sep 17 00:00:00 2001
From: Zahira Ammarguellat <[email protected]>
Date: Wed, 9 Sep 2026 10:28:38 -0700
Subject: [PATCH 1/2] [OpenMP] Accept nested loop transformations as body of
 tile/stripe/reverse

---
 clang/lib/AST/StmtOpenMP.cpp                  | 18 +++--
 .../OpenMP/tile_stripe_reverse_ast_print.cpp  | 68 +++++++++++++++++++
 2 files changed, 81 insertions(+), 5 deletions(-)
 create mode 100644 clang/test/OpenMP/tile_stripe_reverse_ast_print.cpp

diff --git a/clang/lib/AST/StmtOpenMP.cpp b/clang/lib/AST/StmtOpenMP.cpp
index 44656266bcf08..a8d53c674b9cb 100644
--- a/clang/lib/AST/StmtOpenMP.cpp
+++ b/clang/lib/AST/StmtOpenMP.cpp
@@ -133,10 +133,12 @@ OMPLoopBasedDirective::tryToFindNextInnerLoop(Stmt 
*CurStmt,
         for (Stmt *S : CS->body()) {
           if (!S)
             continue;
-          // Peek past an OMPCanonicalLoop wrapper and/or an intra-tile hint to
-          // check whether this child is loop-like; keep the original (wrapped)
-          // node in CurStmt so the hint still reaches the loop-analysis
+          // Peek past a single-child container so a nested loop or
+          // loop-transformation directive (e.g. `#pragma omp reverse` inside
+          // the body of an outer loop) is recognized here. Preserve any
+          // intra-tile hint wrapper so it still reaches the loop-analysis
           // callback.
+          S = ignoreContainersKeepingIntraTileHint(S);
           Stmt *Inner = S;
           if (auto *CanonLoop = dyn_cast<OMPCanonicalLoop>(Inner))
             Inner = CanonLoop->getLoopStmt();
@@ -152,7 +154,6 @@ OMPLoopBasedDirective::tryToFindNextInnerLoop(Stmt *CurStmt,
             CurStmt = S;
             continue;
           }
-          S = S->IgnoreContainers();
           if (auto *InnerCS = dyn_cast_or_null<CompoundStmt>(S))
             NextStatements.push_back(InnerCS);
         }
@@ -177,6 +178,12 @@ bool OMPLoopBasedDirective::doForAllLoops(
         OnTransformationCallback) {
   CurStmt = ignoreContainersKeepingIntraTileHint(CurStmt);
   for (unsigned Cnt = 0; Cnt < NumLoops; ++Cnt) {
+    // If we peel a loop-transformation directive, the enclosing ForStmt is
+    // compiler-synthesized and its body may hold helper statements (e.g.
+    // `reverse` injects `.reversed.iv` and update exprs) before the next
+    // loop. Scan it as an imperfect nest so that e.g. `omp tile` followed by
+    // `omp reverse` is accepted.
+    bool PeeledTransformation = false;
     while (true) {
       auto *Dir = dyn_cast<OMPLoopTransformationDirective>(CurStmt);
       if (!Dir)
@@ -202,6 +209,7 @@ bool OMPLoopBasedDirective::doForAllLoops(
       }
 
       CurStmt = TransformedStmt;
+      PeeledTransformation = true;
     }
     if (auto *CanonLoop = dyn_cast<OMPCanonicalLoop>(CurStmt))
       CurStmt = CanonLoop->getLoopStmt();
@@ -224,7 +232,7 @@ bool OMPLoopBasedDirective::doForAllLoops(
       CurStmt = cast<CXXForRangeStmt>(LoopStmt)->getBody();
     }
     CurStmt = OMPLoopBasedDirective::tryToFindNextInnerLoop(
-        CurStmt, TryImperfectlyNestedLoops);
+        CurStmt, TryImperfectlyNestedLoops || PeeledTransformation);
   }
   return true;
 }
diff --git a/clang/test/OpenMP/tile_stripe_reverse_ast_print.cpp 
b/clang/test/OpenMP/tile_stripe_reverse_ast_print.cpp
new file mode 100644
index 0000000000000..1eee82f241982
--- /dev/null
+++ b/clang/test/OpenMP/tile_stripe_reverse_ast_print.cpp
@@ -0,0 +1,68 @@
+// Check no warnings/errors
+// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fopenmp -fopenmp-version=60 \
+// RUN: -fsyntax-only -verify %s
+// expected-no-diagnostics
+
+// Check AST and unparsing
+// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fopenmp -fopenmp-version=60 \
+// RUN: -ast-print %s | FileCheck %s --check-prefix=PRINT
+
+// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fopenmp -fopenmp-version=60 \
+// RUN: -emit-pch -o %t %s
+// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fopenmp -fopenmp-version=60 \
+// RUN: -include-pch %t -ast-print %s | FileCheck %s --check-prefix=PRINT
+
+#ifndef HEADER
+#define HEADER
+
+extern "C" void body(...);
+
+// PRINT-LABEL: void tile_then_reverse(
+void tile_then_reverse() {
+  // PRINT: #pragma omp tile sizes(2, 2)
+  // PRINT: #pragma omp reverse
+#pragma omp tile sizes(2, 2)
+#pragma omp reverse
+  for (int i = 0; i < 20; ++i)
+    for (int j = 0; j < 20; ++j)
+      body(i, j);
+}
+
+// PRINT-LABEL: void stripe_then_reverse(
+void stripe_then_reverse() {
+  // PRINT: #pragma omp stripe sizes(2, 2)
+  // PRINT: #pragma omp reverse
+#pragma omp stripe sizes(2, 2)
+#pragma omp reverse
+  for (int i = 0; i < 20; ++i)
+    for (int j = 0; j < 20; ++j)
+      body(i, j);
+}
+
+// PRINT-LABEL: void tile_over_inner_reverse(
+void tile_over_inner_reverse() {
+  // PRINT: #pragma omp tile sizes(2, 2)
+#pragma omp tile sizes(2, 2)
+#pragma omp reverse
+  for (int j = 0; j < 20; ++j) {
+    // PRINT: #pragma omp reverse
+#pragma omp reverse
+    for (int i = 0; i < 20; ++i)
+      body(j, i);
+  }
+}
+
+// PRINT-LABEL: void stripe_over_inner_reverse(
+void stripe_over_inner_reverse() {
+  // PRINT: #pragma omp stripe sizes(2, 2)
+#pragma omp stripe sizes(2, 2)
+#pragma omp reverse
+  for (int j = 0; j < 20; ++j) {
+    // PRINT: #pragma omp reverse
+#pragma omp reverse
+    for (int i = 0; i < 20; ++i)
+      body(j, i);
+  }
+}
+
+#endif

>From 910f2617eb41e1fd82c4d5d76ec08eacb5375e51 Mon Sep 17 00:00:00 2001
From: Zahira Ammarguellat <[email protected]>
Date: Tue, 15 Sep 2026 11:01:11 -0700
Subject: [PATCH 2/2] Added test

---
 clang/test/OpenMP/tile_stripe_reverse_ast_print.cpp | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/clang/test/OpenMP/tile_stripe_reverse_ast_print.cpp 
b/clang/test/OpenMP/tile_stripe_reverse_ast_print.cpp
index 1eee82f241982..5eee992f50483 100644
--- a/clang/test/OpenMP/tile_stripe_reverse_ast_print.cpp
+++ b/clang/test/OpenMP/tile_stripe_reverse_ast_print.cpp
@@ -65,4 +65,15 @@ void stripe_over_inner_reverse() {
   }
 }
 
+// PRINT-LABEL: void for_collapse_then_reverse(
+void for_collapse_then_reverse() {
+  // PRINT: #pragma omp for collapse(2)
+  // PRINT: #pragma omp reverse
+#pragma omp for collapse(2)
+#pragma omp reverse
+  for (int j = 0; j < 20; j += 2)
+    for (int i = 0; i < 20; i += 3)
+      body(j, i);
+}
+
 #endif

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to