diff --git a/llvm/include/llvm/Frontend/OpenMP/ConstructDecompositionT.h b/llvm/include/llvm/Frontend/OpenMP/ConstructDecompositionT.h index 349d862135d8cf..b93bc594a82bf3 100644 --- a/llvm/include/llvm/Frontend/OpenMP/ConstructDecompositionT.h +++ b/llvm/include/llvm/Frontend/OpenMP/ConstructDecompositionT.h @@ -1114,6 +1114,11 @@ bool ConstructDecompositionT::applyClause( template bool ConstructDecompositionT::split() { bool success = true; + auto isImplicit = [this](const ClauseTy *node) { + return llvm::any_of( + implicit, [node](const ClauseTy &clause) { return &clause == node; }); + }; + for (llvm::omp::Directive leaf : llvm::omp::getLeafConstructsOrSelf(construct)) leafs.push_back(LeafReprInternal{leaf, /*clauses=*/{}}); @@ -1153,9 +1158,10 @@ template bool ConstructDecompositionT::split() { for (const ClauseTy *node : nodes) { if (skip(node)) continue; - success = - success && + bool result = std::visit([&](auto &&s) { return applyClause(s, node); }, node->u); + if (!isImplicit(node)) + success = success && result; } // Apply "allocate". diff --git a/llvm/unittests/Frontend/OpenMPDecompositionTest.cpp b/llvm/unittests/Frontend/OpenMPDecompositionTest.cpp index c70341b5a86d24..f9541131e4b23d 100644 --- a/llvm/unittests/Frontend/OpenMPDecompositionTest.cpp +++ b/llvm/unittests/Frontend/OpenMPDecompositionTest.cpp @@ -1100,4 +1100,21 @@ TEST_F(OpenMPDecompositionTest, Nowait1) { ASSERT_EQ(Dir1, "parallel"); // (23) ASSERT_EQ(Dir2, "for"); // (23) } + +// --- + +// Check that "simd linear(x)" does not fail despite the implied "firstprivate" +// (which "simd" does not allow). +TEST_F(OpenMPDecompositionTest, Misc1) { + omp::Object x{"x"}; + omp::List Clauses{ + {OMPC_linear, + omp::clause::Linear{{std::nullopt, std::nullopt, std::nullopt, {x}}}}, + }; + + omp::ConstructDecomposition Dec(AnyVersion, Helper, OMPD_simd, Clauses); + ASSERT_EQ(Dec.output.size(), 1u); + std::string Dir0 = stringify(Dec.output[0]); + ASSERT_EQ(Dir0, "simd linear(, , , (x)) lastprivate(, (x))"); +} } // namespace