Skip to content

[OpenMP] Metadirective uses default for non-const user condition #82754

@Thyre

Description

@Thyre

Description

I've been looking at a few lesser used OpenMP directives recently and ran across metadirective. While the syntax always looks a bit intimidating, I wanted to know more about it and experimented with a few test cases. While doing this, I've noticed that Clang seems to use the default case whenever a user condition is used. To show this issue, I've prepared the following reproducer.

Reproducer

#include <cassert>
#include <iostream>
#include <omp.h>

int main( int argc, char** argv )
{
    constexpr size_t num_threads = 4;

    constexpr int constexpr_val = 1;
    #pragma omp metadirective \
        when( user= {condition(constexpr_val > 0)} : parallel num_threads( num_threads ) ) \
        default()
        {
            #pragma omp single
            assert( num_threads == omp_get_num_threads() );
        }

    const int const_val = 1;
    #pragma omp metadirective \
        when( user= {condition(const_val > 0)} : parallel num_threads( num_threads ) ) \
        default()
        {
            #pragma omp single
            assert( num_threads == omp_get_num_threads() );           
        }     

    int non_const_val = 1;
    #pragma omp metadirective \
        when( user= {condition(non_const_val > 0)} : parallel num_threads( num_threads ) ) \
        default()
        {
            #pragma omp single
            assert( num_threads == omp_get_num_threads() );
        }     
}

Here, I just want to make sure that the metadirective works. In theory, all three cases should result in the same: Having a parallel region with four threads. However, this is not the case with LLVM 15.0.7 and newer. Here's the output from LLVM trunk:

$ clang --version
clang version 19.0.0git (https://github.com/llvm/llvm-project.git 1fe6be8794964c011aeba7a66bd2dcd891d21ab0)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /opt/apps/software/Clang/trunk/bin
$ clang++ -fopenmp reproducer.cpp
$ ./a.out                                                                                                                                                                                                                                                          
a.out: reproducer.cpp:33: int main(int, char **): Assertion `num_threads == omp_get_num_threads()' failed.
[1]    1133016 IOT instruction (core dumped)  ./a.out

NVHPC 23.9 handles this test perfectly fine. oneAPI 2024.0 fails the same way and GCC 12.3.0 even fails the first assertion. Replacing the non_const_val with a true user condition (like std::cin > non_const_val) doesn't change the outcome of the test.
Looking at the IR, it seems like the metadirective is replaced by the default, resulting in no check at all if the parallel region should be used: https://godbolt.org/z/9oM5ooeE1

Metadata

Metadata

Assignees

No one assigned

    Labels

    clang:openmpOpenMP related changes to Clanggood first issuehttps://github.com/llvm/llvm-project/contributeopenmp

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions