[Bug c/79219] Feature request: double width/single width -> single width integer division and remainder
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79219 Andrew Pinski changed: What|Removed |Added See Also||https://gcc.gnu.org/bugzill ||a/show_bug.cgi?id=79217 --- Comment #10 from Andrew Pinski --- I am not 100% sure but I suspect _BitInt support satisfies this request here also.
[Bug c/79219] Feature request: double width/single width -> single width integer division and remainder
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79219 --- Comment #9 from Uroš Bizjak --- (In reply to H. Peter Anvin from comment #8) > (In reply to Richard Biener from comment #1) > > So you mean DW/W -> W, but that can result in the result being not > > representable? > > What's the desired behavior in this case? Invoking undefined behavior? > > When the output is not representable, the expected behavior is whatever the > platform does when an ordinary division divides by zero (which usually means > some variant of raise(SIGFPE) is invoked through one path or another.) If this is the case, we already have appropriate pattern (although commented-out ATM) in i386.md (the example is for 32-bit target, but can be trivially changed to fit TImode/DImode on 64-bit targets) --cut here-- ;; We cannot use div/idiv for double division, because it causes ;; "division by zero" on the overflow and that's not what we expect ;; from truncate. Because true (non truncating) double division is ;; never generated, we can't create this insn anyway. ; ;(define_insn "" ; [(set (match_operand:SI 0 "register_operand" "=a") ; (truncate:SI ; (udiv:DI (match_operand:DI 1 "register_operand" "A") ; (zero_extend:DI ;(match_operand:SI 2 "nonimmediate_operand" "rm") ; (set (match_operand:SI 3 "register_operand" "=d") ; (truncate:SI ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2) ; (clobber (reg:CC FLAGS_REG))] ; "" ; "div{l}\t{%2, %0|%0, %2}" ; [(set_attr "type" "idiv")]) --cut here-- The comment suggests that middle-end has to be improved to detect and expand TI/DI -> DI division in a similar generic way as DI/DI -> TI multiplication. OTOH, since the truncation of the result of the division doesn't trap, the combined pattern also should not (combine pass can synthesize this pattern from separate patterns). IMO, at least for x86, we need a builtin.
[Bug c/79219] Feature request: double width/single width -> single width integer division and remainder
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79219 --- Comment #8 from H. Peter Anvin --- (In reply to Richard Biener from comment #1) > So you mean DW/W -> W, but that can result in the result being not > representable? > What's the desired behavior in this case? Invoking undefined behavior? When the output is not representable, the expected behavior is whatever the platform does when an ordinary division divides by zero (which usually means some variant of raise(SIGFPE) is invoked through one path or another.)
[Bug c/79219] Feature request: double width/single width -> single width integer division and remainder
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79219 --- Comment #7 from H. Peter Anvin --- Created attachment 40603 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=40603=edit Test case: assembly output
[Bug c/79219] Feature request: double width/single width -> single width integer division and remainder
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79219 --- Comment #6 from H. Peter Anvin --- Created attachment 40602 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=40602=edit Test case: preprocessor output
[Bug c/79219] Feature request: double width/single width -> single width integer division and remainder
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79219 --- Comment #5 from H. Peter Anvin --- Created attachment 40601 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=40601=edit Test case: source code
[Bug c/79219] Feature request: double width/single width -> single width integer division and remainder
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79219 --- Comment #4 from H. Peter Anvin --- There are a few issues with that: a) the overflow behavior is inherently different, which is why the inline you propose doesn't work. Try compiling the attached program, on x86-64 it produces a call to __udivti3 rather than an inline div instruction (output shown below). The reason is that the div instruction will trap on overflow. b) it requires algorithms to be implemented using lengthy (source-code-wise) multi-precision to be portable between 32- and 64-bit architectures. c) it seems likely that getting __intN where N > CHAR_BIT*sizeof(uintmax_t) into a standard would be very hard, and thus would not be possible to standard-track (although it could be used as an implementation on gcc using a header inline, of course.) dbldiv.o: file format elf64-x86-64 Disassembly of section .text: : 0: 45 31 c9xor%r9d,%r9d 3: 49 89 famov%rdi,%r10 6: 55 push %rbp 7: 4c 89 cfmov%r9,%rdi a: 48 89 d1mov%rdx,%rcx d: 4c 89 d5mov%r10,%rbp 10: 31 d2 xor%edx,%edx 12: 48 01 f7add%rsi,%rdi 15: 48 11 d5adc%rdx,%rbp 18: 48 89 camov%rcx,%rdx 1b: 31 c9 xor%ecx,%ecx 1d: 48 89 eemov%rbp,%rsi 20: e8 00 00 00 00 callq 2521: R_X86_64_PC32 __udivti3-0x4 25: 5d pop%rbp 26: c3 retq 27: 66 0f 1f 84 00 00 00nopw 0x0(%rax,%rax,1) 2e: 00 00 0030 : 30: 48 89 d1mov%rdx,%rcx 33: 48 89 f0mov%rsi,%rax 36: 48 89 famov%rdi,%rdx 39: 48 f7 f2div%rdx 3c: c3 retq
[Bug c/79219] Feature request: double width/single width -> single width integer division and remainder
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79219 Jakub Jelinek changed: What|Removed |Added CC||jakub at gcc dot gnu.org --- Comment #3 from Jakub Jelinek --- I must say I don't understand the need for an extension here. The argument that there might not be a type twice as large as the largest you've made in the high part multiply case (which doesn't make much sense anyway, because I assume the reason you want that is that it is fast and that will only be the case if it is at most word * word -> highpart of doubleword and in that case you always have a type for the doubleword (__int128 for 64-bit, long long for 32-bit)) doesn't apply here, you need to have the double word value to divide. So IMNSHO you should just write long foo (__int128_t a, long b) { return a / b; } or similar and if the HW has instruction for such a divide, it can use it.
[Bug c/79219] Feature request: double width/single width -> single width integer division and remainder
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79219 --- Comment #2 from Uroš Bizjak --- (In reply to Richard Biener from comment #1) > So you mean DW/W -> W, but that can result in the result being not > representable? > What's the desired behavior in this case? Invoking undefined behavior? x86 will generate divide error (#DE) exception in this case.
[Bug c/79219] Feature request: double width/single width -> single width integer division and remainder
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79219 --- Comment #1 from Richard Biener --- So you mean DW/W -> W, but that can result in the result being not representable? What's the desired behavior in this case? Invoking undefined behavior?