[clang] [Clang][OpenMP] Fix crash on `safelen` and `simdlen` of different types (PR #228700)
Akash Manna via cfe-commits
cfe-commits at lists.llvm.org
Sat Oct 3 04:58:16 PDT 2026
https://github.com/akash-manna-sky created https://github.com/llvm/llvm-project/pull/228700
Fixes #108367
When a `simd` directive has both `safelen` and `simdlen`, Sema checks that `simdlen` is not greater than `safelen`. It compared the two values with `APSInt`'s `operator>`, which needs both operands to have the same bit width and signedness. But each clause keeps its argument in the type it was written with, so in `safelen(11111111111) simdlen(1)` one value is 64 bits wide and the other 32, and the comparison asserted. Mixed signedness, as in `safelen(8u) simdlen(4)`, hit a second assertion on the same line. A build without assertions rejected the valid code instead, as if `simdlen` were the larger value.
The check now uses `APSInt::compareValues`, which extends the operands to a common width and handles mixed signedness, so the values themselves are compared. The error is still emitted whenever `simdlen` is larger than `safelen`.
>From e1b54881c1640311f76c97bfa4013a8f091e2052 Mon Sep 17 00:00:00 2001
From: Akash Manna <akash.manna.mymail at gmail.com>
Date: Sat, 3 Oct 2026 17:26:16 +0530
Subject: [PATCH] [Clang][OpenMP] Fix crash on `safelen` and `simdlen` of
different types
When a simd directive has both clauses, Sema checks that simdlen is not
greater than safelen. The values were compared with APSInt's operator>,
which requires operands of the same bit width and signedness, but each
clause keeps its argument in the type it was written with. A pair such
as safelen(11111111111) simdlen(1) asserted, and a build without
assertions rejected it as if simdlen were the larger value.
Compare the values with APSInt::compareValues instead, which handles
operands of different widths and signedness.
Fixes #108367
---
clang/docs/ReleaseNotes.md | 2 ++
clang/lib/Sema/SemaOpenMP.cpp | 2 +-
clang/test/OpenMP/simd_misc_messages.c | 32 ++++++++++++++++++++++++++
3 files changed, 35 insertions(+), 1 deletion(-)
diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index 6afaa6675be7cd..7538f3e1825fc7 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -1071,6 +1071,8 @@ The `alpha.cplusplus.UseAfterLifetimeEnd` checker was renamed to `alpha.core.Use
- Mapping of expressions with base-pointers through a user-defined mapper (e.g.
`map(s.p[0:n])`) now conforms to OpenMP's conditional pointer-attachment,
matching the behavior of such maps outside a mapper.
+- Fixed a crash when the `safelen` and `simdlen` clauses of an OpenMP directive
+ have arguments of different integer types. (#GH108367)
- The `holds` clause on the `assume` directive now lowers side-effect-free
conditions to `llvm.assume`, enabling downstream optimizations. Previously
the clause was parsed but its condition was discarded without effect.
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index 6ef86b8391f40c..315f869e0b72e7 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -11371,7 +11371,7 @@ static bool checkSimdlenSafelenSpecified(Sema &S,
// If both simdlen and safelen clauses are specified, the value of the
// simdlen parameter must be less than or equal to the value of the safelen
// parameter.
- if (SimdlenRes > SafelenRes) {
+ if (llvm::APSInt::compareValues(SimdlenRes, SafelenRes) > 0) {
S.Diag(SimdlenLength->getExprLoc(),
diag::err_omp_wrong_simdlen_safelen_values)
<< SimdlenLength->getSourceRange() << SafelenLength->getSourceRange();
diff --git a/clang/test/OpenMP/simd_misc_messages.c b/clang/test/OpenMP/simd_misc_messages.c
index 818bd9056edbc3..c3e2bcbe2ccde5 100644
--- a/clang/test/OpenMP/simd_misc_messages.c
+++ b/clang/test/OpenMP/simd_misc_messages.c
@@ -274,6 +274,38 @@ void test_safelen_simdlen(void) {
#pragma omp simd safelen(5) simdlen(6)
for (i = 0; i < 16; ++i)
;
+#pragma omp simd safelen(8) simdlen(4)
+ for (i = 0; i < 16; ++i)
+ ;
+// expected-error at +1 {{the value of 'simdlen' parameter must be less than or equal to the value of the 'safelen' parameter}}
+#pragma omp simd safelen(4) simdlen(8)
+ for (i = 0; i < 16; ++i)
+ ;
+}
+
+// GH108367
+void test_safelen_simdlen_types(void) {
+#pragma omp simd safelen(11111111111) simdlen(1)
+ for (int i = 0; i < 10; i++)
+ ;
+// expected-error at +1 {{the value of 'simdlen' parameter must be less than or equal to the value of the 'safelen' parameter}}
+#pragma omp simd simdlen(11111111111) safelen(1)
+ for (int i = 0; i < 10; i++)
+ ;
+// expected-error at +1 {{the value of 'simdlen' parameter must be less than or equal to the value of the 'safelen' parameter}}
+#pragma omp simd safelen(11111111111) simdlen(22222222222)
+ for (int i = 0; i < 10; i++)
+ ;
+#pragma omp simd safelen(22222222222) simdlen(11111111111)
+ for (int i = 0; i < 10; i++)
+ ;
+#pragma omp simd safelen(8u) simdlen(4)
+ for (int i = 0; i < 10; i++)
+ ;
+// expected-error at +1 {{the value of 'simdlen' parameter must be less than or equal to the value of the 'safelen' parameter}}
+#pragma omp simd safelen(4u) simdlen(8)
+ for (int i = 0; i < 10; i++)
+ ;
}
void test_collapse(void) {
More information about the cfe-commits
mailing list