[RFC] Should unused bits in _BitInt be zeroed?

39 views
Skip to first unread message

H.J. Lu

unread,
Feb 8, 2024, 12:30:43 PMFeb 8
to x86-64-abi
Should unused bits in _BitInt be zeroed, instead of undefined? Will
zeroing unused bits improve codgen?

https://gitlab.com/x86-psABIs/x86-64-ABI/-/issues/16

--
H.J.

Carlos O'Donell

unread,
Feb 9, 2024, 8:16:33 AMFeb 9
to H.J. Lu, x86-64-abi
Is it undefined?

Why zero?

What do the current compilers do?

What does a collection of compiler experts believe is the right thing to do?

I would expect that a sign extension into the unused bits would improve codegen?

That way if you cast to a larger _BitInt then you don't need to generate code to
do the sign extension?

--
Cheers,
Carlos.

Florian Weimer

unread,
Feb 9, 2024, 8:33:55 AMFeb 9
to H.J. Lu, x86-64-abi, Jakub Jelinek
* H. J. Lu:

> Should unused bits in _BitInt be zeroed, instead of undefined? Will
> zeroing unused bits improve codgen?
>
> https://gitlab.com/x86-psABIs/x86-64-ABI/-/issues/16

If we required it to be 0, these integers have trap representations,
which introduces additional undefined behavior. Do we really want that?

Cc:ing Jakub, who could share some implementation experience.

Thanks,
Florian

Fangrui Song

unread,
Feb 10, 2024, 1:03:14 AMFeb 10
to H.J. Lu, x86-64-abi, Jakub Jelinek, Florian Weimer
> --
> You received this message because you are subscribed to the Google Groups "X86-64 System V Application Binary Interface" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to x86-64-abi+...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/x86-64-abi/877cjd7oea.fsf%40oldenburg.str.redhat.com.


Unspecifying unused bits has more efficient +,-,*,<<, narrowing, and
atomics when supported.
Zeroing unused bits has more efficient comparison and widening.

% cat bit.c
#ifdef B
typedef _BitInt(B) T;
#elif defined(I)
typedef int T;
#else
typedef char T;
#endif
typedef _BitInt(7) T1;
extern T y;

long sextload(T *x) { return *x; }

// Fast if unused bits are zeros
int load_and_cmp(T x) { return x == y; }
unsigned long zextload(T *x) { return *x; }
int less(T x, T y) { return x < y; }
void store(T x) { y = x; }
T rsh(T x, int y) { return x>>y; }

// Fast if unused bits are unspecified
T plus(T x, T y) { return x+y; }
T mul(T x, T y) { return x*y; }
T lsh(T x, int y) { return x<<y; }
T1 narrow(T x) { return x; }
//void atomic_inc(_Atomic T *x) { ++*x; }

---

When storing a _BitInt to a global variable or returning a _BitInt,
can the unused bits be unspecified?

---

https://github.com/llvm/llvm-project/issues/62032 Clang's
implementation currently has a problem that when a loaded _BitInt is
extended, the high bits are not explicitly cleared.

Michael Matz

unread,
Feb 12, 2024, 9:35:32 AMFeb 12
to H.J. Lu, x86-64-abi
Hello,
So, as Fangrui says, while this will improve some operations, it will
make others worse, so such a change is not quite clear cut. Then it's
unclear why zero-extension instead of sign-extension or
natural-sign-extension should be the correct choice.
Also, in https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113837 the
implementor of _BitInt in GCC doesn't sound very convinced that this is a
good idea.


My gut feeling tells me we should leave the unused bits be unspecified.

Anyone knows undeniable reasons for why specifying them would be a good
idea? (Perhaps a benchmark not only doing compares?)


Ciao,
Michael.

Jan Beulich

unread,
Feb 12, 2024, 9:57:45 AMFeb 12
to Michael Matz, x86-64-abi, H.J. Lu
Anything going to memory (including static variables) may benefit from
things then being predictable / reproducible.

Jan
Reply all
Reply to author
Forward
0 new messages