Bug 90600 - incompatible 64-bit-types in x86-intrinsics
Summary: incompatible 64-bit-types in x86-intrinsics
Status: UNCONFIRMED
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 9.1.1
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2019-05-23 16:14 UTC by g.peterhoff
Modified: 2019-05-24 08:24 UTC (History)
2 users (show)

See Also:
Host: x86-64
Target: x86-64
Build:
Known to work:
Known to fail: 9.1.1
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description g.peterhoff 2019-05-23 16:14:35 UTC
COLLECT_GCC=gcc-9
COLLECT_LTO_WRAPPER=/usr/lib64/gcc/x86_64-suse-linux/9/lto-wrapper
OFFLOAD_TARGET_NAMES=hsa:nvptx-none
Target: x86_64-suse-linux
Configured with: ../configure --prefix=/usr --infodir=/usr/share/info --mandir=/usr/share/man --libdir=/usr/lib64 --libexecdir=/usr/lib64 --enable-languages=c,c++,objc,fortran,obj-c++,ada,go,d --enable-offload-targets=hsa,nvptx-none=/usr/nvptx-none, --without-cuda-driver --disable-werror --with-gxx-include-dir=/usr/include/c++/9 --enable-ssp --disable-libssp --disable-libvtv --disable-cet --disable-libcc1 --enable-plugin --with-bugurl=https://bugs.opensuse.org/ --with-pkgversion='SUSE Linux' --with-slibdir=/lib64 --with-system-zlib --enable-libstdcxx-allocator=new --disable-libstdcxx-pch --enable-libphobos --enable-version-specific-runtime-libs --with-gcc-major-version-only --enable-linker-build-id --enable-linux-futex --enable-gnu-indirect-function --program-suffix=-9 --without-system-libunwind --enable-multilib --with-arch-32=x86-64 --with-tune=generic --with-build-config=bootstrap-lto-lean --enable-link-mutex --build=x86_64-suse-linux --host=x86_64-suse-linux
Thread model: posix
gcc version 9.1.1 20190520 [gcc-9-branch revision 271396] (SUSE Linux) 

snip 1:
using intrinsic_int64_t = decltype(_mm_cvtsi128_si64(__m128i{}));
std::cout<<std::boolalpha;
std::cout<<(std::is_same_v<int64_t, intrinsic_int64_t>)<<std::endl;
std::cout<<(sizeof(int64_t) == sizeof(intrinsic_int64_t))<<std::endl;
->
false
true


snip 2:
uint64_t	a, b, r;
uint8_t		carry;
carry = _addcarry_u64(carry, a, b, &r);
->
error: invalid conversion from ‘uint64_t*’ {aka ‘long unsigned int*’} to ‘long long unsigned int*’ [-fpermissive]


Hello,
you're using incompatible 64-bit-types in the x86-intrinsics. Why are not always and everywhere the default-types taken from "types.h"?
PS: Is there any hope that the completely outdated (from the 70') short/int/long-types will be completely replaced by u/intX_t (keywords!)? With (signed/unsigned) char != u/int8_t, so that you can write:
uint8_t	ui = 65;
int8_t	si = 65;
unsigned char	uc = 65;
signed char	sc = 65;
char		c = 65;
std::cout << ui ...
->
65
65
A
A
A

reguards
Gero
Comment 1 Jakub Jelinek 2019-05-23 17:04:30 UTC
Note, clang agrees with gcc here, and I don't think it is a good idea to change this incompatibly.
Comment 2 g.peterhoff 2019-05-23 18:06:17 UTC
Am 23.05.19 um 19:04 schrieb jakub at gcc dot gnu.org:
> Note, clang agrees with gcc here, and I don't think it is a good idea to change
> this incompatibly.
I think it would be better if there is (on the respective platform) only exactly an absolute type for the significant size and this is consistently used everywhere. Then such problems can not occur at all.
PS: I miss the IO-Routines for __int128 (u/int128_t), clang has this. Will they be retrofitted? On 32-bit platforms (and smaller) these types do not exist either. (Can that clang?)
Comment 3 Marc Glisse 2019-05-23 18:11:52 UTC
Intel documents that it uses "unsigned __int64" but I don't see where they document what __int64 is. We could take a "void *out" argument and cast it inside the function, but that would lose useful diagnostics for people trying to pass a 32-bit type. We could overload in C++. Not sure any of that is worth the trouble, those interfaces are target-specific anyway.
Comment 4 g.peterhoff 2019-05-23 19:27:51 UTC
Am 23.05.19 um 20:11 schrieb glisse at gcc dot gnu.org:
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90600
> 
> --- Comment #3 from Marc Glisse <glisse at gcc dot gnu.org> ---
> Intel documents that it uses "unsigned __int64" but I don't see where they
> document what __int64 is. We could take a "void *out" argument and cast it
> inside the function, but that would lose useful diagnostics for people trying
> to pass a 32-bit type. We could overload in C++. Not sure any of that is worth
> the trouble, those interfaces are target-specific anyway.
> 
What else should "unsigned __int64" be than a uint64_t (0..2^64-1)? Then this would look exactly like this:

external __inline uint8_t
__attribute __ ((__ gnu_inline__, __always_inline__, __artificial__))
_addcarry_u64 (uint8_t __CF, uint64_t __X, uint64_t __Y, uint64_t * __P)
{
    return __builtin_ia32_addcarryx_u64 (__CF, __X, __Y, __P);
}

And I miss addcarry/subborrow for uint8/16/128. You could make that available as a general __builtin :-)
Of course it would be better if such functions are included in the C/C++ standard ...
Comment 5 Marc Glisse 2019-05-23 22:01:36 UTC
(In reply to g.peterhoff from comment #4)
> What else should "unsigned __int64" be than a uint64_t (0..2^64-1)?

If they meant uint64_t, they would spell it uint64_t.

> And I miss addcarry/subborrow for uint8/16/128. You could make that
> available as a general __builtin :-)

clang has some __builtin_addc*, we probably already have an enhancement request in bugzilla asking to implement those...
Comment 6 Jakub Jelinek 2019-05-24 08:24:43 UTC
In 325462 SDM vol 1-2abcd-3abcd in 3.1.1.10 Intel ® C/C++ Compiler Intrinsics Equivalents Section, it is actually written:
"The declarations of Intel C/C++ compiler intrinsic functions may reference some non-standard data types, such as __int64. The C Standard header stdint.h defines similar platform-independent types, and the documentation for that header gives characteristics that apply to corresponding non-standard types according to the following table."
__int64          int64_t
unsigned __int64 uint64_t
But I wonder how recent that section is (whether it hasn't been introduced years after GCC intrinsic headers made their choice).