Message ID | 20221026185857.234023-1-hjl.tools@gmail.com |
---|---|
State | Committed |
Commit | 0e36a9c6915c713d30016cbade97a4b31dcc1350 |
Headers |
Return-Path: <gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org> X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 26D6B388550B for <patchwork@sourceware.org>; Wed, 26 Oct 2022 18:59:30 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 26D6B388550B DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1666810770; bh=8wpWCoxwNDL+cg4gl3EOJSSY+FLkVEajpRSbOmCKnrk=; h=To:Cc:Subject:Date:List-Id:List-Unsubscribe:List-Archive: List-Post:List-Help:List-Subscribe:From:Reply-To:From; b=GbDlbaji43n5W9YHJNGAIEBuaibri7Y5sm0oWRqeSVDx2BcINTGaP8VpCXARRRmPP g4uPBdS55PY9k68EP0cu8nkMIorgAVZNBjvwG5j76uWnv7TUxINDRat77JC1ZmJc13 EeC1sAxKh4vQY7SxuLtMkmlrm7hS7602nj+PUlNM= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-pl1-x633.google.com (mail-pl1-x633.google.com [IPv6:2607:f8b0:4864:20::633]) by sourceware.org (Postfix) with ESMTPS id 3C5A23885507 for <gcc-patches@gcc.gnu.org>; Wed, 26 Oct 2022 18:59:01 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 3C5A23885507 Received: by mail-pl1-x633.google.com with SMTP id f23so15082841plr.6 for <gcc-patches@gcc.gnu.org>; Wed, 26 Oct 2022 11:59:01 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=8wpWCoxwNDL+cg4gl3EOJSSY+FLkVEajpRSbOmCKnrk=; b=qFiEdm+fFQczew28ktYmBeE/rLsxsHT6QzuGSpHvj0eyi3OmZ1FFgFV7sVcaPlI1gC 7sSlF+RCjxSuc4pwNzn4pY0dSHvheM0boX67YOSmbpH2Nw2mYsFAi6C0eV/4bcmi+jJr yU2VaizI9kProDHCyAU8v4ksl9u9WtmNA+sqSK7gVseU6zxzAhJdEs0j3jZhuSwTd9Pq 4Mpi8/B9X0s6kHJ+SRIIuHqVDNZ8MY0uLxX1g0LwVsSWg8I8j37MU5ExvBAbLhDDBRrk e1j+fi9iay0w+Sa5X8I/odmCAbFy//1z1JEQ/zOi9ncOZn4dflRBVC6fxTOedeUPhfJz RbLA== X-Gm-Message-State: ACrzQf23LflP94Wueev8cJOCBBdqQR2aNwokOUNDnhlxTHj/QxwMQacQ gAgsb/6mMgTHJiSWsbv1haP1X8mV0qU= X-Google-Smtp-Source: AMsMyM7VfGgVu0hXgNkB4HwpIqYoqFawUOPmLsYRNAMOFReFs1ihUOnR6P4Ao8OraYRnw2i59MXiOg== X-Received: by 2002:a17:90a:6347:b0:212:fe4a:c363 with SMTP id v7-20020a17090a634700b00212fe4ac363mr5637121pjs.176.1666810739712; Wed, 26 Oct 2022 11:58:59 -0700 (PDT) Received: from gnu-tgl-3.localdomain ([172.56.30.251]) by smtp.gmail.com with ESMTPSA id w12-20020aa7954c000000b005544229b992sm3312555pfq.22.2022.10.26.11.58.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 26 Oct 2022 11:58:59 -0700 (PDT) Received: from gnu-tgl-3.. (localhost [IPv6:::1]) by gnu-tgl-3.localdomain (Postfix) with ESMTP id BBBA0C0539; Wed, 26 Oct 2022 11:58:57 -0700 (PDT) To: gcc-patches@gcc.gnu.org Cc: Uros Bizjak <ubizjak@gmail.com> Subject: [PATCH] x86: Replace ne:CCC/ne:CCO with UNSPEC_CC_NE in neg patterns Date: Wed, 26 Oct 2022 11:58:57 -0700 Message-Id: <20221026185857.234023-1-hjl.tools@gmail.com> X-Mailer: git-send-email 2.37.3 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-3026.4 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list <gcc-patches.gcc.gnu.org> List-Unsubscribe: <https://gcc.gnu.org/mailman/options/gcc-patches>, <mailto:gcc-patches-request@gcc.gnu.org?subject=unsubscribe> List-Archive: <https://gcc.gnu.org/pipermail/gcc-patches/> List-Post: <mailto:gcc-patches@gcc.gnu.org> List-Help: <mailto:gcc-patches-request@gcc.gnu.org?subject=help> List-Subscribe: <https://gcc.gnu.org/mailman/listinfo/gcc-patches>, <mailto:gcc-patches-request@gcc.gnu.org?subject=subscribe> From: "H.J. Lu via Gcc-patches" <gcc-patches@gcc.gnu.org> Reply-To: "H.J. Lu" <hjl.tools@gmail.com> Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" <gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org> |
Series |
x86: Replace ne:CCC/ne:CCO with UNSPEC_CC_NE in neg patterns
|
|
Commit Message
H.J. Lu
Oct. 26, 2022, 6:58 p.m. UTC
In i386.md, neg patterns which set MODE_CC register like (set (reg:CCC FLAGS_REG) (ne:CCC (match_operand:SWI48 1 "general_reg_operand") (const_int 0))) can lead to errors when operand 1 is a constant value. If FLAGS_REG in (set (reg:CCC FLAGS_REG) (ne:CCC (const_int 2) (const_int 0))) is set to 1, RTX simplifiers may simplify (set (reg:SI 93) (neg:SI (ltu:SI (reg:CCC 17 flags) (const_int 0 [0])))) as (set (reg:SI 93) (neg:SI (ltu:SI (const_int 1) (const_int 0 [0])))) which leads to incorrect results since LTU on MODE_CC register isn't the same as "unsigned less than" in x86 backend. To prevent RTL optimizers from setting MODE_CC register to a constant, use UNSPEC_CC_NE to replace ne:CCC/ne:CCO when setting FLAGS_REG in neg patterns. gcc/ PR target/107172 * config/i386/i386.md (UNSPEC_CC_NE): New. Replace ne:CCC/ne:CCO with UNSPEC_CC_NE in neg patterns. gcc/testsuite/ PR target/107172 * gcc.target/i386/pr107172.c: New test. --- gcc/config/i386/i386.md | 45 +++++++++++++----------- gcc/testsuite/gcc.target/i386/pr107172.c | 26 ++++++++++++++ 2 files changed, 51 insertions(+), 20 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/pr107172.c
Comments
On Wed, Oct 26, 2022 at 8:59 PM H.J. Lu <hjl.tools@gmail.com> wrote: > > In i386.md, neg patterns which set MODE_CC register like > > (set (reg:CCC FLAGS_REG) > (ne:CCC (match_operand:SWI48 1 "general_reg_operand") (const_int 0))) > > can lead to errors when operand 1 is a constant value. If FLAGS_REG in > > (set (reg:CCC FLAGS_REG) > (ne:CCC (const_int 2) (const_int 0))) > > is set to 1, RTX simplifiers may simplify > > (set (reg:SI 93) > (neg:SI (ltu:SI (reg:CCC 17 flags) (const_int 0 [0])))) > > as > > (set (reg:SI 93) > (neg:SI (ltu:SI (const_int 1) (const_int 0 [0])))) > > which leads to incorrect results since LTU on MODE_CC register isn't the > same as "unsigned less than" in x86 backend. To prevent RTL optimizers > from setting MODE_CC register to a constant, use UNSPEC_CC_NE to replace > ne:CCC/ne:CCO when setting FLAGS_REG in neg patterns. > > gcc/ > > PR target/107172 > * config/i386/i386.md (UNSPEC_CC_NE): New. > Replace ne:CCC/ne:CCO with UNSPEC_CC_NE in neg patterns. > > gcc/testsuite/ > > PR target/107172 > * gcc.target/i386/pr107172.c: New test. Looking at the PR107172, comments #44 and #45, this patch is a trivial substitution for an invalid RTX. So, OK. Thanks, Uros. > --- > gcc/config/i386/i386.md | 45 +++++++++++++----------- > gcc/testsuite/gcc.target/i386/pr107172.c | 26 ++++++++++++++ > 2 files changed, 51 insertions(+), 20 deletions(-) > create mode 100644 gcc/testsuite/gcc.target/i386/pr107172.c > > diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md > index baf1f1f8fa2..aaa678e7314 100644 > --- a/gcc/config/i386/i386.md > +++ b/gcc/config/i386/i386.md > @@ -113,6 +113,7 @@ (define_c_enum "unspec" [ > UNSPEC_PEEPSIB > UNSPEC_INSN_FALSE_DEP > UNSPEC_SBB > + UNSPEC_CC_NE > > ;; For SSE/MMX support: > UNSPEC_FIX_NOTRUNC > @@ -11470,7 +11471,7 @@ (define_insn_and_split "*neg<dwi>2_doubleword" > "&& reload_completed" > [(parallel > [(set (reg:CCC FLAGS_REG) > - (ne:CCC (match_dup 1) (const_int 0))) > + (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE)) > (set (match_dup 0) (neg:DWIH (match_dup 1)))]) > (parallel > [(set (match_dup 2) > @@ -11499,7 +11500,8 @@ (define_peephole2 > (match_operand:SWI48 1 "nonimmediate_gr_operand")) > (parallel > [(set (reg:CCC FLAGS_REG) > - (ne:CCC (match_operand:SWI48 2 "general_reg_operand") (const_int 0))) > + (unspec:CCC [(match_operand:SWI48 2 "general_reg_operand") > + (const_int 0)] UNSPEC_CC_NE)) > (set (match_dup 2) (neg:SWI48 (match_dup 2)))]) > (parallel > [(set (match_dup 0) > @@ -11517,7 +11519,7 @@ (define_peephole2 > && !reg_mentioned_p (operands[2], operands[1])" > [(parallel > [(set (reg:CCC FLAGS_REG) > - (ne:CCC (match_dup 2) (const_int 0))) > + (unspec:CCC [(match_dup 2) (const_int 0)] UNSPEC_CC_NE)) > (set (match_dup 2) (neg:SWI48 (match_dup 2)))]) > (parallel > [(set (match_dup 0) > @@ -11543,7 +11545,8 @@ (define_peephole2 > (clobber (reg:CC FLAGS_REG))]) > (parallel > [(set (reg:CCC FLAGS_REG) > - (ne:CCC (match_operand:SWI48 1 "general_reg_operand") (const_int 0))) > + (unspec:CCC [(match_operand:SWI48 1 "general_reg_operand") > + (const_int 0)] UNSPEC_CC_NE)) > (set (match_dup 1) (neg:SWI48 (match_dup 1)))]) > (parallel > [(set (match_dup 0) > @@ -11559,7 +11562,7 @@ (define_peephole2 > "REGNO (operands[0]) != REGNO (operands[1])" > [(parallel > [(set (reg:CCC FLAGS_REG) > - (ne:CCC (match_dup 1) (const_int 0))) > + (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE)) > (set (match_dup 1) (neg:SWI48 (match_dup 1)))]) > (parallel > [(set (match_dup 0) > @@ -11635,9 +11638,9 @@ (define_insn "*negsi_2_zext" > > (define_insn "*neg<mode>_ccc_1" > [(set (reg:CCC FLAGS_REG) > - (ne:CCC > - (match_operand:SWI 1 "nonimmediate_operand" "0") > - (const_int 0))) > + (unspec:CCC > + [(match_operand:SWI 1 "nonimmediate_operand" "0") > + (const_int 0)] UNSPEC_CC_NE)) > (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m") > (neg:SWI (match_dup 1)))] > "" > @@ -11647,9 +11650,9 @@ (define_insn "*neg<mode>_ccc_1" > > (define_insn "*neg<mode>_ccc_2" > [(set (reg:CCC FLAGS_REG) > - (ne:CCC > - (match_operand:SWI 1 "nonimmediate_operand" "0") > - (const_int 0))) > + (unspec:CCC > + [(match_operand:SWI 1 "nonimmediate_operand" "0") > + (const_int 0)] UNSPEC_CC_NE)) > (clobber (match_scratch:SWI 0 "=<r>"))] > "" > "neg{<imodesuffix>}\t%0" > @@ -11659,8 +11662,8 @@ (define_insn "*neg<mode>_ccc_2" > (define_expand "x86_neg<mode>_ccc" > [(parallel > [(set (reg:CCC FLAGS_REG) > - (ne:CCC (match_operand:SWI48 1 "register_operand") > - (const_int 0))) > + (unspec:CCC [(match_operand:SWI48 1 "register_operand") > + (const_int 0)] UNSPEC_CC_NE)) > (set (match_operand:SWI48 0 "register_operand") > (neg:SWI48 (match_dup 1)))])]) > > @@ -11686,8 +11689,9 @@ (define_insn "*negqi_ext<mode>_2" > ;; Negate with jump on overflow. > (define_expand "negv<mode>3" > [(parallel [(set (reg:CCO FLAGS_REG) > - (ne:CCO (match_operand:SWI 1 "register_operand") > - (match_dup 3))) > + (unspec:CCO > + [(match_operand:SWI 1 "register_operand") > + (match_dup 3)] UNSPEC_CC_NE)) > (set (match_operand:SWI 0 "register_operand") > (neg:SWI (match_dup 1)))]) > (set (pc) (if_then_else > @@ -11703,8 +11707,9 @@ (define_expand "negv<mode>3" > > (define_insn "*negv<mode>3" > [(set (reg:CCO FLAGS_REG) > - (ne:CCO (match_operand:SWI 1 "nonimmediate_operand" "0") > - (match_operand:SWI 2 "const_int_operand"))) > + (unspec:CCO [(match_operand:SWI 1 "nonimmediate_operand" "0") > + (match_operand:SWI 2 "const_int_operand")] > + UNSPEC_CC_NE)) > (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m") > (neg:SWI (match_dup 1)))] > "ix86_unary_operator_ok (NEG, <MODE>mode, operands) > @@ -11770,7 +11775,7 @@ (define_insn_and_split "*abs<dwi>2_doubleword" > "&& 1" > [(parallel > [(set (reg:CCC FLAGS_REG) > - (ne:CCC (match_dup 1) (const_int 0))) > + (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE)) > (set (match_dup 2) (neg:DWIH (match_dup 1)))]) > (parallel > [(set (match_dup 5) > @@ -11814,7 +11819,7 @@ (define_insn_and_split "*nabs<dwi>2_doubleword" > "&& 1" > [(parallel > [(set (reg:CCC FLAGS_REG) > - (ne:CCC (match_dup 1) (const_int 0))) > + (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE)) > (set (match_dup 2) (neg:DWIH (match_dup 1)))]) > (parallel > [(set (match_dup 5) > @@ -21456,7 +21461,7 @@ (define_split > (const_int 0))))] > "" > [(set (reg:CCC FLAGS_REG) > - (ne:CCC (match_dup 1) (const_int 0))) > + (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE)) > (set (match_dup 0) > (neg:SWI (ltu:SWI (reg:CCC FLAGS_REG) (const_int 0))))]) > > diff --git a/gcc/testsuite/gcc.target/i386/pr107172.c b/gcc/testsuite/gcc.target/i386/pr107172.c > new file mode 100644 > index 00000000000..d2c85f3f47c > --- /dev/null > +++ b/gcc/testsuite/gcc.target/i386/pr107172.c > @@ -0,0 +1,26 @@ > +/* { dg-do run } */ > +/* { dg-options "-O1 -ftree-vrp" } */ > + > +int a, c, d; > +int > +main() > +{ > + long e = 1; > + int f = a = 1; > +L1: > + if (a) > + a = 2; > + int h = e = ~e; > + c = -1; > + if (e >= a) > + goto L2; > + if (-1 > a) > + goto L1; > + if (a) > + f = -1; > +L2: > + d = (-f + d) & h; > + if (d) > + __builtin_abort(); > + return 0; > +} > -- > 2.37.3 >
On Thu, Oct 27, 2022 at 2:59 AM H.J. Lu via Gcc-patches <gcc-patches@gcc.gnu.org> wrote: > > In i386.md, neg patterns which set MODE_CC register like > > (set (reg:CCC FLAGS_REG) > (ne:CCC (match_operand:SWI48 1 "general_reg_operand") (const_int 0))) > > can lead to errors when operand 1 is a constant value. If FLAGS_REG in > > (set (reg:CCC FLAGS_REG) > (ne:CCC (const_int 2) (const_int 0))) > > is set to 1, RTX simplifiers may simplify > > (set (reg:SI 93) > (neg:SI (ltu:SI (reg:CCC 17 flags) (const_int 0 [0])))) > > as > > (set (reg:SI 93) > (neg:SI (ltu:SI (const_int 1) (const_int 0 [0])))) > > which leads to incorrect results since LTU on MODE_CC register isn't the > same as "unsigned less than" in x86 backend. To prevent RTL optimizers > from setting MODE_CC register to a constant, use UNSPEC_CC_NE to replace > ne:CCC/ne:CCO when setting FLAGS_REG in neg patterns. > > gcc/ > > PR target/107172 > * config/i386/i386.md (UNSPEC_CC_NE): New. > Replace ne:CCC/ne:CCO with UNSPEC_CC_NE in neg patterns. > > gcc/testsuite/ > > PR target/107172 > * gcc.target/i386/pr107172.c: New test. > --- > gcc/config/i386/i386.md | 45 +++++++++++++----------- > gcc/testsuite/gcc.target/i386/pr107172.c | 26 ++++++++++++++ > 2 files changed, 51 insertions(+), 20 deletions(-) > create mode 100644 gcc/testsuite/gcc.target/i386/pr107172.c > > diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md > index baf1f1f8fa2..aaa678e7314 100644 > --- a/gcc/config/i386/i386.md > +++ b/gcc/config/i386/i386.md > @@ -113,6 +113,7 @@ (define_c_enum "unspec" [ > UNSPEC_PEEPSIB > UNSPEC_INSN_FALSE_DEP > UNSPEC_SBB > + UNSPEC_CC_NE > > ;; For SSE/MMX support: > UNSPEC_FIX_NOTRUNC > @@ -11470,7 +11471,7 @@ (define_insn_and_split "*neg<dwi>2_doubleword" > "&& reload_completed" > [(parallel > [(set (reg:CCC FLAGS_REG) > - (ne:CCC (match_dup 1) (const_int 0))) > + (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE)) > (set (match_dup 0) (neg:DWIH (match_dup 1)))]) > (parallel > [(set (match_dup 2) > @@ -11499,7 +11500,8 @@ (define_peephole2 > (match_operand:SWI48 1 "nonimmediate_gr_operand")) > (parallel > [(set (reg:CCC FLAGS_REG) > - (ne:CCC (match_operand:SWI48 2 "general_reg_operand") (const_int 0))) > + (unspec:CCC [(match_operand:SWI48 2 "general_reg_operand") > + (const_int 0)] UNSPEC_CC_NE)) > (set (match_dup 2) (neg:SWI48 (match_dup 2)))]) > (parallel > [(set (match_dup 0) > @@ -11517,7 +11519,7 @@ (define_peephole2 > && !reg_mentioned_p (operands[2], operands[1])" > [(parallel > [(set (reg:CCC FLAGS_REG) > - (ne:CCC (match_dup 2) (const_int 0))) > + (unspec:CCC [(match_dup 2) (const_int 0)] UNSPEC_CC_NE)) > (set (match_dup 2) (neg:SWI48 (match_dup 2)))]) > (parallel > [(set (match_dup 0) > @@ -11543,7 +11545,8 @@ (define_peephole2 > (clobber (reg:CC FLAGS_REG))]) > (parallel > [(set (reg:CCC FLAGS_REG) > - (ne:CCC (match_operand:SWI48 1 "general_reg_operand") (const_int 0))) > + (unspec:CCC [(match_operand:SWI48 1 "general_reg_operand") > + (const_int 0)] UNSPEC_CC_NE)) > (set (match_dup 1) (neg:SWI48 (match_dup 1)))]) > (parallel > [(set (match_dup 0) > @@ -11559,7 +11562,7 @@ (define_peephole2 > "REGNO (operands[0]) != REGNO (operands[1])" > [(parallel > [(set (reg:CCC FLAGS_REG) > - (ne:CCC (match_dup 1) (const_int 0))) > + (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE)) > (set (match_dup 1) (neg:SWI48 (match_dup 1)))]) > (parallel > [(set (match_dup 0) > @@ -11635,9 +11638,9 @@ (define_insn "*negsi_2_zext" > > (define_insn "*neg<mode>_ccc_1" > [(set (reg:CCC FLAGS_REG) > - (ne:CCC > - (match_operand:SWI 1 "nonimmediate_operand" "0") > - (const_int 0))) > + (unspec:CCC > + [(match_operand:SWI 1 "nonimmediate_operand" "0") > + (const_int 0)] UNSPEC_CC_NE)) > (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m") > (neg:SWI (match_dup 1)))] > "" > @@ -11647,9 +11650,9 @@ (define_insn "*neg<mode>_ccc_1" > > (define_insn "*neg<mode>_ccc_2" > [(set (reg:CCC FLAGS_REG) > - (ne:CCC > - (match_operand:SWI 1 "nonimmediate_operand" "0") > - (const_int 0))) > + (unspec:CCC > + [(match_operand:SWI 1 "nonimmediate_operand" "0") > + (const_int 0)] UNSPEC_CC_NE)) > (clobber (match_scratch:SWI 0 "=<r>"))] > "" > "neg{<imodesuffix>}\t%0" > @@ -11659,8 +11662,8 @@ (define_insn "*neg<mode>_ccc_2" > (define_expand "x86_neg<mode>_ccc" > [(parallel > [(set (reg:CCC FLAGS_REG) > - (ne:CCC (match_operand:SWI48 1 "register_operand") > - (const_int 0))) > + (unspec:CCC [(match_operand:SWI48 1 "register_operand") > + (const_int 0)] UNSPEC_CC_NE)) > (set (match_operand:SWI48 0 "register_operand") > (neg:SWI48 (match_dup 1)))])]) > > @@ -11686,8 +11689,9 @@ (define_insn "*negqi_ext<mode>_2" > ;; Negate with jump on overflow. > (define_expand "negv<mode>3" > [(parallel [(set (reg:CCO FLAGS_REG) > - (ne:CCO (match_operand:SWI 1 "register_operand") > - (match_dup 3))) > + (unspec:CCO > + [(match_operand:SWI 1 "register_operand") > + (match_dup 3)] UNSPEC_CC_NE)) > (set (match_operand:SWI 0 "register_operand") > (neg:SWI (match_dup 1)))]) > (set (pc) (if_then_else > @@ -11703,8 +11707,9 @@ (define_expand "negv<mode>3" > > (define_insn "*negv<mode>3" > [(set (reg:CCO FLAGS_REG) > - (ne:CCO (match_operand:SWI 1 "nonimmediate_operand" "0") > - (match_operand:SWI 2 "const_int_operand"))) > + (unspec:CCO [(match_operand:SWI 1 "nonimmediate_operand" "0") > + (match_operand:SWI 2 "const_int_operand")] > + UNSPEC_CC_NE)) > (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m") > (neg:SWI (match_dup 1)))] > "ix86_unary_operator_ok (NEG, <MODE>mode, operands) > @@ -11770,7 +11775,7 @@ (define_insn_and_split "*abs<dwi>2_doubleword" > "&& 1" > [(parallel > [(set (reg:CCC FLAGS_REG) > - (ne:CCC (match_dup 1) (const_int 0))) > + (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE)) > (set (match_dup 2) (neg:DWIH (match_dup 1)))]) > (parallel > [(set (match_dup 5) > @@ -11814,7 +11819,7 @@ (define_insn_and_split "*nabs<dwi>2_doubleword" > "&& 1" > [(parallel > [(set (reg:CCC FLAGS_REG) > - (ne:CCC (match_dup 1) (const_int 0))) > + (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE)) > (set (match_dup 2) (neg:DWIH (match_dup 1)))]) > (parallel > [(set (match_dup 5) > @@ -21456,7 +21461,7 @@ (define_split > (const_int 0))))] > "" > [(set (reg:CCC FLAGS_REG) > - (ne:CCC (match_dup 1) (const_int 0))) > + (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE)) Do we have a define_insn for this? It looks like a setcc to me. > (set (match_dup 0) > (neg:SWI (ltu:SWI (reg:CCC FLAGS_REG) (const_int 0))))]) > > diff --git a/gcc/testsuite/gcc.target/i386/pr107172.c b/gcc/testsuite/gcc.target/i386/pr107172.c > new file mode 100644 > index 00000000000..d2c85f3f47c > --- /dev/null > +++ b/gcc/testsuite/gcc.target/i386/pr107172.c > @@ -0,0 +1,26 @@ > +/* { dg-do run } */ > +/* { dg-options "-O1 -ftree-vrp" } */ > + > +int a, c, d; > +int > +main() > +{ > + long e = 1; > + int f = a = 1; > +L1: > + if (a) > + a = 2; > + int h = e = ~e; > + c = -1; > + if (e >= a) > + goto L2; > + if (-1 > a) > + goto L1; > + if (a) > + f = -1; > +L2: > + d = (-f + d) & h; > + if (d) > + __builtin_abort(); > + return 0; > +} > -- > 2.37.3 >
On Fri, Oct 28, 2022 at 1:56 PM Hongtao Liu <crazylht@gmail.com> wrote: > > On Thu, Oct 27, 2022 at 2:59 AM H.J. Lu via Gcc-patches > <gcc-patches@gcc.gnu.org> wrote: > > > > In i386.md, neg patterns which set MODE_CC register like > > > > (set (reg:CCC FLAGS_REG) > > (ne:CCC (match_operand:SWI48 1 "general_reg_operand") (const_int 0))) > > > > can lead to errors when operand 1 is a constant value. If FLAGS_REG in > > > > (set (reg:CCC FLAGS_REG) > > (ne:CCC (const_int 2) (const_int 0))) > > > > is set to 1, RTX simplifiers may simplify > > > > (set (reg:SI 93) > > (neg:SI (ltu:SI (reg:CCC 17 flags) (const_int 0 [0])))) > > > > as > > > > (set (reg:SI 93) > > (neg:SI (ltu:SI (const_int 1) (const_int 0 [0])))) > > > > which leads to incorrect results since LTU on MODE_CC register isn't the > > same as "unsigned less than" in x86 backend. To prevent RTL optimizers > > from setting MODE_CC register to a constant, use UNSPEC_CC_NE to replace > > ne:CCC/ne:CCO when setting FLAGS_REG in neg patterns. > > > > gcc/ > > > > PR target/107172 > > * config/i386/i386.md (UNSPEC_CC_NE): New. > > Replace ne:CCC/ne:CCO with UNSPEC_CC_NE in neg patterns. > > > > gcc/testsuite/ > > > > PR target/107172 > > * gcc.target/i386/pr107172.c: New test. > > --- > > gcc/config/i386/i386.md | 45 +++++++++++++----------- > > gcc/testsuite/gcc.target/i386/pr107172.c | 26 ++++++++++++++ > > 2 files changed, 51 insertions(+), 20 deletions(-) > > create mode 100644 gcc/testsuite/gcc.target/i386/pr107172.c > > > > diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md > > index baf1f1f8fa2..aaa678e7314 100644 > > --- a/gcc/config/i386/i386.md > > +++ b/gcc/config/i386/i386.md > > @@ -113,6 +113,7 @@ (define_c_enum "unspec" [ > > UNSPEC_PEEPSIB > > UNSPEC_INSN_FALSE_DEP > > UNSPEC_SBB > > + UNSPEC_CC_NE > > > > ;; For SSE/MMX support: > > UNSPEC_FIX_NOTRUNC > > @@ -11470,7 +11471,7 @@ (define_insn_and_split "*neg<dwi>2_doubleword" > > "&& reload_completed" > > [(parallel > > [(set (reg:CCC FLAGS_REG) > > - (ne:CCC (match_dup 1) (const_int 0))) > > + (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE)) > > (set (match_dup 0) (neg:DWIH (match_dup 1)))]) > > (parallel > > [(set (match_dup 2) > > @@ -11499,7 +11500,8 @@ (define_peephole2 > > (match_operand:SWI48 1 "nonimmediate_gr_operand")) > > (parallel > > [(set (reg:CCC FLAGS_REG) > > - (ne:CCC (match_operand:SWI48 2 "general_reg_operand") (const_int 0))) > > + (unspec:CCC [(match_operand:SWI48 2 "general_reg_operand") > > + (const_int 0)] UNSPEC_CC_NE)) > > (set (match_dup 2) (neg:SWI48 (match_dup 2)))]) > > (parallel > > [(set (match_dup 0) > > @@ -11517,7 +11519,7 @@ (define_peephole2 > > && !reg_mentioned_p (operands[2], operands[1])" > > [(parallel > > [(set (reg:CCC FLAGS_REG) > > - (ne:CCC (match_dup 2) (const_int 0))) > > + (unspec:CCC [(match_dup 2) (const_int 0)] UNSPEC_CC_NE)) > > (set (match_dup 2) (neg:SWI48 (match_dup 2)))]) > > (parallel > > [(set (match_dup 0) > > @@ -11543,7 +11545,8 @@ (define_peephole2 > > (clobber (reg:CC FLAGS_REG))]) > > (parallel > > [(set (reg:CCC FLAGS_REG) > > - (ne:CCC (match_operand:SWI48 1 "general_reg_operand") (const_int 0))) > > + (unspec:CCC [(match_operand:SWI48 1 "general_reg_operand") > > + (const_int 0)] UNSPEC_CC_NE)) > > (set (match_dup 1) (neg:SWI48 (match_dup 1)))]) > > (parallel > > [(set (match_dup 0) > > @@ -11559,7 +11562,7 @@ (define_peephole2 > > "REGNO (operands[0]) != REGNO (operands[1])" > > [(parallel > > [(set (reg:CCC FLAGS_REG) > > - (ne:CCC (match_dup 1) (const_int 0))) > > + (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE)) > > (set (match_dup 1) (neg:SWI48 (match_dup 1)))]) > > (parallel > > [(set (match_dup 0) > > @@ -11635,9 +11638,9 @@ (define_insn "*negsi_2_zext" > > > > (define_insn "*neg<mode>_ccc_1" > > [(set (reg:CCC FLAGS_REG) > > - (ne:CCC > > - (match_operand:SWI 1 "nonimmediate_operand" "0") > > - (const_int 0))) > > + (unspec:CCC > > + [(match_operand:SWI 1 "nonimmediate_operand" "0") > > + (const_int 0)] UNSPEC_CC_NE)) > > (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m") > > (neg:SWI (match_dup 1)))] > > "" > > @@ -11647,9 +11650,9 @@ (define_insn "*neg<mode>_ccc_1" > > > > (define_insn "*neg<mode>_ccc_2" > > [(set (reg:CCC FLAGS_REG) > > - (ne:CCC > > - (match_operand:SWI 1 "nonimmediate_operand" "0") > > - (const_int 0))) > > + (unspec:CCC > > + [(match_operand:SWI 1 "nonimmediate_operand" "0") > > + (const_int 0)] UNSPEC_CC_NE)) > > (clobber (match_scratch:SWI 0 "=<r>"))] > > "" > > "neg{<imodesuffix>}\t%0" > > @@ -11659,8 +11662,8 @@ (define_insn "*neg<mode>_ccc_2" > > (define_expand "x86_neg<mode>_ccc" > > [(parallel > > [(set (reg:CCC FLAGS_REG) > > - (ne:CCC (match_operand:SWI48 1 "register_operand") > > - (const_int 0))) > > + (unspec:CCC [(match_operand:SWI48 1 "register_operand") > > + (const_int 0)] UNSPEC_CC_NE)) > > (set (match_operand:SWI48 0 "register_operand") > > (neg:SWI48 (match_dup 1)))])]) > > > > @@ -11686,8 +11689,9 @@ (define_insn "*negqi_ext<mode>_2" > > ;; Negate with jump on overflow. > > (define_expand "negv<mode>3" > > [(parallel [(set (reg:CCO FLAGS_REG) > > - (ne:CCO (match_operand:SWI 1 "register_operand") > > - (match_dup 3))) > > + (unspec:CCO > > + [(match_operand:SWI 1 "register_operand") > > + (match_dup 3)] UNSPEC_CC_NE)) > > (set (match_operand:SWI 0 "register_operand") > > (neg:SWI (match_dup 1)))]) > > (set (pc) (if_then_else > > @@ -11703,8 +11707,9 @@ (define_expand "negv<mode>3" > > > > (define_insn "*negv<mode>3" > > [(set (reg:CCO FLAGS_REG) > > - (ne:CCO (match_operand:SWI 1 "nonimmediate_operand" "0") > > - (match_operand:SWI 2 "const_int_operand"))) > > + (unspec:CCO [(match_operand:SWI 1 "nonimmediate_operand" "0") > > + (match_operand:SWI 2 "const_int_operand")] > > + UNSPEC_CC_NE)) > > (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m") > > (neg:SWI (match_dup 1)))] > > "ix86_unary_operator_ok (NEG, <MODE>mode, operands) > > @@ -11770,7 +11775,7 @@ (define_insn_and_split "*abs<dwi>2_doubleword" > > "&& 1" > > [(parallel > > [(set (reg:CCC FLAGS_REG) > > - (ne:CCC (match_dup 1) (const_int 0))) > > + (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE)) > > (set (match_dup 2) (neg:DWIH (match_dup 1)))]) > > (parallel > > [(set (match_dup 5) > > @@ -11814,7 +11819,7 @@ (define_insn_and_split "*nabs<dwi>2_doubleword" > > "&& 1" > > [(parallel > > [(set (reg:CCC FLAGS_REG) > > - (ne:CCC (match_dup 1) (const_int 0))) > > + (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE)) > > (set (match_dup 2) (neg:DWIH (match_dup 1)))]) > > (parallel > > [(set (match_dup 5) > > @@ -21456,7 +21461,7 @@ (define_split > > (const_int 0))))] > > [(set (reg:CCC FLAGS_REG) > > - (ne:CCC (match_dup 1) (const_int 0))) > > + (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE)) > Do we have a define_insn for this? It looks like a setcc to me. It's not, nevermind. > > (set (match_dup 0) > > (neg:SWI (ltu:SWI (reg:CCC FLAGS_REG) (const_int 0))))]) > > > > diff --git a/gcc/testsuite/gcc.target/i386/pr107172.c b/gcc/testsuite/gcc.target/i386/pr107172.c > > new file mode 100644 > > index 00000000000..d2c85f3f47c > > --- /dev/null > > +++ b/gcc/testsuite/gcc.target/i386/pr107172.c > > @@ -0,0 +1,26 @@ > > +/* { dg-do run } */ > > +/* { dg-options "-O1 -ftree-vrp" } */ > > + > > +int a, c, d; > > +int > > +main() > > +{ > > + long e = 1; > > + int f = a = 1; > > +L1: > > + if (a) > > + a = 2; > > + int h = e = ~e; > > + c = -1; > > + if (e >= a) > > + goto L2; > > + if (-1 > a) > > + goto L1; > > + if (a) > > + f = -1; > > +L2: > > + d = (-f + d) & h; > > + if (d) > > + __builtin_abort(); > > + return 0; > > +} > > -- > > 2.37.3 > > > > > -- > BR, > Hongtao
> (set (reg:SI 93) > (neg:SI (ltu:SI (reg:CCC 17 flags) (const_int 0 [0])))) > > as > > (set (reg:SI 93) > (neg:SI (ltu:SI (const_int 1) (const_int 0 [0])))) > > which leads to incorrect results since LTU on MODE_CC register isn't the > same as "unsigned less than" in x86 backend. That's not specific to the x86 back-end, i.e. it's a generic caveat. > PR target/107172 > * config/i386/i386.md (UNSPEC_CC_NE): New. > Replace ne:CCC/ne:CCO with UNSPEC_CC_NE in neg patterns. FWIW the SPARC back-end uses a COMPARE instead of an UNSPEC here.
On Fri, Oct 28, 2022 at 1:35 AM Eric Botcazou <botcazou@adacore.com> wrote: > > > (set (reg:SI 93) > > (neg:SI (ltu:SI (reg:CCC 17 flags) (const_int 0 [0])))) > > > > as > > > > (set (reg:SI 93) > > (neg:SI (ltu:SI (const_int 1) (const_int 0 [0])))) > > > > which leads to incorrect results since LTU on MODE_CC register isn't the > > same as "unsigned less than" in x86 backend. > > That's not specific to the x86 back-end, i.e. it's a generic caveat. > > > PR target/107172 > > * config/i386/i386.md (UNSPEC_CC_NE): New. > > Replace ne:CCC/ne:CCO with UNSPEC_CC_NE in neg patterns. > > FWIW the SPARC back-end uses a COMPARE instead of an UNSPEC here. COMPARE may also set CC register to a constant when both operands are known constants.
> COMPARE may also set CC register to a constant when both operands are > known constants. No, a COMPARE is never evaluated alone, only the CC user may be evaluated.
On Wed, Oct 26, 2022 at 11:58:57AM -0700, H.J. Lu via Gcc-patches wrote: > In i386.md, neg patterns which set MODE_CC register like > > (set (reg:CCC FLAGS_REG) > (ne:CCC (match_operand:SWI48 1 "general_reg_operand") (const_int 0))) > > can lead to errors when operand 1 is a constant value. If FLAGS_REG in But it cannot be. general_reg_operand will not allow that: === (define_predicate "general_reg_operand" (and (match_code "reg") (match_test "GENERAL_REGNO_P (REGNO (op))"))) === > (set (reg:CCC FLAGS_REG) > (ne:CCC (const_int 2) (const_int 0))) > > is set to 1, RTX simplifiers may simplify "is set to 1"? Do you mean you do something like (set (regs FLAGS_REG) (const_int 1)) ? That is invalid RTL, as I've said tens of time in the last few weeks. > which leads to incorrect results since LTU on MODE_CC register isn't the > same as "unsigned less than" in x86 backend. The special notation (ltu (reg:CC) (const_int 0)) is not about comparing anything to 0, but simply means "did the comparison-like thing that set that reg say ltu was true". > To prevent RTL optimizers > from setting MODE_CC register to a constant, use UNSPEC_CC_NE to replace > ne:CCC/ne:CCO when setting FLAGS_REG in neg patterns. This is an indirect workaround, nothing more. The unspec will naturally not be folded to anything else (unless you arrange for that yourself), there is nothing the generic code knows about the semantics of any unspec after all. AFIACS there is no way to express overflow in a CC, but an unspec can help, sure. You need to fix the setter side as well though. Segher
Hi! On Fri, Oct 28, 2022 at 10:35:03AM +0200, Eric Botcazou via Gcc-patches wrote: > > (set (reg:SI 93) > > (neg:SI (ltu:SI (reg:CCC 17 flags) (const_int 0 [0])))) > > > > as > > > > (set (reg:SI 93) > > (neg:SI (ltu:SI (const_int 1) (const_int 0 [0])))) > > > > which leads to incorrect results since LTU on MODE_CC register isn't the > > same as "unsigned less than" in x86 backend. > > That's not specific to the x86 back-end, i.e. it's a generic caveat. A MODE_CC reg can never be "const_int 1". That is total garbage. It cannot work. It would mean all of (eq (reg:CC) (const_int 0)) (lt (reg:CC) (const_int 0)) (gt (reg:CC) (const_int 0)) (ne (reg:CC) (const_int 0)) (ge (reg:CC) (const_int 0)) (le (reg:CC) (const_int 0)) (and more) are simultaneously true. > > PR target/107172 > > * config/i386/i386.md (UNSPEC_CC_NE): New. > > Replace ne:CCC/ne:CCO with UNSPEC_CC_NE in neg patterns. > > FWIW the SPARC back-end uses a COMPARE instead of an UNSPEC here. You mean in CCV? That works yes, but only because (or if) the setter and getter of the CC reg both use CCV (so never use any other flag at the same time; CCV has an empty intersection with all other CC modes). Segher
> You mean in CCV? That works yes, but only because (or if) the setter > and getter of the CC reg both use CCV (so never use any other flag at > the same time; CCV has an empty intersection with all other CC modes). We're talking about CCC here AFAIK, i.e. the carry, not CCV.
On Fri, Oct 28, 2022 at 2:34 PM Segher Boessenkool <segher@kernel.crashing.org> wrote: > > On Wed, Oct 26, 2022 at 11:58:57AM -0700, H.J. Lu via Gcc-patches wrote: > > In i386.md, neg patterns which set MODE_CC register like > > > > (set (reg:CCC FLAGS_REG) > > (ne:CCC (match_operand:SWI48 1 "general_reg_operand") (const_int 0))) > > > > can lead to errors when operand 1 is a constant value. If FLAGS_REG in > > But it cannot be. general_reg_operand will not allow that: > === > (define_predicate "general_reg_operand" > (and (match_code "reg") > (match_test "GENERAL_REGNO_P (REGNO (op))"))) > === > > > (set (reg:CCC FLAGS_REG) > > (ne:CCC (const_int 2) (const_int 0))) > > > > is set to 1, RTX simplifiers may simplify > Here is another example: (define_insn "*neg<mode>_ccc_1" [(set (reg:CCC FLAGS_REG) (ne:CCC (match_operand:SWI 1 "nonimmediate_operand" "0") (const_int 0))) (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m") (neg:SWI (match_dup 1)))] "" "neg{<imodesuffix>}\t%0" [(set_attr "type" "negnot") (set_attr "mode" "<MODE>")]) Operand 1 can be a known value. H.J.
On Fri, Oct 28, 2022 at 11:55:35PM +0200, Eric Botcazou wrote: > > You mean in CCV? That works yes, but only because (or if) the setter > > and getter of the CC reg both use CCV (so never use any other flag at > > the same time; CCV has an empty intersection with all other CC modes). > > We're talking about CCC here AFAIK, i.e. the carry, not CCV. Yes. But it is all the same: neither signed overflow nor unsigned overflow (of an addition, say) can be described as the result of an RTL comparison. The point is that all of this is put completely outside of all other MODE_CC handling, and only works because of that. And a small modification to the backend, completely elsewhere, can make that house of cards collapse. It is much more robust to use a different relation, not EQ, to decribe this. Something with an unspec is fine. But what the sparc backend does does work. Segher
> Yes. But it is all the same: neither signed overflow nor unsigned > overflow (of an addition, say) can be described as the result of an > RTL comparison. I disagree, see for example the implementation of the addvdi4_sp3 pattern (for which we indeed use an UNSPEC) and of the uaddvdi4_sp32 pattern (for which we describe the overflow with a COMPARE) in the SPARC back-end. And that's even simpler for an unsigned subtraction, where we do not need a special CC mode. Sure there is a technical difficulty for unsigned negation because of the canonicalization rules, hence the trick used in the SPARC back-end, but unsigned overflow is much easier to deal with than signed overflow.
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index baf1f1f8fa2..aaa678e7314 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -113,6 +113,7 @@ (define_c_enum "unspec" [ UNSPEC_PEEPSIB UNSPEC_INSN_FALSE_DEP UNSPEC_SBB + UNSPEC_CC_NE ;; For SSE/MMX support: UNSPEC_FIX_NOTRUNC @@ -11470,7 +11471,7 @@ (define_insn_and_split "*neg<dwi>2_doubleword" "&& reload_completed" [(parallel [(set (reg:CCC FLAGS_REG) - (ne:CCC (match_dup 1) (const_int 0))) + (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE)) (set (match_dup 0) (neg:DWIH (match_dup 1)))]) (parallel [(set (match_dup 2) @@ -11499,7 +11500,8 @@ (define_peephole2 (match_operand:SWI48 1 "nonimmediate_gr_operand")) (parallel [(set (reg:CCC FLAGS_REG) - (ne:CCC (match_operand:SWI48 2 "general_reg_operand") (const_int 0))) + (unspec:CCC [(match_operand:SWI48 2 "general_reg_operand") + (const_int 0)] UNSPEC_CC_NE)) (set (match_dup 2) (neg:SWI48 (match_dup 2)))]) (parallel [(set (match_dup 0) @@ -11517,7 +11519,7 @@ (define_peephole2 && !reg_mentioned_p (operands[2], operands[1])" [(parallel [(set (reg:CCC FLAGS_REG) - (ne:CCC (match_dup 2) (const_int 0))) + (unspec:CCC [(match_dup 2) (const_int 0)] UNSPEC_CC_NE)) (set (match_dup 2) (neg:SWI48 (match_dup 2)))]) (parallel [(set (match_dup 0) @@ -11543,7 +11545,8 @@ (define_peephole2 (clobber (reg:CC FLAGS_REG))]) (parallel [(set (reg:CCC FLAGS_REG) - (ne:CCC (match_operand:SWI48 1 "general_reg_operand") (const_int 0))) + (unspec:CCC [(match_operand:SWI48 1 "general_reg_operand") + (const_int 0)] UNSPEC_CC_NE)) (set (match_dup 1) (neg:SWI48 (match_dup 1)))]) (parallel [(set (match_dup 0) @@ -11559,7 +11562,7 @@ (define_peephole2 "REGNO (operands[0]) != REGNO (operands[1])" [(parallel [(set (reg:CCC FLAGS_REG) - (ne:CCC (match_dup 1) (const_int 0))) + (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE)) (set (match_dup 1) (neg:SWI48 (match_dup 1)))]) (parallel [(set (match_dup 0) @@ -11635,9 +11638,9 @@ (define_insn "*negsi_2_zext" (define_insn "*neg<mode>_ccc_1" [(set (reg:CCC FLAGS_REG) - (ne:CCC - (match_operand:SWI 1 "nonimmediate_operand" "0") - (const_int 0))) + (unspec:CCC + [(match_operand:SWI 1 "nonimmediate_operand" "0") + (const_int 0)] UNSPEC_CC_NE)) (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m") (neg:SWI (match_dup 1)))] "" @@ -11647,9 +11650,9 @@ (define_insn "*neg<mode>_ccc_1" (define_insn "*neg<mode>_ccc_2" [(set (reg:CCC FLAGS_REG) - (ne:CCC - (match_operand:SWI 1 "nonimmediate_operand" "0") - (const_int 0))) + (unspec:CCC + [(match_operand:SWI 1 "nonimmediate_operand" "0") + (const_int 0)] UNSPEC_CC_NE)) (clobber (match_scratch:SWI 0 "=<r>"))] "" "neg{<imodesuffix>}\t%0" @@ -11659,8 +11662,8 @@ (define_insn "*neg<mode>_ccc_2" (define_expand "x86_neg<mode>_ccc" [(parallel [(set (reg:CCC FLAGS_REG) - (ne:CCC (match_operand:SWI48 1 "register_operand") - (const_int 0))) + (unspec:CCC [(match_operand:SWI48 1 "register_operand") + (const_int 0)] UNSPEC_CC_NE)) (set (match_operand:SWI48 0 "register_operand") (neg:SWI48 (match_dup 1)))])]) @@ -11686,8 +11689,9 @@ (define_insn "*negqi_ext<mode>_2" ;; Negate with jump on overflow. (define_expand "negv<mode>3" [(parallel [(set (reg:CCO FLAGS_REG) - (ne:CCO (match_operand:SWI 1 "register_operand") - (match_dup 3))) + (unspec:CCO + [(match_operand:SWI 1 "register_operand") + (match_dup 3)] UNSPEC_CC_NE)) (set (match_operand:SWI 0 "register_operand") (neg:SWI (match_dup 1)))]) (set (pc) (if_then_else @@ -11703,8 +11707,9 @@ (define_expand "negv<mode>3" (define_insn "*negv<mode>3" [(set (reg:CCO FLAGS_REG) - (ne:CCO (match_operand:SWI 1 "nonimmediate_operand" "0") - (match_operand:SWI 2 "const_int_operand"))) + (unspec:CCO [(match_operand:SWI 1 "nonimmediate_operand" "0") + (match_operand:SWI 2 "const_int_operand")] + UNSPEC_CC_NE)) (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m") (neg:SWI (match_dup 1)))] "ix86_unary_operator_ok (NEG, <MODE>mode, operands) @@ -11770,7 +11775,7 @@ (define_insn_and_split "*abs<dwi>2_doubleword" "&& 1" [(parallel [(set (reg:CCC FLAGS_REG) - (ne:CCC (match_dup 1) (const_int 0))) + (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE)) (set (match_dup 2) (neg:DWIH (match_dup 1)))]) (parallel [(set (match_dup 5) @@ -11814,7 +11819,7 @@ (define_insn_and_split "*nabs<dwi>2_doubleword" "&& 1" [(parallel [(set (reg:CCC FLAGS_REG) - (ne:CCC (match_dup 1) (const_int 0))) + (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE)) (set (match_dup 2) (neg:DWIH (match_dup 1)))]) (parallel [(set (match_dup 5) @@ -21456,7 +21461,7 @@ (define_split (const_int 0))))] "" [(set (reg:CCC FLAGS_REG) - (ne:CCC (match_dup 1) (const_int 0))) + (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE)) (set (match_dup 0) (neg:SWI (ltu:SWI (reg:CCC FLAGS_REG) (const_int 0))))]) diff --git a/gcc/testsuite/gcc.target/i386/pr107172.c b/gcc/testsuite/gcc.target/i386/pr107172.c new file mode 100644 index 00000000000..d2c85f3f47c --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr107172.c @@ -0,0 +1,26 @@ +/* { dg-do run } */ +/* { dg-options "-O1 -ftree-vrp" } */ + +int a, c, d; +int +main() +{ + long e = 1; + int f = a = 1; +L1: + if (a) + a = 2; + int h = e = ~e; + c = -1; + if (e >= a) + goto L2; + if (-1 > a) + goto L1; + if (a) + f = -1; +L2: + d = (-f + d) & h; + if (d) + __builtin_abort(); + return 0; +}