[Bug c/79219] Feature request: double width/single width -> single width integer division and remainder

2024-04-03 Thread pinskia at gcc dot gnu.org via Gcc-bugs
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

2017-01-27 Thread ubizjak at gmail dot com
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

2017-01-26 Thread hpa at zytor dot com
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

2017-01-26 Thread hpa at zytor dot com
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

2017-01-26 Thread hpa at zytor dot com
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

2017-01-26 Thread hpa at zytor dot com
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

2017-01-26 Thread hpa at zytor dot com
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  25 
21: 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

2017-01-25 Thread jakub at gcc dot gnu.org
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

2017-01-25 Thread ubizjak at gmail dot com
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

2017-01-25 Thread rguenth at gcc dot gnu.org
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?