[PATCH] D120327: compiler-rt: Add udivmodei5 to builtins and add bitint library
Matthias Gehre via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Mon May 9 07:20:26 PDT 2022
mgehre-amd added a comment.
There is some push back on the gcc mailing list both on requiring an extra word to enable Knuth [0]
and generally defining the libgcc function before _BitInt is implemented in gcc [1].
There are also concerns about whether this would be consistent with the ABI,
which is isn't finalized on all targets yet.
I see a few options going forward:
1. Continue discussion with the gcc folks.
I'm not sure that I can move the discussion anywhere.
2. I prototyped replacing the division with an inlined and fully unrolled version of
set_zero(quo, words);
set_zero(rem, words);
unsigned bits = words * WORD_SIZE_IN_BITS;
for (int i = bits - 1; i >= 0; --i) {
left_shift_1(rem, words); // rem <<= 1;
set_bit_0(rem, words, get_bit(a, words, i)); // rem(bit 0) = a(bit i);
if (ucompare(rem, b, words) >= 0) { // if (rem >= b)
subtract(rem, b, words); // rem -= b;
set_bit(quo, words, i); // quo(bit i) = 1;
}
}
during SelectionDAG legalization. This seems to generally work, requires no compiler-rt
extension, but leads to ~5600 instructions on AArch64 for a single udiv i256.
I just created a SelectionDAG node for every line above, and let SelectionDAG legalize
those further to native types.
3. Do the expansion of large udivs on LLVM IR (in TargetPassConfig::addIRPasses ?).
This has the advantage that we are allowed to create loops and functions, so we can
keep the loop rolled to save on the instruction count. We can also keep the function
outlined. We would still specialize based on the integer type, so
the implementation for i256 would look like
define i256 __llvm__udivrem256(i256 a, i256 b) {
...
loop_body:
..
; rem <<= 1;
%rem_sh = shl i256 %rem, 1
; rem(bit 0) = a(bit i);
%a_n1 = lshr i256 %a, %i
%a_n = and i256 %a_n1, 1
%rem_sb = or i256 %rem_sh, %a_n
...
which makes the pass simple to write. The backend later expands those big integer types
into native ones.
4. Continue with the current approach, but rename the functions to `__llvm_divmodei5` to be independent
of what gcc will decide to do.
We still need build libbitint and link to it whenever the user selects libgcc as their runtime library.
`WEAK_IF_BITINT_LIBRARY` can be removed; the functions always have strong linkage.
What do you think?
[0] https://gcc.gnu.org/pipermail/gcc/2022-May/238659.html
[1] https://gcc.gnu.org/pipermail/gcc/2022-May/238666.html
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D120327/new/
https://reviews.llvm.org/D120327
More information about the llvm-commits
mailing list