Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OpenMP failing offload of static object if bitfields #132342

Open
KaruroChori opened this issue Mar 21, 2025 · 7 comments
Open

OpenMP failing offload of static object if bitfields #132342

KaruroChori opened this issue Mar 21, 2025 · 7 comments
Labels

Comments

@KaruroChori
Copy link

KaruroChori commented Mar 21, 2025

Tested in one of the latest commits. This works as intended:

    struct hello{
        struct sub{
            uint32_t uid;
            uint32_t gid ;
            uint32_t idx;
            uint32_t weak ;
        };
        
        #pragma omp declare target
        constexpr static sub A={1,1,1,false};
        #pragma omp end declare target
    };

while this does not:

    struct hello{
        struct sub{
            uint32_t uid:32;
            uint32_t gid:32;
            uint32_t idx:32;
            uint32_t weak:32;
        };
        
        #pragma omp declare target
        constexpr static sub A={1,1,1,false};
        #pragma omp end declare target
    };

Bitfields are intrinsically not working, and the error message is a generic sounding Offloading entry for declare target variable _ZN3sdf5hello1AE is incorrect: the address is invalid.
At the very least, a more explicit description would help but still, I see no reason why bitfields should not be allowed.

Potential workarounds like wrapping it in an union and setting it up through a different field will not work.

@llvmbot
Copy link
Member

llvmbot commented Mar 21, 2025

@llvm/issue-subscribers-openmp

Author: None (KaruroChori)

Tested in one of the latest commits. This works as intended: ``` struct hello{ struct sub{ uint32_t uid; uint32_t gid ; uint32_t idx; uint32_t weak ; };
    #pragma omp declare target
    constexpr static sub A={1,1,1,false};
    #pragma omp end declare target
};

while this does not:

struct hello{
    struct sub{
        uint32_t uid:32;
        uint32_t gid:32;
        uint32_t idx:32;
        uint32_t weak:32;
    };
    
    #pragma omp declare target
    constexpr static sub A={1,1,1,false};
    #pragma omp end declare target
};

Bitfields are intrinsically not working, and the error message is a generic sounding `Offloading entry for declare target variable _ZN3sdf5hello1AE is incorrect: the address is invalid.`
At the very least, a more explicit description would help but still, I see no reason why bitfields should not be allowed.

Potential workarounds like wrapping it in an union and setting it up through a different field will not work.
</details>

@shiltian
Copy link
Contributor

Hmm, wonder what the difference is in terms of IR representation of the two structs.

@KaruroChori
Copy link
Author

KaruroChori commented Mar 21, 2025

Honestly, no idea and I have no clue where to start to check that. But I would be mildly surprised if that was the case.
At the very least, I am pretty positive the layout of the final structs is equivalent, or my application would be broken (more broken).
I guess there could be a potential problem with endianess on some combinations of architectures maybe?

@KaruroChori
Copy link
Author

KaruroChori commented Mar 23, 2025

More info as I tested this further:

  • The issue is not specific for one single target. It will fail for both amd64 and nvptx.
  • Bitfields are perfectly usable within target regions. Also copying in and out of target regions seems fine for all scenarios I tested. The problem is specifically when using the declare target clause.

I also tried to compare the llvm bytecode, but I cannot spot any meaningful difference
https://godbolt.org/z/odKE5df1e

@jhuber6
Copy link
Contributor

jhuber6 commented Mar 23, 2025

The error is emitted here https://github.com/llvm/llvm-project/blob/main/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp#L9499. We need an address to be able to emit an offloading entry, because an offloading entry fundamentally is a named symbol in the ELF that the device runtime can look up and copy / read to. A bitfield should have an address, but I'm going to guess that something inside of OpenMP gets confused when it's used. I don't know anything more than that, maybe @alexey-bataev has a guess.

@alexey-bataev
Copy link
Member

Bitfields are not addressable by the standard

@KaruroChori
Copy link
Author

KaruroChori commented Mar 23, 2025

The bit-aligned fields inside a structure surely are not, but I would assume there should be no problem addressing full instances of structs, even if they have bitfields inside.
Is it failing because it wants each field to be addressable?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

6 participants