[PATCH] longlong.h: loongarch64: replace unsigned __int128__ with __uint128_t

Yao Zi ziyao at disroot.org
Sat Feb 1 14:10:41 CET 2025


On Sat, Feb 01, 2025 at 12:12:39PM +0100, Marc Glisse wrote:
> On Sat, 1 Feb 2025, Yao Zi wrote:
> 
> > On Fri, Jan 31, 2025 at 10:42:09PM +0100, Marc Glisse wrote:
> > > Hi,
> > > 
> > > would it work for you if I replaced __int128__ with __int128, i.e. the name
> > > that gcc documents at
> > > https://gcc.gnu.org/onlinedocs/gcc/_005f_005fint128.html ? I think clang
> > > handles that fine.
> > 
> > Oops, I found out why. GCC 14 complains about usage of __int128 with our
> > default build configuration while Clang doesn't.
> > 
> >    ../longlong.h:1165:22: warning: ISO C does not support '__int128' types [-Wpedantic]
> 
> But it doesn't complain about __uint128_t? That sounds strange...

Yep, quite weird as they're actually both extensions...

> There is also the possibility of adding __extension__ in front, that's
> what's done in the sanitizers (in llvm) and libstdc++ (in gcc).

Another solution is to write some inline assembly for LoongArch, like
the x86_64 support,

diff -r 6df5dd697f5a -r d8edcde87b12 longlong.h
--- a/longlong.h	Fri Oct 18 19:16:58 2024 +0200
+++ b/longlong.h	Sat Nov 23 22:15:10 2024 +0800
@@ -1159,11 +1159,9 @@
 
 #if defined (__loongarch64) && W_TYPE_SIZE == 64
 #define umul_ppmm(w1, w0, u, v) \
-  do {									\
-    UDItype __u = (u), __v = (v);					\
-    (w0) = __u * __v;							\
-    (w1) = (unsigned __int128__) __u * __v >> 64;			\
-  } while (0)
+  __asm__ ("mul.d %0, %2, %3\n\tmulh.du %1, %2, %3"			\
+	   : "=&r" (w0), "=r" (w1)					\
+	   : "r" ((UDItype)(u)), "r" ((UDItype)(v)))
 #endif
 
 
This doesn't bring any performance regression on both GCC 14 and Clang
19. Compilers generate basically the same assembly.

Marc, which solution would you prefer?

> -- 
> Marc Glisse

Thanks,
Yao Zi


More information about the gmp-devel mailing list