public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/60971] New: Wrong code when coercing unsigned char to bool
@ 2014-04-26  0:36 peter at empeg dot com
  2014-04-26  9:54 ` [Bug tree-optimization/60971] [4.9/4.10 Regression] " jakub at gcc dot gnu.org
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: peter at empeg dot com @ 2014-04-26  0:36 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60971

            Bug ID: 60971
           Summary: Wrong code when coercing unsigned char to bool
           Product: gcc
           Version: 4.9.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: peter at empeg dot com

GCC 4.9.0 for x86_64 produces the wrong code for bar1 given this C++ file:

unsigned char foo();
bool bar1() { return foo() & 1; }
bool bar2() { return foo() & 2; }

gcc -O2 -S gcc49.cpp -Wall -Wextra

bar1 is compiled into a direct tailcall to foo() -- no and'ing with 1 is done
to the result (so it returns the Wrong Thing if foo() returns 0x40, say). bar2
is correct however.

GCC 4.8.2 got this right (its output for bar1 and bar2 is very similar except
for the constant being and'ed with).

GCC 4.9.0 gets it right if "unsigned char" is replaced with "unsigned short" or
"unsigned int".

4.9.0 built from release tarball, configured --enable-shared \
            --enable-languages=c,c++ --disable-werror \
            --enable-threads --disable-multilib \
            --enable-__cxa_atexit --with-system-zlib

When GCC was compiled, CFLAGS, LIBCFLAGS, LIBCXXFLAGS, and BOOT_CFLAGS were all
set to "-O2 -O9 -march=core2 -mtune=core2 -pipe".


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

* [Bug tree-optimization/60971] [4.9/4.10 Regression] Wrong code when coercing unsigned char to bool
  2014-04-26  0:36 [Bug c++/60971] New: Wrong code when coercing unsigned char to bool peter at empeg dot com
@ 2014-04-26  9:54 ` jakub at gcc dot gnu.org
  2014-04-29  5:06 ` law at redhat dot com
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: jakub at gcc dot gnu.org @ 2014-04-26  9:54 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60971

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jakub at gcc dot gnu.org,
                   |                            |law at gcc dot gnu.org
   Target Milestone|---                         |4.9.1

--- Comment #2 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Indeed.  Regressed with r198121.

volatile unsigned char c;

__attribute__((noinline)) unsigned char
foo (void)
{
  return c;
}

__attribute__((noinline)) _Bool
bar (void)
{
  return foo () & 1;
}

int
main ()
{
  c = 0x41;
  c = bar ();
  if (c != 1)
    __builtin_abort ();
  c = 0x20;
  c = bar ();
  if (c != 0)
    __builtin_abort ();
  return 0;
}


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

* [Bug tree-optimization/60971] [4.9/4.10 Regression] Wrong code when coercing unsigned char to bool
  2014-04-26  0:36 [Bug c++/60971] New: Wrong code when coercing unsigned char to bool peter at empeg dot com
  2014-04-26  9:54 ` [Bug tree-optimization/60971] [4.9/4.10 Regression] " jakub at gcc dot gnu.org
@ 2014-04-29  5:06 ` law at redhat dot com
  2014-04-29  9:29 ` jakub at gcc dot gnu.org
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: law at redhat dot com @ 2014-04-29  5:06 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60971

--- Comment #3 from Jeffrey A. Law <law at redhat dot com> ---
Isn't the real problem here that we emitted the tail call because we thought
the return type from "foo" was close enough to the return type from "bar" that
no coercion was needed?

In the .optimized dump we have:

bar ()
{
  unsigned char _3;
  _Bool _4;

;;   basic block 2, loop depth 0, count 0, freq 10000, maybe hot
;;    prev block 0, next block 1, flags: (NEW, REACHABLE)
;;    pred:       ENTRY [100.0%]  (FALLTHRU,EXECUTABLE)
  _3 = foo (); [tail call]
  _4 = (_Bool) _3;
  return _4;
;;    succ:       EXIT [100.0%]

}

Which is correct AFAICT.

Yet we turn that into:

        jmp     foo     # 5     *sibcall_value  [length = 5]


Which loses the conversion from unsigned char to _Bool which strips off the
bits outside _Bool.

We have the following code which is supposed to handle these kinds of cases,
but obviously isn't sufficient as deals strictly with RTL modes (and at the RTL
mode level, the return types are effectively equivalent)

 /* Check if caller and callee disagree in promotion of function
     return value.  */
  if (try_tail_call)
    {
      enum machine_mode caller_mode, caller_promoted_mode;
      enum machine_mode callee_mode, callee_promoted_mode;
      int caller_unsignedp, callee_unsignedp;
      tree caller_res = DECL_RESULT (current_function_decl);

      caller_unsignedp = TYPE_UNSIGNED (TREE_TYPE (caller_res));
      caller_mode = DECL_MODE (caller_res);
      callee_unsignedp = TYPE_UNSIGNED (TREE_TYPE (funtype));
      callee_mode = TYPE_MODE (TREE_TYPE (funtype));
      caller_promoted_mode
        = promote_function_mode (TREE_TYPE (caller_res), caller_mode,
                                 &caller_unsignedp,
                                 TREE_TYPE (current_function_decl), 1);
      callee_promoted_mode
        = promote_function_mode (TREE_TYPE (funtype), callee_mode,
                                 &callee_unsignedp,
                                 funtype, 1);
      if (caller_mode != VOIDmode
          && (caller_promoted_mode != callee_promoted_mode
              || ((caller_mode != caller_promoted_mode
                   || callee_mode != callee_promoted_mode)
                  && (caller_unsignedp != callee_unsignedp
                      || GET_MODE_BITSIZE (caller_mode)
                         < GET_MODE_BITSIZE (callee_mode)))))
        try_tail_call = 0;
    }


Not surprisingly, if I add "-fno-optimize-sibling-calls" the test passes.


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

* [Bug tree-optimization/60971] [4.9/4.10 Regression] Wrong code when coercing unsigned char to bool
  2014-04-26  0:36 [Bug c++/60971] New: Wrong code when coercing unsigned char to bool peter at empeg dot com
  2014-04-26  9:54 ` [Bug tree-optimization/60971] [4.9/4.10 Regression] " jakub at gcc dot gnu.org
  2014-04-29  5:06 ` law at redhat dot com
@ 2014-04-29  9:29 ` jakub at gcc dot gnu.org
  2014-04-29 10:18 ` jakub at gcc dot gnu.org
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: jakub at gcc dot gnu.org @ 2014-04-29  9:29 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60971

--- Comment #4 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Created attachment 32702
  --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=32702&action=edit
gcc49-pr60971.patch

Agreed, but I'd say the bug is in the tailc pass then, it assumes conversion
from QImode integer type with 8-bit precision to QImode bool type with 1-bit
precision doesn't need any code, when that is not true, during expansion in
those cases we apply REDUCE_BIT_FIELD.


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

* [Bug tree-optimization/60971] [4.9/4.10 Regression] Wrong code when coercing unsigned char to bool
  2014-04-26  0:36 [Bug c++/60971] New: Wrong code when coercing unsigned char to bool peter at empeg dot com
                   ` (2 preceding siblings ...)
  2014-04-29  9:29 ` jakub at gcc dot gnu.org
@ 2014-04-29 10:18 ` jakub at gcc dot gnu.org
  2014-04-29 13:04 ` law at redhat dot com
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: jakub at gcc dot gnu.org @ 2014-04-29 10:18 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60971

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
  Attachment #32702|0                           |1
        is obsolete|                            |

--- Comment #5 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Created attachment 32704
  --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=32704&action=edit
gcc49-pr60971.patch

Updated patch based on IRC discussion.


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

* [Bug tree-optimization/60971] [4.9/4.10 Regression] Wrong code when coercing unsigned char to bool
  2014-04-26  0:36 [Bug c++/60971] New: Wrong code when coercing unsigned char to bool peter at empeg dot com
                   ` (3 preceding siblings ...)
  2014-04-29 10:18 ` jakub at gcc dot gnu.org
@ 2014-04-29 13:04 ` law at redhat dot com
  2014-04-29 14:44 ` jakub at gcc dot gnu.org
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: law at redhat dot com @ 2014-04-29 13:04 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60971

--- Comment #6 from Jeffrey A. Law <law at redhat dot com> ---
Jakub,

That patch is fine -- it's effectively what I was planning to do today, just in
a different location.


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

* [Bug tree-optimization/60971] [4.9/4.10 Regression] Wrong code when coercing unsigned char to bool
  2014-04-26  0:36 [Bug c++/60971] New: Wrong code when coercing unsigned char to bool peter at empeg dot com
                   ` (4 preceding siblings ...)
  2014-04-29 13:04 ` law at redhat dot com
@ 2014-04-29 14:44 ` jakub at gcc dot gnu.org
  2014-04-29 14:46 ` jakub at gcc dot gnu.org
  2014-04-30 17:36 ` law at redhat dot com
  7 siblings, 0 replies; 9+ messages in thread
From: jakub at gcc dot gnu.org @ 2014-04-29 14:44 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60971

--- Comment #7 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Author: jakub
Date: Tue Apr 29 14:44:07 2014
New Revision: 209900

URL: http://gcc.gnu.org/viewcvs?rev=209900&root=gcc&view=rev
Log:
    PR tree-optimization/60971
    * tree-tailcall.c (process_assignment): Reject conversions which
    reduce precision.

    * c-c++-common/turtore/pr60971.c: New test.

Added:
    trunk/gcc/testsuite/c-c++-common/torture/pr60971.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/tree-tailcall.c


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

* [Bug tree-optimization/60971] [4.9/4.10 Regression] Wrong code when coercing unsigned char to bool
  2014-04-26  0:36 [Bug c++/60971] New: Wrong code when coercing unsigned char to bool peter at empeg dot com
                   ` (5 preceding siblings ...)
  2014-04-29 14:44 ` jakub at gcc dot gnu.org
@ 2014-04-29 14:46 ` jakub at gcc dot gnu.org
  2014-04-30 17:36 ` law at redhat dot com
  7 siblings, 0 replies; 9+ messages in thread
From: jakub at gcc dot gnu.org @ 2014-04-29 14:46 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60971

--- Comment #8 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Author: jakub
Date: Tue Apr 29 14:45:24 2014
New Revision: 209901

URL: http://gcc.gnu.org/viewcvs?rev=209901&root=gcc&view=rev
Log:
    PR tree-optimization/60971
    * tree-tailcall.c (process_assignment): Reject conversions which
    reduce precision.

    * c-c++-common/turtore/pr60971.c: New test.

Added:
    branches/gcc-4_9-branch/gcc/testsuite/c-c++-common/torture/pr60971.c
Modified:
    branches/gcc-4_9-branch/gcc/ChangeLog
    branches/gcc-4_9-branch/gcc/testsuite/ChangeLog
    branches/gcc-4_9-branch/gcc/tree-tailcall.c


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

* [Bug tree-optimization/60971] [4.9/4.10 Regression] Wrong code when coercing unsigned char to bool
  2014-04-26  0:36 [Bug c++/60971] New: Wrong code when coercing unsigned char to bool peter at empeg dot com
                   ` (6 preceding siblings ...)
  2014-04-29 14:46 ` jakub at gcc dot gnu.org
@ 2014-04-30 17:36 ` law at redhat dot com
  7 siblings, 0 replies; 9+ messages in thread
From: law at redhat dot com @ 2014-04-30 17:36 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60971

Jeffrey A. Law <law at redhat dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|---                         |FIXED

--- Comment #9 from Jeffrey A. Law <law at redhat dot com> ---
Fixed on trunk and 4.9 branch.


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

end of thread, other threads:[~2014-04-30 17:36 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-04-26  0:36 [Bug c++/60971] New: Wrong code when coercing unsigned char to bool peter at empeg dot com
2014-04-26  9:54 ` [Bug tree-optimization/60971] [4.9/4.10 Regression] " jakub at gcc dot gnu.org
2014-04-29  5:06 ` law at redhat dot com
2014-04-29  9:29 ` jakub at gcc dot gnu.org
2014-04-29 10:18 ` jakub at gcc dot gnu.org
2014-04-29 13:04 ` law at redhat dot com
2014-04-29 14:44 ` jakub at gcc dot gnu.org
2014-04-29 14:46 ` jakub at gcc dot gnu.org
2014-04-30 17:36 ` law at redhat dot com

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).