public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
From: "ubizjak at gmail dot com" <gcc-bugzilla@gcc.gnu.org>
To: gcc-bugs@gcc.gnu.org
Subject: [Bug target/58779] [4.7/4.8/4.9 Regression] wrong code at -O1 on x86_64-linux-gnu
Date: Tue, 22 Oct 2013 07:08:00 -0000	[thread overview]
Message-ID: <bug-58779-4-PcTGvf4S9m@http.gcc.gnu.org/bugzilla/> (raw)
In-Reply-To: <bug-58779-4@http.gcc.gnu.org/bugzilla/>

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="UTF-8", Size: 9847 bytes --]

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

--- Comment #5 from Uroš Bizjak <ubizjak at gmail dot com> ---
combine pass is converting:

(insn 21 20 22 4 (parallel [
            (set (reg:SI 73)
                (minus:SI (reg:SI 64 [ a.2 ])
                    (reg:SI 59 [ iftmp.3 ])))
            (clobber (reg:CC 17 flags))
        ]) pr58779.c:8 286 {*subsi_1}
     (expr_list:REG_DEAD (reg:SI 59 [ iftmp.3 ])
        (expr_list:REG_UNUSED (reg:CC 17 flags)
            (nil))))

(insn 22 21 23 4 (set (reg:CC 17 flags)
        (compare:CC (reg:SI 64 [ a.2 ])
            (reg:SI 73))) pr58779.c:8 6 {*cmpsi_1}
     (expr_list:REG_DEAD (reg:SI 73)
        (expr_list:REG_DEAD (reg:SI 64 [ a.2 ])
            (nil))))

(jump_insn 23 22 24 4 (set (pc)
        (if_then_else (ltu (reg:CC 17 flags)
                (const_int 0 [0]))
            (label_ref 27)
            (pc))) pr58779.c:8 596 {*jcc_1}
     (expr_list:REG_DEAD (reg:CC 17 flags)
        (expr_list:REG_BR_PROB (const_int 9996 [0x270c])
            (nil)))

to:

(insn 22 21 23 4 (set (reg:CCC 17 flags)
        (compare:CCC (minus:SI (reg:SI 64 [ a.2 ])
                (reg:SI 59 [ iftmp.3 ]))
            (reg:SI 64 [ a.2 ]))) pr58779.c:8 316 {*subsi3_cconly_overflow}
     (expr_list:REG_DEAD (reg:SI 59 [ iftmp.3 ])
        (expr_list:REG_DEAD (reg:SI 64 [ a.2 ])
            (nil))))

(jump_insn 23 22 24 4 (set (pc)
        (if_then_else (gtu (reg:CCC 17 flags)
                (const_int 0 [0]))
            (label_ref 27)
            (pc))) pr58779.c:8 596 {*jcc_1}
     (expr_list:REG_DEAD (reg:CC 17 flags)
        (expr_list:REG_BR_PROB (const_int 9996 [0x270c])
            (nil)))

To satisfy the *subsi3_cconly_overflow pattern, the operands of the compare are
swapped, and this reflects in changing jump insn condition from LTU to GTU.

The LTU in CCmode results in "jb" instruction, whereas GTU in CCCmode in
unpatched gcc also results in "jb". As Mikael figured out in Comment #2, we
should jump on Not-Carry condition here.

It looks to me that MINUS overflow checks are NOT modelled correctly. To hide
this problem, GTU and LEU conditions operate with inverted flag check, as can
be seen in i386.c, put_condition_code:

    case GTU:
      if (mode == CCmode)
    suffix = fp ? "nbe" : "a";
      else if (mode == CCCmode)
    suffix = "b";
    ...
    case LEU:
      if (mode == CCmode)
    suffix = "be";
      else if (mode == CCCmode)
    suffix = fp ? "nb" : "ae";
    ...

As can be seen from the above code, hecks in CCCmode are inverted.

So, the solution is simply to remove wrong MINUS overflow checks, as in to-be
attached patch.
>From gcc-bugs-return-432430-listarch-gcc-bugs=gcc.gnu.org@gcc.gnu.org Tue Oct 22 07:09:31 2013
Return-Path: <gcc-bugs-return-432430-listarch-gcc-bugs=gcc.gnu.org@gcc.gnu.org>
Delivered-To: listarch-gcc-bugs@gcc.gnu.org
Received: (qmail 19234 invoked by alias); 22 Oct 2013 07:09:31 -0000
Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm
Precedence: bulk
List-Id: <gcc-bugs.gcc.gnu.org>
List-Archive: <http://gcc.gnu.org/ml/gcc-bugs/>
List-Post: <mailto:gcc-bugs@gcc.gnu.org>
List-Help: <mailto:gcc-bugs-help@gcc.gnu.org>
Sender: gcc-bugs-owner@gcc.gnu.org
Delivered-To: mailing list gcc-bugs@gcc.gnu.org
Received: (qmail 19179 invoked by uid 48); 22 Oct 2013 07:09:28 -0000
From: "ubizjak at gmail dot com" <gcc-bugzilla@gcc.gnu.org>
To: gcc-bugs@gcc.gnu.org
Subject: [Bug target/58779] [4.7/4.8/4.9 Regression] wrong code at -O1 on x86_64-linux-gnu
Date: Tue, 22 Oct 2013 07:09:00 -0000
X-Bugzilla-Reason: CC
X-Bugzilla-Type: changed
X-Bugzilla-Watch-Reason: None
X-Bugzilla-Product: gcc
X-Bugzilla-Component: target
X-Bugzilla-Version: 4.9.0
X-Bugzilla-Keywords: wrong-code
X-Bugzilla-Severity: normal
X-Bugzilla-Who: ubizjak at gmail dot com
X-Bugzilla-Status: ASSIGNED
X-Bugzilla-Priority: P3
X-Bugzilla-Assigned-To: ubizjak at gmail dot com
X-Bugzilla-Target-Milestone: 4.7.4
X-Bugzilla-Flags:
X-Bugzilla-Changed-Fields: attachments.created
Message-ID: <bug-58779-4-PrthPMGrAC@http.gcc.gnu.org/bugzilla/>
In-Reply-To: <bug-58779-4@http.gcc.gnu.org/bugzilla/>
References: <bug-58779-4@http.gcc.gnu.org/bugzilla/>
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/
Auto-Submitted: auto-generated
MIME-Version: 1.0
X-SW-Source: 2013-10/txt/msg01574.txt.bz2
Content-length: 289

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

--- Comment #6 from Uroš Bizjak <ubizjak at gmail dot com> ---
Created attachment 31067
  --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=31067&action=edit
Proposed patch that removes MINUS overflow checks

Patch in testing.
>From gcc-bugs-return-432431-listarch-gcc-bugs=gcc.gnu.org@gcc.gnu.org Tue Oct 22 07:45:49 2013
Return-Path: <gcc-bugs-return-432431-listarch-gcc-bugs=gcc.gnu.org@gcc.gnu.org>
Delivered-To: listarch-gcc-bugs@gcc.gnu.org
Received: (qmail 10958 invoked by alias); 22 Oct 2013 07:45:48 -0000
Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm
Precedence: bulk
List-Id: <gcc-bugs.gcc.gnu.org>
List-Archive: <http://gcc.gnu.org/ml/gcc-bugs/>
List-Post: <mailto:gcc-bugs@gcc.gnu.org>
List-Help: <mailto:gcc-bugs-help@gcc.gnu.org>
Sender: gcc-bugs-owner@gcc.gnu.org
Delivered-To: mailing list gcc-bugs@gcc.gnu.org
Received: (qmail 10930 invoked by uid 48); 22 Oct 2013 07:45:44 -0000
From: "dougkwan at google dot com" <gcc-bugzilla@gcc.gnu.org>
To: gcc-bugs@gcc.gnu.org
Subject: [Bug target/58838] New: mullw sets condition code incorrectly.
Date: Tue, 22 Oct 2013 07:45:00 -0000
X-Bugzilla-Reason: CC
X-Bugzilla-Type: new
X-Bugzilla-Watch-Reason: None
X-Bugzilla-Product: gcc
X-Bugzilla-Component: target
X-Bugzilla-Version: 4.9.0
X-Bugzilla-Keywords:
X-Bugzilla-Severity: normal
X-Bugzilla-Who: dougkwan at google dot com
X-Bugzilla-Status: UNCONFIRMED
X-Bugzilla-Priority: P3
X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org
X-Bugzilla-Target-Milestone: ---
X-Bugzilla-Flags:
X-Bugzilla-Changed-Fields: bug_id short_desc product version bug_status bug_severity priority component assigned_to reporter
Message-ID: <bug-58838-4@http.gcc.gnu.org/bugzilla/>
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: 7bit
X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/
Auto-Submitted: auto-generated
MIME-Version: 1.0
X-SW-Source: 2013-10/txt/msg01575.txt.bz2
Content-length: 3174

http://gcc.gnu.org/bugzilla/show_bug.cgi?idX838

            Bug ID: 58838
           Summary: mullw sets condition code incorrectly.
           Product: gcc
           Version: 4.9.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: dougkwan at google dot com

It was observed in 4.7 and trunk that the Power backend generated bad code
involving condition setting mullw.  Below is a test case for the problem:

-----
#include <cassert>
#include <cstdlib>
#include <vector>

struct b88 {
 char data[88];
};

namespace {

inline int int_size(const std::vector<b88>& v) {
 return v.size();
}

}

int __attribute__ ((noinline))
foo(const std::vector<b88>& v) {
 if (int_size(v) > 0) {
   return atoi("1");
 }
 return 0;
}

int main() {
 std::vector<b88> v;
 v.push_back(b88());
 assert(foo(v) != 0);
 return 0;
}
----

The above test failed with gcc 4.7 and trunk for target powerpc64-linux-gnu

We seem to be fine getting out of the middle-end of gcc-4.7:

;; Function int foo(const std::vector<b88>&) (_Z3fooRKSt6vectorI3b88SaIS0_EE,
funcdef_noG3, decl_uid‘36, cgraph_uid\x102)

int foo(const std::vector<b88>&) (const struct vector & v)
{
 int _1;
 struct b88 * _4;
 struct b88 * _5;
 long int _6;
 long int _7;
 long int _8;
 long int _9;
 int _10;
 long int _11;
 int _12;

 <bb 2>:
 _4 = MEM[(const struct vector *)v_3(D)];
 _5 = MEM[(const struct vector *)v_3(D) + 8B];
 _6 = (long int) _5;
 _7 = (long int) _4;
 _8 = _6 - _7;
 _9 = _8 /[ex] 88;
 _10 = (int) _9;
 if (_10 > 0)
   goto <bb 3>;
 else
   goto <bb 4>;

 <bb 3>:
 _11 = strtol ("1", 0B, 10);
 _12 = (int) _11;

 <bb 4>:
 # _1 = PHI <_12(3), 0(2)>
 return _1;

}

RTL expansion looks correct, gcc expands "_8 /[ex] 88;" into shift and
multiplication.

(_8 >> 3) * 0x2e8ba2e8ba2e8ba3.

Since we know that the _8 is a multiple of 88, we can do this.
0x2e8ba2e8ba2e8ba3 is the multiplicative-inverse of 11 in Z{2^64}.


But the selected PPC instruction is bad:

  0x10000b80 <._Z3fooRKSt6vectorI3b88SaIS0_EE>:        lis     r9,11915
  0x10000b84 <._Z3fooRKSt6vectorI3b88SaIS0_EE+4>:      ld      r8,8(r3)
  0x10000b88 <._Z3fooRKSt6vectorI3b88SaIS0_EE+8>:      ld      r10,0(r3)
  0x10000b8c <._Z3fooRKSt6vectorI3b88SaIS0_EE+12>:     ori     r9,r9,41704
  0x10000b90 <._Z3fooRKSt6vectorI3b88SaIS0_EE+16>:     rldicr  r9,r9,32,31
  0x10000b94 <._Z3fooRKSt6vectorI3b88SaIS0_EE+20>:     subf    r10,r10,r8
  0x10000b98 <._Z3fooRKSt6vectorI3b88SaIS0_EE+24>:     oris    r9,r9,47662
  0x10000b9c <._Z3fooRKSt6vectorI3b88SaIS0_EE+28>:     sradi   r10,r10,3
  0x10000ba0 <._Z3fooRKSt6vectorI3b88SaIS0_EE+32>:     ori     r9,r9,35747
  0x10000ba4 <._Z3fooRKSt6vectorI3b88SaIS0_EE+36>:     mullw.  r8,r10,r9
<================ note the "dot"
  0x10000ba8 <._Z3fooRKSt6vectorI3b88SaIS0_EE+40>:     ble     0x10000bf0
<._Z3fooRKSt6vectorI3b88SaIS0_EE+112>

mullw correctly computes the lower 32-bits of  "_9 = _8 /[ex] 88;" but it sets
the condition code incorrectly, since signed-comparison is done in 64 bits.
Instead there should be sign extension, ie.

mullw  r8,r10,r9
extsw. r8,r8


  parent reply	other threads:[~2013-10-22  7:08 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-10-18  6:44 [Bug rtl-optimization/58779] New: " su at cs dot ucdavis.edu
2013-10-18  6:53 ` [Bug rtl-optimization/58779] [4.7/4.8/4.9 Regression] " pinskia at gcc dot gnu.org
2013-10-18  8:16 ` rguenth at gcc dot gnu.org
2013-10-20 21:08 ` mikpelinux at gmail dot com
2013-10-21  6:52 ` [Bug target/58779] " pinskia at gcc dot gnu.org
2013-10-22  6:10 ` ubizjak at gmail dot com
2013-10-22  7:08 ` ubizjak at gmail dot com [this message]
2013-10-22 18:36 ` uros at gcc dot gnu.org
2013-10-22 18:38 ` ubizjak at gmail dot com
2013-10-26  6:02 ` uros at gcc dot gnu.org
2013-10-26  6:09 ` uros at gcc dot gnu.org

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=bug-58779-4-PcTGvf4S9m@http.gcc.gnu.org/bugzilla/ \
    --to=gcc-bugzilla@gcc.gnu.org \
    --cc=gcc-bugs@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).