{u}int_fastN_t Types and Preprocessor Defines

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

{u}int_fastN_t Types and Preprocessor Defines

Vassil Vassilev via cfe-dev
Hi cfe-dev!

I am currently investigating an ABI incompatibility for RISC-V between Clang and GCC.

GCC defines `{u}int_fast8_t` and `{u}int_fast16_t` to be the same sizes as `{u}int32_t` or `{u}int64_t`, depending on the underlying hardware register length (RISC-V has a 32-bit architecture and a 64-bit architecture). This, to me, makes sense, as there are no sub-registers in the architecture. The `{u}int_least8_t` and `{u}int_least16_t` match their bitwidths.

However, in Clang, I believe we cannot have `{u}int_fastN_t` different from the equivalent `{u}int_leastN_t`, as the codebase currently stands, due to both `DefineFastIntType` and the definitions in `clang/lib/Headers/stdint.h`.

Point one is while investigating this, Luis discovered that on x86 these types *do* differ in size: https://godbolt.org/z/rrNGPa
I cannot work out how x86 manages this, because my reading of stdint.h and the clang codebase do not show any codepaths where this would work. Any help to shed light on how this is done would be useful.

Point two is that I have started a patch to add a `getFastIntTypeByWidth` hook for Clang, which by default defers to `getLeastIntTypeByWidth`, to match the current behaviour. The comment in `DefineFastIntType` points to me having to update `stdint.h` to ensure these match, and any guidance about doing so would be appreciated. The patch is here: https://reviews.llvm.org/D80963 

I know psABIs are a minefield (to say nothing of preprocessors ;) ), so I'm keen to see if we can add this functionality for RISC-V without breaking any other architectures. psABIs are hard enough to verify at the best of times.

Thanks In Advance,

Sam

--
Sam Elliott
Software Team Lead
Senior Software Developer - LLVM and OpenTitan
lowRISC CIC

_______________________________________________
cfe-dev mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: {u}int_fastN_t Types and Preprocessor Defines

Vassil Vassilev via cfe-dev
I think for X86, clang's stdint.h is ignored due to this part of stdint.h. You'll get different sizes if you pass -ffreestanding.

/* If we're hosted, fall back to the system's stdint.h, which might have
 * additional definitions.
 */
#if __STDC_HOSTED__ && __has_include_next(<stdint.h>)

~Craig


On Mon, Jun 1, 2020 at 5:09 PM Sam Elliott via cfe-dev <[hidden email]> wrote:
Hi cfe-dev!

I am currently investigating an ABI incompatibility for RISC-V between Clang and GCC.

GCC defines `{u}int_fast8_t` and `{u}int_fast16_t` to be the same sizes as `{u}int32_t` or `{u}int64_t`, depending on the underlying hardware register length (RISC-V has a 32-bit architecture and a 64-bit architecture). This, to me, makes sense, as there are no sub-registers in the architecture. The `{u}int_least8_t` and `{u}int_least16_t` match their bitwidths.

However, in Clang, I believe we cannot have `{u}int_fastN_t` different from the equivalent `{u}int_leastN_t`, as the codebase currently stands, due to both `DefineFastIntType` and the definitions in `clang/lib/Headers/stdint.h`.

Point one is while investigating this, Luis discovered that on x86 these types *do* differ in size: https://godbolt.org/z/rrNGPa
I cannot work out how x86 manages this, because my reading of stdint.h and the clang codebase do not show any codepaths where this would work. Any help to shed light on how this is done would be useful.

Point two is that I have started a patch to add a `getFastIntTypeByWidth` hook for Clang, which by default defers to `getLeastIntTypeByWidth`, to match the current behaviour. The comment in `DefineFastIntType` points to me having to update `stdint.h` to ensure these match, and any guidance about doing so would be appreciated. The patch is here: https://reviews.llvm.org/D80963

I know psABIs are a minefield (to say nothing of preprocessors ;) ), so I'm keen to see if we can add this functionality for RISC-V without breaking any other architectures. psABIs are hard enough to verify at the best of times.

Thanks In Advance,

Sam

--
Sam Elliott
Software Team Lead
Senior Software Developer - LLVM and OpenTitan
lowRISC CIC

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

_______________________________________________
cfe-dev mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: {u}int_fastN_t Types and Preprocessor Defines

Vassil Vassilev via cfe-dev
In reply to this post by Vassil Vassilev via cfe-dev
The test in your godbolt link is using the system stdint.h, not the one shipped by clang.  So it's ignoring whatever clang thinks the size of the types should be.

clang's stdint.h should probably be changed to use the __INT_LEAST* and __INT_FAST* macros.  I think the reason it currently doesn't use them is that the macros didn't exist when clang's stdint.h was originally written.

-Eli

-----Original Message-----
From: cfe-dev <[hidden email]> On Behalf Of Sam Elliott via cfe-dev
Sent: Monday, June 1, 2020 5:09 PM
To: [hidden email] Developers <[hidden email]>
Subject: [EXT] [cfe-dev] {u}int_fastN_t Types and Preprocessor Defines

Hi cfe-dev!

I am currently investigating an ABI incompatibility for RISC-V between Clang and GCC.

GCC defines `{u}int_fast8_t` and `{u}int_fast16_t` to be the same sizes as `{u}int32_t` or `{u}int64_t`, depending on the underlying hardware register length (RISC-V has a 32-bit architecture and a 64-bit architecture). This, to me, makes sense, as there are no sub-registers in the architecture. The `{u}int_least8_t` and `{u}int_least16_t` match their bitwidths.

However, in Clang, I believe we cannot have `{u}int_fastN_t` different from the equivalent `{u}int_leastN_t`, as the codebase currently stands, due to both `DefineFastIntType` and the definitions in `clang/lib/Headers/stdint.h`.

Point one is while investigating this, Luis discovered that on x86 these types *do* differ in size: https://godbolt.org/z/rrNGPa
I cannot work out how x86 manages this, because my reading of stdint.h and the clang codebase do not show any codepaths where this would work. Any help to shed light on how this is done would be useful.

Point two is that I have started a patch to add a `getFastIntTypeByWidth` hook for Clang, which by default defers to `getLeastIntTypeByWidth`, to match the current behaviour. The comment in `DefineFastIntType` points to me having to update `stdint.h` to ensure these match, and any guidance about doing so would be appreciated. The patch is here: https://reviews.llvm.org/D80963

I know psABIs are a minefield (to say nothing of preprocessors ;) ), so I'm keen to see if we can add this functionality for RISC-V without breaking any other architectures. psABIs are hard enough to verify at the best of times.

Thanks In Advance,

Sam

--
Sam Elliott
Software Team Lead
Senior Software Developer - LLVM and OpenTitan
lowRISC CIC

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