[Bug target/107172] [13 Regression] wrong code with "-O1 -ftree-vrp" on x86_64-linux-gnu since r13-1268-g8c99e307b20c502e

2023-07-27 Thread shaohua.li at inf dot ethz.ch via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107172

--- Comment #52 from Shaohua Li  ---
*** Bug 107257 has been marked as a duplicate of this bug. ***

[Bug target/107172] [13 Regression] wrong code with "-O1 -ftree-vrp" on x86_64-linux-gnu since r13-1268-g8c99e307b20c502e

2023-05-30 Thread cvs-commit at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107172

--- Comment #51 from CVS Commits  ---
The master branch has been updated by Roger Sayle :

https://gcc.gnu.org/g:69185294f322dd53d4e1592115014c5488302e2e

commit r14-1405-g69185294f322dd53d4e1592115014c5488302e2e
Author: Roger Sayle 
Date:   Tue May 30 14:40:50 2023 +0100

PR target/107172: Avoid "unusual" MODE_CC comparisons in simplify-rtx.cc

I believe that a better (or supplementary) fix to PR target/107172 is to
avoid producing incorrect (but valid) RTL in
simplify_const_relational_operation when presented with questionable
(obviously invalid) expressions, such as those produced during combine.
Just as with the "first do no harm" clause with the Hippocratic Oath,
simplify-rtx (probably) shouldn't unintentionally transform invalid RTL
expressions, into incorrect (non-equivalent) but valid RTL that may be
inappropriately recognized by recog.

In this specific case, many GCC backends represent their flags register via
MODE_CC, whose representation is intentionally "opaque" to the middle-end.
The only use of MODE_CC comprehensible to the middle-end's RTL optimizers
is relational comparisons between the result of a COMPARE rtx (op0) and
zero
(op1).  Any other uses of MODE_CC should be left alone, and some might
argue
indicate representational issues in the backend.

In practice, CPUs occasionally have numerous instructions that affect the
flags register(s) other than comparisons [AVR's setc, powerpc's mtcrf,
x86's clc, stc and cmc and x86_64's ptest that sets C and Z flags in
non-obvious ways, c.f. PR target/109973].  Currently care has to be taken,
wrapping these in UNSPEC, to avoid combine inappropriately merging flags
setters with flags consumers (such as conditional jumps).  It's safer to
teach simplify_const_relational_operation not to modify expressions that
it doesn't understand/recognize.

2023-05-30  Roger Sayle  

gcc/ChangeLog
PR target/107172
* simplify-rtx.cc (simplify_const_relational_operation): Return
early if we have a MODE_CC comparison that isn't a COMPARE against
const0_rtx.

[Bug target/107172] [13 Regression] wrong code with "-O1 -ftree-vrp" on x86_64-linux-gnu since r13-1268-g8c99e307b20c502e

2022-11-30 Thread hjl.tools at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107172

H.J. Lu  changed:

   What|Removed |Added

 Resolution|--- |FIXED
 Status|NEW |RESOLVED

--- Comment #50 from H.J. Lu  ---
Fixed.

[Bug target/107172] [13 Regression] wrong code with "-O1 -ftree-vrp" on x86_64-linux-gnu since r13-1268-g8c99e307b20c502e

2022-11-30 Thread jakub at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107172

Jakub Jelinek  changed:

   What|Removed |Added

 CC||jakub at gcc dot gnu.org

--- Comment #49 from Jakub Jelinek  ---
So is the wrong-code issue now fixed?
If yes, we should either close or at least drop the [13 Regression] part for it
if you want to keep it as a reminder that it would be nice to get rid of the
UNSPEC.

[Bug target/107172] [13 Regression] wrong code with "-O1 -ftree-vrp" on x86_64-linux-gnu since r13-1268-g8c99e307b20c502e

2022-10-28 Thread hjl.tools at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107172

--- Comment #48 from H.J. Lu  ---
(In reply to Roger Sayle from comment #47)
> I really don't believe that using UNSPEC here is the correct way to go, but
> it appears to be the (only?) approach that Segher is prepared to approve. 
> Hohum.

I wish we could avoid UNSPEC.

[Bug target/107172] [13 Regression] wrong code with "-O1 -ftree-vrp" on x86_64-linux-gnu since r13-1268-g8c99e307b20c502e

2022-10-28 Thread roger at nextmovesoftware dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107172

--- Comment #47 from Roger Sayle  ---
I really don't believe that using UNSPEC here is the correct way to go, but it
appears to be the (only?) approach that Segher is prepared to approve.  Hohum.

[Bug target/107172] [13 Regression] wrong code with "-O1 -ftree-vrp" on x86_64-linux-gnu since r13-1268-g8c99e307b20c502e

2022-10-27 Thread cvs-commit at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107172

--- Comment #46 from CVS Commits  ---
The master branch has been updated by H.J. Lu :

https://gcc.gnu.org/g:0e36a9c6915c713d30016cbade97a4b31dcc1350

commit r13-3530-g0e36a9c6915c713d30016cbade97a4b31dcc1350
Author: H.J. Lu 
Date:   Thu Oct 20 11:55:19 2022 -0700

x86: Replace ne:CCC/ne:CCO with UNSPEC_CC_NE in neg patterns

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.

[Bug target/107172] [13 Regression] wrong code with "-O1 -ftree-vrp" on x86_64-linux-gnu since r13-1268-g8c99e307b20c502e

2022-10-22 Thread segher at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107172

--- Comment #45 from Segher Boessenkool  ---
Yes, that is fine afaics.

[Bug target/107172] [13 Regression] wrong code with "-O1 -ftree-vrp" on x86_64-linux-gnu since r13-1268-g8c99e307b20c502e

2022-10-20 Thread hjl.tools at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107172

--- Comment #44 from H.J. Lu  ---
(In reply to Segher Boessenkool from comment #42)
> (In reply to H.J. Lu from comment #41)
> > (In reply to Segher Boessenkool from comment #40)
> > > Let me repeat: A const_int cannot be assigned to a MODE_CC.  It has no
> > > meaning.
> > > This is invalid RTL.  If it ever works, or worked, that is an accident.
> > 
> > Can we make it to work with a target hook? It will allow more backed
> > optimizations.
> 
> No, you cannot.  A lot of generic code will not work with your special
> re-interpretation of basic RTL rules.  Just write correct code in your
> backend, it is not hard.

Does it look correct:

(set (reg:CCC FLAGS_REG)
 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))

[Bug target/107172] [13 Regression] wrong code with "-O1 -ftree-vrp" on x86_64-linux-gnu since r13-1268-g8c99e307b20c502e

2022-10-20 Thread pinskia at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107172

Andrew Pinski  changed:

   What|Removed |Added

 CC||shaohua.li at inf dot ethz.ch

--- Comment #43 from Andrew Pinski  ---
*** Bug 107257 has been marked as a duplicate of this bug. ***

[Bug target/107172] [13 Regression] wrong code with "-O1 -ftree-vrp" on x86_64-linux-gnu since r13-1268-g8c99e307b20c502e

2022-10-18 Thread segher at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107172

--- Comment #42 from Segher Boessenkool  ---
(In reply to H.J. Lu from comment #41)
> (In reply to Segher Boessenkool from comment #40)
> > Let me repeat: A const_int cannot be assigned to a MODE_CC.  It has no
> > meaning.
> > This is invalid RTL.  If it ever works, or worked, that is an accident.
> 
> Can we make it to work with a target hook? It will allow more backed
> optimizations.

No, you cannot.  A lot of generic code will not work with your special
re-interpretation of basic RTL rules.  Just write correct code in your
backend, it is not hard.

[Bug target/107172] [13 Regression] wrong code with "-O1 -ftree-vrp" on x86_64-linux-gnu since r13-1268-g8c99e307b20c502e

2022-10-18 Thread hjl.tools at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107172

--- Comment #41 from H.J. Lu  ---
(In reply to Segher Boessenkool from comment #40)
> Let me repeat: A const_int cannot be assigned to a MODE_CC.  It has no
> meaning.
> This is invalid RTL.  If it ever works, or worked, that is an accident.

Can we make it to work with a target hook? It will allow more backed
optimizations.

[Bug target/107172] [13 Regression] wrong code with "-O1 -ftree-vrp" on x86_64-linux-gnu since r13-1268-g8c99e307b20c502e

2022-10-18 Thread segher at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107172

--- Comment #40 from Segher Boessenkool  ---
Let me repeat: A const_int cannot be assigned to a MODE_CC.  It has no meaning.
This is invalid RTL.  If it ever works, or worked, that is an accident.

A MODE_CC stands for a comparison (in the mathematical sense).  Saying it is
"1"
would mean what?

[Bug target/107172] [13 Regression] wrong code with "-O1 -ftree-vrp" on x86_64-linux-gnu since r13-1268-g8c99e307b20c502e

2022-10-17 Thread hjl.tools at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107172

--- Comment #39 from H.J. Lu  ---
(In reply to Segher Boessenkool from comment #38)
> You cannot put a const_int in a MODE_CC.  It is meaningless.

Reg 17 in

(insn 49 10 50 2 (parallel [
(set (reg:CCC 17 flags)
(ne:CCC (reg:SI 82 [ a.1_2 ])
(const_int 0 [0])))
(set (reg:SI 92)
(neg:SI (reg:SI 82 [ a.1_2 ])))
]) "107172.c":4:10 680 {*negsi_ccc_1}

becomes const_int 1 since a.1_2 is known non-zero.  Roger's patch simplifies
const_int in a MODE_CC properly.

[Bug target/107172] [13 Regression] wrong code with "-O1 -ftree-vrp" on x86_64-linux-gnu since r13-1268-g8c99e307b20c502e

2022-10-17 Thread segher at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107172

--- Comment #38 from Segher Boessenkool  ---
You cannot put a const_int in a MODE_CC.  It is meaningless.

[Bug target/107172] [13 Regression] wrong code with "-O1 -ftree-vrp" on x86_64-linux-gnu since r13-1268-g8c99e307b20c502e

2022-10-17 Thread hjl.tools at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107172

--- Comment #37 from H.J. Lu  ---
(In reply to Segher Boessenkool from comment #33)
> (In reply to H.J. Lu from comment #32)
> > > There is no actual comparison with 0, that is just notation.
> > 
> > True.  But simplify-rtx.cc simplifies
> > 
> > (ltu (reg 17) (const_int 0))
> > 
> > to false when reg 17 is set.
> 
> Is set?  What does that even mean?  Is set to what?

(reg 17) was set to 1.

> > Use the actual comparison isn't issue.  The issue is how
> > 
> > (ltu (reg 17) (const_int 0))
> > 
> > should be simplified when reg 17 is known to be set.
> 
> You need to look at the setter.  It cannot be simplified otherwise.

The backend knows how to evaluate

(ltu:SI (const_int 1 [0x1]) (const_int 0 [0]))

from

(ltu:SI (reg:CCC 17 flags) (const_int 0 [0]))

where (reg:CCC 17 flags) was set to a constant by backend.

[Bug target/107172] [13 Regression] wrong code with "-O1 -ftree-vrp" on x86_64-linux-gnu since r13-1268-g8c99e307b20c502e

2022-10-17 Thread rguenth at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107172

--- Comment #36 from Richard Biener  ---
*** Bug 107273 has been marked as a duplicate of this bug. ***

[Bug target/107172] [13 Regression] wrong code with "-O1 -ftree-vrp" on x86_64-linux-gnu since r13-1268-g8c99e307b20c502e

2022-10-17 Thread rguenth at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107172

--- Comment #35 from Richard Biener  ---
*** Bug 107269 has been marked as a duplicate of this bug. ***

[Bug target/107172] [13 Regression] wrong code with "-O1 -ftree-vrp" on x86_64-linux-gnu since r13-1268-g8c99e307b20c502e

2022-10-16 Thread crazylht at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107172

--- Comment #34 from Hongtao.liu  ---
There's 2 similar issues in PR107273 and PR107269.

[Bug target/107172] [13 Regression] wrong code with "-O1 -ftree-vrp" on x86_64-linux-gnu since r13-1268-g8c99e307b20c502e

2022-10-15 Thread segher at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107172

--- Comment #33 from Segher Boessenkool  ---
(In reply to H.J. Lu from comment #32)
> > There is no actual comparison with 0, that is just notation.
> 
> True.  But simplify-rtx.cc simplifies
> 
> (ltu (reg 17) (const_int 0))
> 
> to false when reg 17 is set.

Is set?  What does that even mean?  Is set to what?

> Use the actual comparison isn't issue.  The issue is how
> 
> (ltu (reg 17) (const_int 0))
> 
> should be simplified when reg 17 is known to be set.

You need to look at the setter.  It cannot be simplified otherwise.

[Bug target/107172] [13 Regression] wrong code with "-O1 -ftree-vrp" on x86_64-linux-gnu since r13-1268-g8c99e307b20c502e

2022-10-13 Thread hjl.tools at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107172

--- Comment #32 from H.J. Lu  ---
(In reply to Segher Boessenkool from comment #30)
> (In reply to H.J. Lu from comment #26)
> > LTU/GEU are only used to check FLAGS_REG against constant 0.
> 
> That is not what
>   (ltu (reg 17) (const_int 0))
> means though?
> 
> Together with a previous
>   (set (reg 17) (compare A B))
> 
> it means the result of A <= B.

That is correct.

> There is no actual comparison with 0, that is just notation.

True.  But simplify-rtx.cc simplifies

(ltu (reg 17) (const_int 0))

to false when reg 17 is set.

> > simplify_const_relational_operation has
> > 
> >  /* We can't simplify MODE_CC values since we don't know what the
> >  actual comparison is.  */
> >   if (GET_MODE_CLASS (GET_MODE (op0)) == MODE_CC)
> > return 0;
> 
> And combine *does* know how to find the actual comparison, in many cases. 
> Some
> other passes can as well, there is no magic involved, you just need to look
> at
> other insns as well (just one really, the CC setter).

Use the actual comparison isn't issue.  The issue is how

(ltu (reg 17) (const_int 0))

should be simplified when reg 17 is known to be set.

[Bug target/107172] [13 Regression] wrong code with "-O1 -ftree-vrp" on x86_64-linux-gnu since r13-1268-g8c99e307b20c502e

2022-10-13 Thread hjl.tools at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107172

--- Comment #31 from H.J. Lu  ---
(In reply to Segher Boessenkool from comment #29)
> (In reply to Hongtao.liu from comment #23)
> > looking at i386.c put_condition_code used by *setcc_qi, it looks like (EQ
> > (reg:CCCmode FLAG_REG) (const_int 0)) means get carry flag.
> > Not (LTU: (REG:CCCmode FLAGS_REG) (const_int 0)).
> > Now I got more confused.
> 
> (eq (reg:CCC 17) (const_int 0))  means that the comparison that did set reg
> 17
> returned "equal".
> 

Isn't the meaning of MODE_CC comparison only known to the backend? On x86, EQ
in

  (set (pc) (if_then_else
   (eq (reg:CCO FLAGS_REG) (const_int 0))
   (label_ref (match_operand 3))
   (pc)))]

doesn't evaluate to true when (reg:CCO FLAGS_REG) is 0.  It is true when
(reg:CCO FLAGS_REG) is set.

[Bug target/107172] [13 Regression] wrong code with "-O1 -ftree-vrp" on x86_64-linux-gnu since r13-1268-g8c99e307b20c502e

2022-10-13 Thread segher at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107172

--- Comment #30 from Segher Boessenkool  ---
(In reply to H.J. Lu from comment #26)
> LTU/GEU are only used to check FLAGS_REG against constant 0.

That is not what
  (ltu (reg 17) (const_int 0))
means though?

Together with a previous
  (set (reg 17) (compare A B))

it means the result of A <= B.

There is no actual comparison with 0, that is just notation.

> simplify_const_relational_operation has
> 
>  /* We can't simplify MODE_CC values since we don't know what the
>  actual comparison is.  */
>   if (GET_MODE_CLASS (GET_MODE (op0)) == MODE_CC)
> return 0;

And combine *does* know how to find the actual comparison, in many cases.  Some
other passes can as well, there is no magic involved, you just need to look at
other insns as well (just one really, the CC setter).

[Bug target/107172] [13 Regression] wrong code with "-O1 -ftree-vrp" on x86_64-linux-gnu since r13-1268-g8c99e307b20c502e

2022-10-13 Thread segher at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107172

--- Comment #29 from Segher Boessenkool  ---
(In reply to Hongtao.liu from comment #23)
> looking at i386.c put_condition_code used by *setcc_qi, it looks like (EQ
> (reg:CCCmode FLAG_REG) (const_int 0)) means get carry flag.
> Not (LTU: (REG:CCCmode FLAGS_REG) (const_int 0)).
> Now I got more confused.

(eq (reg:CCC 17) (const_int 0))  means that the comparison that did set reg 17
returned "equal".

CCCmode is just like CCmode, but *only* the carry flag is valid.

[Bug target/107172] [13 Regression] wrong code with "-O1 -ftree-vrp" on x86_64-linux-gnu since r13-1268-g8c99e307b20c502e

2022-10-13 Thread segher at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107172

--- Comment #28 from Segher Boessenkool  ---
> So the issue is with the consumer:
> 
> (insn 50 49 51 2 (parallel [
> (set (reg:SI 93)
> (neg:SI (ltu:SI (reg:CCC 17 flags)
> (const_int 0 [0]
> (clobber (reg:CC 17 flags))
> ]) "107172.c":4:10 1258 {*x86_movsicc_0_m1_neg}
>  (expr_list:REG_DEAD (reg:CCC 17 flags)
> (expr_list:REG_UNUSED (reg:CC 17 flags)
> (nil
> 
> There are many similar patterns in different backends.  They work as long as
> the flags register isn't a known constant since simplify-rtx.cc leaves them
> alone.  They become a problem only when the flags register is a known
> constant.

Such patterns are fine.  The problem is that this consumer of MODE_CC does not
fit together with the producer of that reg 17: it only has meaning together,
that
is how this stuff works; and it has no meaning at all like this.

[Bug target/107172] [13 Regression] wrong code with "-O1 -ftree-vrp" on x86_64-linux-gnu since r13-1268-g8c99e307b20c502e

2022-10-13 Thread hjl.tools at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107172

--- Comment #27 from H.J. Lu  ---
Another oddity is

  (set (pc) (if_then_else
   (eq (reg:CCO FLAGS_REG) (const_int 0))
   (label_ref (match_operand 3))
   (pc)))]

CCOmode means that the overflow flag is tested.  EQ means that the flag is set
and NE
means unset.

[Bug target/107172] [13 Regression] wrong code with "-O1 -ftree-vrp" on x86_64-linux-gnu since r13-1268-g8c99e307b20c502e

2022-10-13 Thread hjl.tools at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107172

--- Comment #26 from H.J. Lu  ---
(In reply to Uroš Bizjak from comment #24)
> (In reply to Hongtao.liu from comment #23)
> > looking at i386.c put_condition_code used by *setcc_qi, it looks like (EQ
> > (reg:CCCmode FLAG_REG) (const_int 0)) means get carry flag.
> > Not (LTU: (REG:CCCmode FLAGS_REG) (const_int 0)).
> > Now I got more confused.
> 
> CCCmode means that single flag is tested, it uses EQ and NE, so "c" and "nc"
> suffix is emitted. When CCmode is used, LTU/GEU operation on CCmode flags
> reg produces "b" and "nb" suffix, which decodes to exactly the same assembly
> as "c" and "nc" suffixes.
> 
> However, it looks that somewhere LTU/GEU is also generated with CCCmode
> flags reg, and some fixup was introduced to put_condition_code to "fix" this
> inconsistency. If LTU/GEU is valid only for CCmode, then the producers of
> invalid RTX should be fixed.

EQ and NE are only used to set FLAGS_REG in CCCmode from 2 integer operands.
LTU/GEU are only used to check FLAGS_REG against constant 0.  This is very
consistent.  simplify_const_relational_operation has

 /* We can't simplify MODE_CC values since we don't know what the
 actual comparison is.  */
  if (GET_MODE_CLASS (GET_MODE (op0)) == MODE_CC)
return 0;

In case of the comparison in CCCmode with constant op0 and op1, it should
let the backend perform the actual comparison.

[Bug target/107172] [13 Regression] wrong code with "-O1 -ftree-vrp" on x86_64-linux-gnu since r13-1268-g8c99e307b20c502e

2022-10-13 Thread crazylht at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107172

--- Comment #25 from Hongtao.liu  ---
(In reply to Uroš Bizjak from comment #24)
> (In reply to Hongtao.liu from comment #23)
> > looking at i386.c put_condition_code used by *setcc_qi, it looks like (EQ
> > (reg:CCCmode FLAG_REG) (const_int 0)) means get carry flag.
> > Not (LTU: (REG:CCCmode FLAGS_REG) (const_int 0)).
> > Now I got more confused.
> 
> CCCmode means that single flag is tested, it uses EQ and NE, so "c" and "nc"
> suffix is emitted. When CCmode is used, LTU/GEU operation on CCmode flags
> reg produces "b" and "nb" suffix, which decodes to exactly the same assembly
> as "c" and "nc" suffixes.
> 
> However, it looks that somewhere LTU/GEU is also generated with CCCmode
> flags reg, and some fixup was introduced to put_condition_code to "fix" this
> inconsistency. If LTU/GEU is valid only for CCmode, then the producers of
> invalid RTX should be fixed.

grep -e ltu -e geu *.md, it looks like most places use CCmode for LTU, only
below cases use CCCmode, maybe we should use CCmode for all of those and "fix"
put_condition_code?

cut CCCmode---
i386.md:   (ltu (reg:CCC FLAGS_REG) (const_int 0))
i386.md:(compare:CCC (neg:QI (geu:QI (reg:CC_CCC FLAGS_REG) (const_int
0)))
i386.md: (ltu:QI (reg:CC_CCC FLAGS_REG) (const_int 0]
i386.md:  (neg:SWI48 (ltu:SWI48 (reg:CCC FLAGS_REG) (const_int 0
i386.md:(neg:SWI (ltu:SWI (reg:CCC FLAGS_REG) (const_int 0])

cut ends---

cut CCmode---
i386.md:   (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
i386.md:   (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
i386.md: (ltu: (reg:CC FLAGS_REG) (const_int 0))
i386.md:   (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
i386.md:   (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
i386.md: (ltu: (reg:CC FLAGS_REG) (const_int 0))
i386.md:   (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
i386.md:   (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
i386.md:   (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
i386.md:   (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
i386.md: (ltu: (reg:CC FLAGS_REG) (const_int 0)))
i386.md:   (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
i386.md:   (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
i386.md: (ltu: (reg:CC FLAGS_REG) (const_int 0)))
i386.md:   (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
i386.md:   (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
i386.md:   (ltu (reg:CC FLAGS_REG) (const_int 0))
i386.md:(ltu: (reg:CC FLAGS_REG) (const_int 0))
i386.md:(ltu: (reg:CC FLAGS_REG) (const_int 0))
i386.md:  (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))]
i386.md:   (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
i386.md:   (ltu: (reg:CC FLAGS_REG) (const_int 0)
i386.md: (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int
0))
i386.md: (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int
0))
i386.md:(ltu:SWI (reg:CC FLAGS_REG) (const_int
0)))
i386.md:   (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
i386.md:(ltu:SWI (reg:CC FLAGS_REG) (const_int
0)))
i386.md:(ltu:SWI (reg:CC FLAGS_REG) (const_int
0)))
i386.md: (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int
0))
i386.md:(ltu:SWI (reg:CC FLAGS_REG) (const_int
0)))
i386.md:  (ltu:SWI (reg:CC FLAGS_REG) (const_int
0
i386.md:   (ltu:SWI (reg:CC FLAGS_REG) (const_int
0))
i386.md:  (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int
0))
i386.md:(ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))
i386.md: (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0)))
i386.md:(ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))
i386.md:  (if_then_else:SWI48 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int
0))
i386.md:  (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int
0))
i386.md:  (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int
0))
i386.md:(ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
i386.md:(ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
i386.md:(ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
i386.md:(neg:SWI48 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0]
i386.md:(neg:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0])

cut 

[Bug target/107172] [13 Regression] wrong code with "-O1 -ftree-vrp" on x86_64-linux-gnu since r13-1268-g8c99e307b20c502e

2022-10-13 Thread ubizjak at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107172

--- Comment #24 from Uroš Bizjak  ---
(In reply to Hongtao.liu from comment #23)
> looking at i386.c put_condition_code used by *setcc_qi, it looks like (EQ
> (reg:CCCmode FLAG_REG) (const_int 0)) means get carry flag.
> Not (LTU: (REG:CCCmode FLAGS_REG) (const_int 0)).
> Now I got more confused.

CCCmode means that single flag is tested, it uses EQ and NE, so "c" and "nc"
suffix is emitted. When CCmode is used, LTU/GEU operation on CCmode flags reg
produces "b" and "nb" suffix, which decodes to exactly the same assembly as "c"
and "nc" suffixes.

However, it looks that somewhere LTU/GEU is also generated with CCCmode flags
reg, and some fixup was introduced to put_condition_code to "fix" this
inconsistency. If LTU/GEU is valid only for CCmode, then the producers of
invalid RTX should be fixed.

[Bug target/107172] [13 Regression] wrong code with "-O1 -ftree-vrp" on x86_64-linux-gnu since r13-1268-g8c99e307b20c502e

2022-10-12 Thread crazylht at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107172

--- Comment #23 from Hongtao.liu  ---
looking at i386.c put_condition_code used by *setcc_qi, it looks like (EQ
(reg:CCCmode FLAG_REG) (const_int 0)) means get carry flag.
Not (LTU: (REG:CCCmode FLAGS_REG) (const_int 0)).
Now I got more confused.

[Bug target/107172] [13 Regression] wrong code with "-O1 -ftree-vrp" on x86_64-linux-gnu since r13-1268-g8c99e307b20c502e

2022-10-12 Thread hjl.tools at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107172

--- Comment #22 from H.J. Lu  ---
(In reply to Segher Boessenkool from comment #21)
> (In reply to Hongtao.liu from comment #19)
> > (In reply to H.J. Lu from comment #18)
> > > (In reply to Segher Boessenkool from comment #16)
> > > > Hi Roger,
> > > > 
> > > > (In reply to Roger Sayle from comment #15)
> > > > > Yes, a COMPARE rtx can be used to set various flags on x86, but many 
> > > > > other
> > > > > operations also legitimately set and/or use MODE_CC, often in a 
> > > > > parallel
> > > > > with the primary operation.
> > > > 
> > > > *Any* MODE_CC setter sets the flags as-if from a compare.  This is what
> > > > MODE_CC *is*.
> > > > 
> > > > Setting something as ne:CC and then using it as somethingelse:CC has no
> > > > defined meaning.
> > > 
> > > This
> > > 
> > > (parallel [
> > > (set (reg:SI 97) 
> > > (neg:SI (ltu:SI (reg:CCC 17 flags)
> > > (const_int 0 [0]
> > > (clobber (reg:CC 17 flags))
> > > ])
> > > 
> > > still won't work correctly if reg:CCC 17 flags is set by a compare of
> > > 2 known values.
> > 
> > I guess Segher means it should be NE instead of LTU in the
> > x86_movcc_0_m1_neg, since the setters is NE to const 0.
> 
> Yes.

So the issue is with the consumer:

(insn 50 49 51 2 (parallel [
(set (reg:SI 93)
(neg:SI (ltu:SI (reg:CCC 17 flags)
(const_int 0 [0]
(clobber (reg:CC 17 flags))
]) "107172.c":4:10 1258 {*x86_movsicc_0_m1_neg}
 (expr_list:REG_DEAD (reg:CCC 17 flags)
(expr_list:REG_UNUSED (reg:CC 17 flags)
(nil

There are many similar patterns in different backends.  They work as long as
the flags register isn't a known constant since simplify-rtx.cc leaves them
alone.  They become a problem only when the flags register is a known constant.

[Bug target/107172] [13 Regression] wrong code with "-O1 -ftree-vrp" on x86_64-linux-gnu since r13-1268-g8c99e307b20c502e

2022-10-12 Thread segher at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107172

--- Comment #21 from Segher Boessenkool  ---
(In reply to Hongtao.liu from comment #19)
> (In reply to H.J. Lu from comment #18)
> > (In reply to Segher Boessenkool from comment #16)
> > > Hi Roger,
> > > 
> > > (In reply to Roger Sayle from comment #15)
> > > > Yes, a COMPARE rtx can be used to set various flags on x86, but many 
> > > > other
> > > > operations also legitimately set and/or use MODE_CC, often in a parallel
> > > > with the primary operation.
> > > 
> > > *Any* MODE_CC setter sets the flags as-if from a compare.  This is what
> > > MODE_CC *is*.
> > > 
> > > Setting something as ne:CC and then using it as somethingelse:CC has no
> > > defined meaning.
> > 
> > This
> > 
> > (parallel [
> > (set (reg:SI 97) 
> > (neg:SI (ltu:SI (reg:CCC 17 flags)
> > (const_int 0 [0]
> > (clobber (reg:CC 17 flags))
> > ])
> > 
> > still won't work correctly if reg:CCC 17 flags is set by a compare of
> > 2 known values.
> 
> I guess Segher means it should be NE instead of LTU in the
> x86_movcc_0_m1_neg, since the setters is NE to const 0.

Yes.

>  (ne:CCC (reg:SI 87 [ a_lsm.8 ])
> (const_int 0 [0])))
> 
>  (define_expand "x86_movcc_0_m1_neg"
>[(parallel
>  [(set (match_operand:SWI48 0 "register_operand")
> - (neg:SWI48 (ltu:SWI48 (reg:CCC FLAGS_REG) (const_int 0
> + (neg:SWI48 (ne:SWI48 (reg:CCC FLAGS_REG) (const_int 0
>   (clobber (reg:CC FLAGS_REG))])])
> 
> It can pass the PR, but failed pr101617.c, the f1 case.
> 
> generate:
> testl   %edi, %edi
> movl$1, %edx
> movl$-1, %eax
> cmove   %edx, %eax
> 
> origin:
> negl%edi
> sbbl%eax, %eax
> orl $1, %eax

And this is why using a relation (e.g. ltu, an RTX_COMPARE) instead of a
compare (an RTX_BIN_ARITH) as setter cannot work.  The setter and the getter
are modified independently by very many parts of the compiler, and then
everything falls apart.

The only valid things on the RHS of a MODE_CC set are a reg, a compare, or
an unspec.  Everything else is undefined and problematical as well.

[Bug target/107172] [13 Regression] wrong code with "-O1 -ftree-vrp" on x86_64-linux-gnu since r13-1268-g8c99e307b20c502e

2022-10-12 Thread crazylht at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107172

--- Comment #20 from Hongtao.liu  ---
> generate:
> testl   %edi, %edi
> movl$1, %edx
> movl$-1, %eax
> cmove   %edx, %eax
> 
> origin:
> negl%edi
> sbbl%eax, %eax
> orl $1, %eax

It now go through *if-conversion succeeded through noce_try_cmove_arith*
instead of original *if-conversion succeeded through noce_try_cmove*.

[Bug target/107172] [13 Regression] wrong code with "-O1 -ftree-vrp" on x86_64-linux-gnu since r13-1268-g8c99e307b20c502e

2022-10-12 Thread crazylht at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107172

--- Comment #19 from Hongtao.liu  ---
(In reply to H.J. Lu from comment #18)
> (In reply to Segher Boessenkool from comment #16)
> > Hi Roger,
> > 
> > (In reply to Roger Sayle from comment #15)
> > > Yes, a COMPARE rtx can be used to set various flags on x86, but many other
> > > operations also legitimately set and/or use MODE_CC, often in a parallel
> > > with the primary operation.
> > 
> > *Any* MODE_CC setter sets the flags as-if from a compare.  This is what
> > MODE_CC *is*.
> > 
> > Setting something as ne:CC and then using it as somethingelse:CC has no
> > defined meaning.
> 
> This
> 
> (parallel [
> (set (reg:SI 97) 
> (neg:SI (ltu:SI (reg:CCC 17 flags)
> (const_int 0 [0]
> (clobber (reg:CC 17 flags))
> ])
> 
> still won't work correctly if reg:CCC 17 flags is set by a compare of
> 2 known values.

I guess Segher means it should be NE instead of LTU in the
x86_movcc_0_m1_neg, since the setters is NE to const 0.

 (ne:CCC (reg:SI 87 [ a_lsm.8 ])
(const_int 0 [0])))

 (define_expand "x86_movcc_0_m1_neg"
   [(parallel
 [(set (match_operand:SWI48 0 "register_operand")
- (neg:SWI48 (ltu:SWI48 (reg:CCC FLAGS_REG) (const_int 0
+ (neg:SWI48 (ne:SWI48 (reg:CCC FLAGS_REG) (const_int 0
  (clobber (reg:CC FLAGS_REG))])])

It can pass the PR, but failed pr101617.c, the f1 case.

generate:
testl   %edi, %edi
movl$1, %edx
movl$-1, %eax
cmove   %edx, %eax

origin:
negl%edi
sbbl%eax, %eax
orl $1, %eax

[Bug target/107172] [13 Regression] wrong code with "-O1 -ftree-vrp" on x86_64-linux-gnu since r13-1268-g8c99e307b20c502e

2022-10-11 Thread hjl.tools at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107172

--- Comment #18 from H.J. Lu  ---
(In reply to Segher Boessenkool from comment #16)
> Hi Roger,
> 
> (In reply to Roger Sayle from comment #15)
> > Yes, a COMPARE rtx can be used to set various flags on x86, but many other
> > operations also legitimately set and/or use MODE_CC, often in a parallel
> > with the primary operation.
> 
> *Any* MODE_CC setter sets the flags as-if from a compare.  This is what
> MODE_CC *is*.
> 
> Setting something as ne:CC and then using it as somethingelse:CC has no
> defined meaning.

This

(parallel [
(set (reg:SI 97) 
(neg:SI (ltu:SI (reg:CCC 17 flags)
(const_int 0 [0]
(clobber (reg:CC 17 flags))
])

still won't work correctly if reg:CCC 17 flags is set by a compare of
2 known values.

[Bug target/107172] [13 Regression] wrong code with "-O1 -ftree-vrp" on x86_64-linux-gnu since r13-1268-g8c99e307b20c502e

2022-10-11 Thread hjl.tools at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107172

--- Comment #17 from H.J. Lu  ---
(In reply to Segher Boessenkool from comment #14)
> (In reply to H.J. Lu from comment #13)
> > (In reply to Segher Boessenkool from comment #12)
> > > 
> > > To determine the semantics of this piece of RTL you need to see the 
> > > setter(s)
> > > of reg 17 feeding this use.  In this case, the setter was
> > >   (set (reg:CCC 17)
> > >(ne:CCC (reg:SI 82)
> > >(const_int 0 [0])))
> > > which has no meaning for a use that uses "ltu".
> > 
> > What should a valid setter look like?  It should set reg 17 in CCC mode if
> > reg 82 in SI mode isn't 0.
> 
> CCCmode can only represent the result of a comparison, like any other MODE_CC
> thing.  The i386 CCCmode means only the carry bit can be used for this, so
> you
> beed to do an unsigned comparison against (const_int 1).  This will end up
> with
> the opposite polarity of what you said I guess, you need "geu" instead?

Since it checks if the input register is 0, compare against (const_int 1)
won't work here.

[Bug target/107172] [13 Regression] wrong code with "-O1 -ftree-vrp" on x86_64-linux-gnu since r13-1268-g8c99e307b20c502e

2022-10-11 Thread segher at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107172

--- Comment #16 from Segher Boessenkool  ---
Hi Roger,

(In reply to Roger Sayle from comment #15)
> Yes, a COMPARE rtx can be used to set various flags on x86, but many other
> operations also legitimately set and/or use MODE_CC, often in a parallel
> with the primary operation.

*Any* MODE_CC setter sets the flags as-if from a compare.  This is what
MODE_CC *is*.

Setting something as ne:CC and then using it as somethingelse:CC has no
defined meaning.

[Bug target/107172] [13 Regression] wrong code with "-O1 -ftree-vrp" on x86_64-linux-gnu since r13-1268-g8c99e307b20c502e

2022-10-11 Thread roger at nextmovesoftware dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107172

Roger Sayle  changed:

   What|Removed |Added

 CC||roger at nextmovesoftware dot 
com

--- Comment #15 from Roger Sayle  ---
Hi HJ (and Segher),
The i386's *negsi_ccc_1 pattern fully models the flags setting behaviour of the
x86's neg instruction.  neg %eax, in addition to setting %eax to -%eax, will
clear the carry flag if %eax is zero, and set it for all other values of %eax. 
Hence, this pattern is a useful mechanism for setting the carry flag to a known
value from a scalar integer register.  For example, it's used in the expansion
of __builtin_add_with_carry (sp?).

The *x86_movsicc_0_m1_neg instruction does the reverse.  The sbc %eax,%eax
instruction (subtract with carry) will place the value 0 in %eax if the carry
flag is clear, and the value -1 in %eax if the carry flag is set (independent
of whatever value was in %eax before the instruction).

Understanding these patterns is perhaps a little easier with a little more
context.  For example,
https://gcc.gnu.org/pipermail/gcc-patches/2022-July/598058.html describes
efforts to add support for x86's stc (set carry flag) and clc (clear carry
flag) instructions.  I've a similar patch for "cmc" (complement carry flag) but
all of these are blocked by the simplify-rtx issue
underlying PR 107172, that MODE_CC requires special care and/or backend
specific support to interpret.

Yes, a COMPARE rtx can be used to set various flags on x86, but many other
operations also legitimately set and/or use MODE_CC, often in a parallel with
the primary operation.

[Bug target/107172] [13 Regression] wrong code with "-O1 -ftree-vrp" on x86_64-linux-gnu since r13-1268-g8c99e307b20c502e

2022-10-11 Thread segher at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107172

--- Comment #14 from Segher Boessenkool  ---
(In reply to H.J. Lu from comment #13)
> (In reply to Segher Boessenkool from comment #12)
> > 
> > To determine the semantics of this piece of RTL you need to see the 
> > setter(s)
> > of reg 17 feeding this use.  In this case, the setter was
> >   (set (reg:CCC 17)
> >(ne:CCC (reg:SI 82)
> >(const_int 0 [0])))
> > which has no meaning for a use that uses "ltu".
> 
> What should a valid setter look like?  It should set reg 17 in CCC mode if
> reg 82 in SI mode isn't 0.

CCCmode can only represent the result of a comparison, like any other MODE_CC
thing.  The i386 CCCmode means only the carry bit can be used for this, so you
beed to do an unsigned comparison against (const_int 1).  This will end up with
the opposite polarity of what you said I guess, you need "geu" instead?

[Bug target/107172] [13 Regression] wrong code with "-O1 -ftree-vrp" on x86_64-linux-gnu since r13-1268-g8c99e307b20c502e

2022-10-11 Thread hjl.tools at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107172

--- Comment #13 from H.J. Lu  ---
(In reply to Segher Boessenkool from comment #12)
> 
> To determine the semantics of this piece of RTL you need to see the setter(s)
> of reg 17 feeding this use.  In this case, the setter was
>   (set (reg:CCC 17)
>(ne:CCC (reg:SI 82)
>(const_int 0 [0])))
> which has no meaning for a use that uses "ltu".

What should a valid setter look like?  It should set reg 17 in CCC mode if
reg 82 in SI mode isn't 0.

[Bug target/107172] [13 Regression] wrong code with "-O1 -ftree-vrp" on x86_64-linux-gnu since r13-1268-g8c99e307b20c502e

2022-10-11 Thread segher at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107172

--- Comment #12 from Segher Boessenkool  ---
(In reply to H.J. Lu from comment #11)
> Assuming (reg:CCC 17 flags) is set to 1 by compare properly, how should

A MODE_CC RTL reg is never set to "1".  It is set to the result of a
comparison,
instead.  The semantics of a consumer of a MODE_CC depends on the producer.

> (insn 50 49 51 2 (parallel [
> (set (reg:SI 93)
> (neg:SI (ltu:SI (reg:CCC 17 flags)
> (const_int 0 [0]
> (clobber (reg:CC 17 flags))
> ]) "107172.c":4:10 1258 {*x86_movsicc_0_m1_neg}
>  (expr_list:REG_DEAD (reg:CCC 17 flags)
> (expr_list:REG_UNUSED (reg:CC 17 flags)
> (nil
> 
> work?

The semantics of
  (ltu:SI (reg:CCC 17) (const_int 0))
is: the result of "ltu" of the producer of this reg 17, taken from 17 as mode
CCC (which means only the carry output is valid), and that result as a SImode
(which then depends on what STORE_FLAG_VALUE is for your target -- 1 or -1 for
most targets, but other values are more complicated).

It never means "1".  It never means "0".  Never.

To determine the semantics of this piece of RTL you need to see the setter(s)
of reg 17 feeding this use.  In this case, the setter was
  (set (reg:CCC 17)
   (ne:CCC (reg:SI 82)
   (const_int 0 [0])))
which has no meaning for a use that uses "ltu".

[Bug target/107172] [13 Regression] wrong code with "-O1 -ftree-vrp" on x86_64-linux-gnu since r13-1268-g8c99e307b20c502e

2022-10-10 Thread hjl.tools at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107172

--- Comment #11 from H.J. Lu  ---
Assuming (reg:CCC 17 flags) is set to 1 by compare properly, how should

(insn 50 49 51 2 (parallel [
(set (reg:SI 93)
(neg:SI (ltu:SI (reg:CCC 17 flags)
(const_int 0 [0]
(clobber (reg:CC 17 flags))
]) "107172.c":4:10 1258 {*x86_movsicc_0_m1_neg}
 (expr_list:REG_DEAD (reg:CCC 17 flags)
(expr_list:REG_UNUSED (reg:CC 17 flags)
(nil

work?

[Bug target/107172] [13 Regression] wrong code with "-O1 -ftree-vrp" on x86_64-linux-gnu since r13-1268-g8c99e307b20c502e

2022-10-10 Thread segher at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107172

--- Comment #10 from Segher Boessenkool  ---
The input to combine has

(insn 49 10 50 2 (parallel [
(set (reg:CCC 17 flags)
(ne:CCC (reg:SI 82 [ a.1_2 ])
(const_int 0 [0])))
(set (reg:SI 92)
(neg:SI (reg:SI 82 [ a.1_2 ])))
]) "107172.c":4:10 680 {*negsi_ccc_1}
 (expr_list:REG_DEAD (reg:SI 82 [ a.1_2 ])
(expr_list:REG_UNUSED (reg:SI 92)
(nil
(insn 50 49 51 2 (parallel [
(set (reg:SI 93)
(neg:SI (ltu:SI (reg:CCC 17 flags)
(const_int 0 [0]
(clobber (reg:CC 17 flags))
]) "107172.c":4:10 1258 {*x86_movsicc_0_m1_neg}
 (expr_list:REG_DEAD (reg:CCC 17 flags)
(expr_list:REG_UNUSED (reg:CC 17 flags)
(nil

This is incorrect already: insn 49 has to do a cmp, not a ne, for it to be
valid.  It was created by the ce1 pass.

[Bug target/107172] [13 Regression] wrong code with "-O1 -ftree-vrp" on x86_64-linux-gnu since r13-1268-g8c99e307b20c502e

2022-10-10 Thread hjl.tools at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107172

--- Comment #9 from H.J. Lu  ---
(In reply to Segher Boessenkool from comment #7)
> Please show the (relevant part of) output of -fdump-rtl-combine-all ?  At
> least
> those parts where it decided (ltu:SI (const_int 1) (const_int 0)) is valid
> (it
> isn't) and where optimising that to (const_int 0) is valid (it isn't).

Trying 6, 62 -> 63:
6: r87:SI=0x2
   62: {flags:CCC=r87:SI!=0;r96:SI=-r87:SI;}
  REG_DEAD r87:SI
  REG_UNUSED r96:SI
   63: {r97:SI=-ltu(flags:CCC,0);clobber flags:CC;}
  REG_DEAD flags:CCC
  REG_UNUSED flags:CC
Failed to match this instruction:
(parallel [
(set (reg:SI 97)
(const_int 0 [0]))
(clobber (reg:CC 17 flags))
(set (reg:SI 96)
(const_int -2 [0xfffe]))
])
Failed to match this instruction:
(parallel [
(set (reg:SI 97)
(const_int 0 [0]))
(set (reg:SI 96)
(const_int -2 [0xfffe]))
])
Successfully matched this instruction:
(set (reg:SI 96)
(const_int -2 [0xfffe]))
Successfully matched this instruction:
(set (reg:SI 97)
(const_int 0 [0]))
allowing combination of insns 6, 62 and 63
original costs 4 + 0 + 8 = 0
replacement costs 4 + 4 = 8
deferring deletion of insn with uid = 62.
deferring deletion of insn with uid = 6.
modifying insn i262: r96:SI=0xfffe
deferring rescan insn with uid = 62.
modifying insn i363: r97:SI=0
deferring rescan insn with uid = 63.

[Bug target/107172] [13 Regression] wrong code with "-O1 -ftree-vrp" on x86_64-linux-gnu since r13-1268-g8c99e307b20c502e

2022-10-10 Thread segher at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107172

--- Comment #8 from Segher Boessenkool  ---
Bah, scratch that last part, of course it is valid (I thought this was using 0
in a MODE_CC but I just cannot read).

[Bug target/107172] [13 Regression] wrong code with "-O1 -ftree-vrp" on x86_64-linux-gnu since r13-1268-g8c99e307b20c502e

2022-10-10 Thread segher at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107172

Segher Boessenkool  changed:

   What|Removed |Added

 CC||segher at gcc dot gnu.org

--- Comment #7 from Segher Boessenkool  ---
Please show the (relevant part of) output of -fdump-rtl-combine-all ?  At least
those parts where it decided (ltu:SI (const_int 1) (const_int 0)) is valid (it
isn't) and where optimising that to (const_int 0) is valid (it isn't).

[Bug target/107172] [13 Regression] wrong code with "-O1 -ftree-vrp" on x86_64-linux-gnu since r13-1268-g8c99e307b20c502e

2022-10-09 Thread roger at nextmovesoftware dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107172

--- Comment #6 from Roger Sayle  ---
This sounds related to the discussion/patch originally proposed at
https://gcc.gnu.org/pipermail/gcc-patches/2022-July/598040.html
and then revised (based on reviewer comments) at
https://gcc.gnu.org/pipermail/gcc-patches/2022-July/598835.html

[Bug target/107172] [13 Regression] wrong code with "-O1 -ftree-vrp" on x86_64-linux-gnu since r13-1268-g8c99e307b20c502e

2022-10-07 Thread hjl.tools at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107172

--- Comment #5 from H.J. Lu  ---
i386 needs to change

(ltu:SI (const_int 1 [1])
(const_int 0 [0]))

to

(ne:SI (const_int 1 [1])
(const_int 0 [0]))

when checking the carry flag.  But the mode info isn't passed to
TARGET_CANONICALIZE_COMPARISON.

[Bug target/107172] [13 Regression] wrong code with "-O1 -ftree-vrp" on x86_64-linux-gnu since r13-1268-g8c99e307b20c502e

2022-10-07 Thread hjl.tools at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107172

H.J. Lu  changed:

   What|Removed |Added

 CC||hjl.tools at gmail dot com,
   ||ubizjak at gmail dot com

--- Comment #4 from H.J. Lu  ---
There are:

(insn 6 5 17 2 (set (reg:SI 87 [ a_lsm.8 ])
(const_int 2 [0x2])) "x.c":7:7 83 {*movsi_internal}
 (nil))
...
(insn 62 59 63 2 (parallel [
(set (reg:CCC 17 flags)
(ne:CCC (reg:SI 87 [ a_lsm.8 ])
(const_int 0 [0])))
(set (reg:SI 96) 
(neg:SI (reg:SI 87 [ a_lsm.8 ])))
]) "x.c":4:7 680 {*negsi_ccc_1}
 (expr_list:REG_DEAD (reg:SI 87 [ a_lsm.8 ])
(expr_list:REG_UNUSED (reg:SI 96) 
(nil
(insn 63 62 64 2 (parallel [
(set (reg:SI 97) 
(neg:SI (ltu:SI (reg:CCC 17 flags)
(const_int 0 [0]
(clobber (reg:CC 17 flags))
]) "x.c":4:7 1258 {*x86_movsicc_0_m1_neg}
 (expr_list:REG_DEAD (reg:CCC 17 flags)
(expr_list:REG_UNUSED (reg:CC 17 flags)
(nil

Since r87 == 2, combine knows (reg:CCC 17 flags) == 1 and optimizes

(ltu:SI (reg:CCC 17 flags)
(const_int 0 [0]))

as

(ltu:SI (const_int 1 [1])
(const_int 0 [0]))

to 0.