https://github.com/loopacino created 
https://github.com/llvm/llvm-project/pull/238257

For all loop transforms, Clang cast loop as a `CapturedStmt` in the 
`-fopenmp-simd` mode, when these loop transforms keep a normal loop `ForStmt` 
and do not wrap a captured region. 

This in-turn results in a crash for all loop transforms (verified), as 
mentioned for flatten here (#231741).

Note: Only unroll was on the list and not other loop directives.

Fixes #231741

>From 649dfc634067c40274d4089cf983965033524b6c Mon Sep 17 00:00:00 2001
From: amtiwari <[email protected]>
Date: Tue, 3 Nov 2026 04:01:40 -0500
Subject: [PATCH] simd_issue_on_loop_transforms

---
 clang/lib/CodeGen/CGStmtOpenMP.cpp            |  4 +-
 .../loop_transformation_simd_codegen.cpp      | 81 +++++++++++++++++++
 2 files changed, 83 insertions(+), 2 deletions(-)
 create mode 100644 clang/test/OpenMP/loop_transformation_simd_codegen.cpp

diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp 
b/clang/lib/CodeGen/CGStmtOpenMP.cpp
index e63957df3e4069..61a47604efa05a 100644
--- a/clang/lib/CodeGen/CGStmtOpenMP.cpp
+++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp
@@ -9166,8 +9166,8 @@ void CodeGenFunction::EmitSimpleOMPExecutableDirective(
       D.getDirectiveKind() == OMPD_section ||
       D.getDirectiveKind() == OMPD_master ||
       D.getDirectiveKind() == OMPD_masked ||
-      D.getDirectiveKind() == OMPD_unroll ||
-      D.getDirectiveKind() == OMPD_assume) {
+      D.getDirectiveKind() == OMPD_assume ||
+      isOpenMPLoopTransformationDirective(D.getDirectiveKind())) {
     EmitStmt(D.getAssociatedStmt());
   } else {
     auto LPCRegion =
diff --git a/clang/test/OpenMP/loop_transformation_simd_codegen.cpp 
b/clang/test/OpenMP/loop_transformation_simd_codegen.cpp
new file mode 100644
index 00000000000000..3e7ce3d8abb4db
--- /dev/null
+++ b/clang/test/OpenMP/loop_transformation_simd_codegen.cpp
@@ -0,0 +1,81 @@
+// Verify that loop transformation directives do not crash under -fopenmp-simd
+// and that the original associated loops are emitted without OpenMP runtime
+// calls. Transforms are ignored in simd-only mode.
+//
+// RUN: %clang_cc1 -verify -triple x86_64-pc-linux-gnu -fopenmp-simd 
-fopenmp-version=61 -emit-llvm %s -o - | FileCheck %s 
--implicit-check-not="{{__kmpc|__tgt}}"
+// expected-no-diagnostics
+
+extern "C" void body(...);
+
+// CHECK-LABEL: define {{.*}}void @flatten_simd(
+// CHECK-NOT: .flatten.iv
+// CHECK: call void ({{.*}}) @body(
+extern "C" void flatten_simd(int n, int m) {
+#pragma omp flatten
+  for (int i = 0; i < n; ++i)
+    for (int j = 0; j < m; ++j)
+      body(i, j);
+}
+
+// CHECK-LABEL: define {{.*}}void @tile_simd(
+// CHECK: call void ({{.*}}) @body(
+extern "C" void tile_simd(int n) {
+#pragma omp tile sizes(2)
+  for (int i = 0; i < n; ++i)
+    body(i);
+}
+
+// CHECK-LABEL: define {{.*}}void @stripe_simd(
+// CHECK: call void ({{.*}}) @body(
+extern "C" void stripe_simd(int n) {
+#pragma omp stripe sizes(2)
+  for (int i = 0; i < n; ++i)
+    body(i);
+}
+
+// CHECK-LABEL: define {{.*}}void @reverse_simd(
+// CHECK: call void ({{.*}}) @body(
+extern "C" void reverse_simd(int n) {
+#pragma omp reverse
+  for (int i = 0; i < n; ++i)
+    body(i);
+}
+
+// CHECK-LABEL: define {{.*}}void @split_simd(
+// CHECK-NOT: .split.iv
+// CHECK: call void ({{.*}}) @body(
+extern "C" void split_simd(int n) {
+#pragma omp split counts(2, omp_fill)
+  for (int i = 0; i < n; ++i)
+    body(i);
+}
+
+// CHECK-LABEL: define {{.*}}void @interchange_simd(
+// CHECK: call void ({{.*}}) @body(
+extern "C" void interchange_simd(int n, int m) {
+#pragma omp interchange
+  for (int i = 0; i < n; ++i)
+    for (int j = 0; j < m; ++j)
+      body(i, j);
+}
+
+// CHECK-LABEL: define {{.*}}void @fuse_simd(
+// CHECK: call void ({{.*}}) @body(
+// CHECK: call void ({{.*}}) @body(
+extern "C" void fuse_simd(int n, int m) {
+#pragma omp fuse
+  {
+    for (int i = 0; i < n; ++i)
+      body(i);
+    for (int j = 0; j < m; ++j)
+      body(j);
+  }
+}
+
+// CHECK-LABEL: define {{.*}}void @unroll_simd(
+// CHECK: call void ({{.*}}) @body(
+extern "C" void unroll_simd(int n) {
+#pragma omp unroll
+  for (int i = 0; i < n; ++i)
+    body(i);
+}

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

Reply via email to