public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug sanitizer/104937] New: wrong code with _Complex division and -fsanitize=undefined
@ 2022-03-15 16:38 zsojka at seznam dot cz
  2022-03-15 18:24 ` [Bug sanitizer/104937] " jakub at gcc dot gnu.org
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: zsojka at seznam dot cz @ 2022-03-15 16:38 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104937

            Bug ID: 104937
           Summary: wrong code with _Complex division and
                    -fsanitize=undefined
           Product: gcc
           Version: 12.0
            Status: UNCONFIRMED
          Keywords: wrong-code
          Severity: normal
          Priority: P3
         Component: sanitizer
          Assignee: unassigned at gcc dot gnu.org
          Reporter: zsojka at seznam dot cz
                CC: dodji at gcc dot gnu.org, dvyukov at gcc dot gnu.org,
                    jakub at gcc dot gnu.org, kcc at gcc dot gnu.org, marxin at gcc dot gnu.org
  Target Milestone: ---
              Host: x86_64-pc-linux-gnu
            Target: x86_64-pc-linux-gnu

Created attachment 52631
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=52631&action=edit
reduced testcase

Output:
$ x86_64-pc-linux-gnu-gcc -fsanitize=undefined testcase.c
$ ./a.out 
Aborted

The __imag__ part seems to be garbage.

$ x86_64-pc-linux-gnu-gcc -v
Using built-in specs.
COLLECT_GCC=/repo/gcc-trunk/binary-latest-amd64/bin/x86_64-pc-linux-gnu-gcc
COLLECT_LTO_WRAPPER=/repo/gcc-trunk/binary-trunk-r12-7654-20220315102422-gda24fce323e-checking-yes-rtl-df-extra-nobootstrap-amd64/bin/../libexec/gcc/x86_64-pc-linux-gnu/12.0.1/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: /repo/gcc-trunk//configure --enable-languages=c,c++
--enable-valgrind-annotations --disable-nls --enable-checking=yes,rtl,df,extra
--disable-bootstrap --with-cloog --with-ppl --with-isl
--build=x86_64-pc-linux-gnu --host=x86_64-pc-linux-gnu
--target=x86_64-pc-linux-gnu --with-ld=/usr/bin/x86_64-pc-linux-gnu-ld
--with-as=/usr/bin/x86_64-pc-linux-gnu-as --disable-libstdcxx-pch
--prefix=/repo/gcc-trunk//binary-trunk-r12-7654-20220315102422-gda24fce323e-checking-yes-rtl-df-extra-nobootstrap-amd64
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 12.0.1 20220315 (experimental) (GCC)

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [Bug sanitizer/104937] wrong code with _Complex division and -fsanitize=undefined
  2022-03-15 16:38 [Bug sanitizer/104937] New: wrong code with _Complex division and -fsanitize=undefined zsojka at seznam dot cz
@ 2022-03-15 18:24 ` jakub at gcc dot gnu.org
  2022-03-15 18:30 ` zsojka at seznam dot cz
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: jakub at gcc dot gnu.org @ 2022-03-15 18:24 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104937

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jsm28 at gcc dot gnu.org

--- Comment #1 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Doesn't seem to be sanitizer specific.
Just change the testcase to:
_Complex unsigned
foo (_Complex unsigned x)
{
  _Complex unsigned y = x;
  return y / x;
}

int
main ()
{
  _Complex unsigned x = foo (6 + 43 * 1i);
  if (x != 1)
    __builtin_abort ();
  return 0;
}
so that it doesn't get folded to 1 + 0i in the FE and at -O0 you'll get abort
as well.
I think division just doesn't work at all for _Complex unsigned, seems to work
for _Complex signed.
Don't we have some PR covering it?

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [Bug sanitizer/104937] wrong code with _Complex division and -fsanitize=undefined
  2022-03-15 16:38 [Bug sanitizer/104937] New: wrong code with _Complex division and -fsanitize=undefined zsojka at seznam dot cz
  2022-03-15 18:24 ` [Bug sanitizer/104937] " jakub at gcc dot gnu.org
@ 2022-03-15 18:30 ` zsojka at seznam dot cz
  2022-03-15 18:52 ` jakub at gcc dot gnu.org
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: zsojka at seznam dot cz @ 2022-03-15 18:30 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104937

--- Comment #2 from Zdenek Sojka <zsojka at seznam dot cz> ---
There was PR104604 where _Complex unsigned division was fixed, but I didn't
notice any other related wrong-code PR.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [Bug sanitizer/104937] wrong code with _Complex division and -fsanitize=undefined
  2022-03-15 16:38 [Bug sanitizer/104937] New: wrong code with _Complex division and -fsanitize=undefined zsojka at seznam dot cz
  2022-03-15 18:24 ` [Bug sanitizer/104937] " jakub at gcc dot gnu.org
  2022-03-15 18:30 ` zsojka at seznam dot cz
@ 2022-03-15 18:52 ` jakub at gcc dot gnu.org
  2022-03-15 18:55 ` jakub at gcc dot gnu.org
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: jakub at gcc dot gnu.org @ 2022-03-15 18:52 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104937

--- Comment #3 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
For
_Complex unsigned
foo (_Complex unsigned x, _Complex unsigned y)
{
  return y / x;
}

int
main ()
{
  _Complex int a = foo (6 + 43i, 6 + 43i);
  __builtin_printf ("%d %d\n", __real__ a, __imag__ a);
  return 0;
}
from what I see if xr < xi we expand it as
t=xr/xi*xr + xi
((yr*xr/xi + yi) / t) + ((yi*xr/xi - yr) / t) * i
Now, for the given numbers that is t=43 and the result is
43 / 43 + (0 - 6) / 43 * i
For signed complex that "works" by producing 1 + 0i, but for unsigned
that 0U - 6U is some huge number divided by 43.
But now that I see it, I think it doesn't work properly in most cases for
_Complex int either - for signed the xr < xi is actually done as abs(xr) <
abs(xi), so for both signed and unsigned complex xr/xi is 0, and similarly the
other case where we use xi/xr, with the only exception when xr==xi and thus
xr/xi is 1.  I bet the algorithm is well suited only for floating point...

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [Bug sanitizer/104937] wrong code with _Complex division and -fsanitize=undefined
  2022-03-15 16:38 [Bug sanitizer/104937] New: wrong code with _Complex division and -fsanitize=undefined zsojka at seznam dot cz
                   ` (2 preceding siblings ...)
  2022-03-15 18:52 ` jakub at gcc dot gnu.org
@ 2022-03-15 18:55 ` jakub at gcc dot gnu.org
  2022-03-16  7:42 ` [Bug c/104937] " rguenth at gcc dot gnu.org
  2022-03-17 14:03 ` jakub at gcc dot gnu.org
  5 siblings, 0 replies; 7+ messages in thread
From: jakub at gcc dot gnu.org @ 2022-03-15 18:55 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104937

--- Comment #4 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
https://gcc.gnu.org/legacy-ml/gcc/2001-11/msg00790.html
Regarding the debug info argument in there, this is being discussed for DWARF6.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [Bug c/104937] wrong code with _Complex division and -fsanitize=undefined
  2022-03-15 16:38 [Bug sanitizer/104937] New: wrong code with _Complex division and -fsanitize=undefined zsojka at seznam dot cz
                   ` (3 preceding siblings ...)
  2022-03-15 18:55 ` jakub at gcc dot gnu.org
@ 2022-03-16  7:42 ` rguenth at gcc dot gnu.org
  2022-03-17 14:03 ` jakub at gcc dot gnu.org
  5 siblings, 0 replies; 7+ messages in thread
From: rguenth at gcc dot gnu.org @ 2022-03-16  7:42 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104937

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
          Component|sanitizer                   |c

--- Comment #5 from Richard Biener <rguenth at gcc dot gnu.org> ---
Do the division using _Complex double and convert back?  But honestly I think
rejecting _Complex int division is good enough and maybe we should indeed
deprecate all of _Complex int.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [Bug c/104937] wrong code with _Complex division and -fsanitize=undefined
  2022-03-15 16:38 [Bug sanitizer/104937] New: wrong code with _Complex division and -fsanitize=undefined zsojka at seznam dot cz
                   ` (4 preceding siblings ...)
  2022-03-16  7:42 ` [Bug c/104937] " rguenth at gcc dot gnu.org
@ 2022-03-17 14:03 ` jakub at gcc dot gnu.org
  5 siblings, 0 replies; 7+ messages in thread
From: jakub at gcc dot gnu.org @ 2022-03-17 14:03 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104937

--- Comment #6 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
What we could for _Complex int just use the standard
(a + b*i) / (c + d*i) = (a*c + b*d) / (c*c + d*d) + ((b*c - a*d) / (c*c +
d*d))*i
which would be 6 multiplications and 2 divisions instead of the current
3 multiplications and 3 divisions.  But in order to avoid overflows we'd need
to do that all in bigger precision.  c*c + d*d for _Complex int is in [0,
LONG_LONG_MAX+1ULL] range, a*c+b*d in [-LONG_LONG_MAX+2*INT_MAX+2,
LONG_LONG_MAX+1ULL] range etc., so perhaps with some special cases we fit into
2*prec type.
For _Complex unsigned we'd also need to watch for b*c being smaller than a*d
and handle that by doing - ((a*d - b*c) / (c*c + d*d)) instead.

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2022-03-17 14:03 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-03-15 16:38 [Bug sanitizer/104937] New: wrong code with _Complex division and -fsanitize=undefined zsojka at seznam dot cz
2022-03-15 18:24 ` [Bug sanitizer/104937] " jakub at gcc dot gnu.org
2022-03-15 18:30 ` zsojka at seznam dot cz
2022-03-15 18:52 ` jakub at gcc dot gnu.org
2022-03-15 18:55 ` jakub at gcc dot gnu.org
2022-03-16  7:42 ` [Bug c/104937] " rguenth at gcc dot gnu.org
2022-03-17 14:03 ` jakub at gcc dot gnu.org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).