[Bug tree-optimization/81814] Incorrect behaviour at -O0 (conditional operator)

2017-08-11 Thread mpolacek at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81814

Marek Polacek  changed:

   What|Removed |Added

 CC||mpolacek at gcc dot gnu.org

--- Comment #1 from Marek Polacek  ---
 That really looks like a bug.  Even gcc34 prints 0!

[Bug tree-optimization/81814] Incorrect behaviour at -O0 (conditional operator)

2017-08-11 Thread mpolacek at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81814

--- Comment #2 from Marek Polacek  ---
Probably started with r125012.

[Bug tree-optimization/81814] Incorrect behaviour at -O0 (conditional operator)

2017-08-11 Thread mpolacek at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81814

--- Comment #3 from Marek Polacek  ---
Ugh, I believe fold_cond_expr_with_comparison does Very Bad stuff: it sees
A == 0 ? A : 0 and thinks that it can be optimized to 0, btu it can't, in this
case we have
(signed char) xxx == 0 ? (unsigned long long) xxx : 0
(signed char) xxx is indeed 0 but (unsigned long long) xxx is not.

[Bug tree-optimization/81814] Incorrect behaviour at -O0 (conditional operator)

2017-08-11 Thread d25fe0be at outlook dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81814

--- Comment #4 from d25fe0be@  ---
Per n4659 7.8/[conv.integral]:

```
If the destination type is signed, the value is unchanged if it can be
represented in the destination type;
otherwise, the value is implementation-defined.
```

Isn't `(char)xxx` implementation-defined? (as GCC treats `char` as signed)

And as the following code prints 0, I believe that GCC defines the result of
such casting as 0:

```
#include 
int xxx = 0x0100;
int main() {
printf("%d\n", (char)xxx);
return 0;
}
```

So I think the output should indeed be 0.

[Bug tree-optimization/81814] Incorrect behaviour at -O0 (conditional operator)

2017-08-11 Thread d25fe0be at outlook dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81814

--- Comment #5 from d25fe0be@  ---
Oops, sorry, I read the 2nd and the 3rd operand of the conditional operator in
wrong order.

A silly mistake..

[Bug tree-optimization/81814] Incorrect behaviour at -O0 (conditional operator)

2017-08-15 Thread rguenth at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81814

Richard Biener  changed:

   What|Removed |Added

   Keywords||wrong-code
 Status|UNCONFIRMED |NEW
   Last reconfirmed||2017-08-15
 CC||rguenth at gcc dot gnu.org
 Ever confirmed|0   |1

--- Comment #6 from Richard Biener  ---
The folding obviously preserves precision changing casts, so it should be
valid.  Things must go wrong elsewhere, possibly in
operand_equal_for_comparison_p which ends up using get_narrower.

[Bug tree-optimization/81814] Incorrect behaviour at -O0 (conditional operator)

2017-08-15 Thread mpolacek at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81814

--- Comment #7 from Marek Polacek  ---
Yes, it's in operand_equal_for_comparison_p, and that would also explain why it
started with r125012.  I didn't update the BZ when I found this out.  I hope to
look into this more this week.

[Bug tree-optimization/81814] Incorrect behaviour at -O0 (conditional operator)

2017-08-16 Thread mpolacek at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81814

--- Comment #8 from Marek Polacek  ---
I wonder if I could just

--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -3401,14 +3401,14 @@ operand_equal_for_comparison_p (tree arg0, tree arg1,
tree other)

   primarg1 = get_narrower (arg1, &unsignedp1);
   primother = get_narrower (other, &unsignedpo);
+  tree type = TREE_TYPE (arg0);

   correct_width = TYPE_PRECISION (TREE_TYPE (arg1));
   if (unsignedp1 == unsignedpo
+  && TYPE_PRECISION (TREE_TYPE (primarg1)) == TYPE_PRECISION (type)
   && TYPE_PRECISION (TREE_TYPE (primarg1)) < correct_width
   && TYPE_PRECISION (TREE_TYPE (primother)) < correct_width)
 {
-  tree type = TREE_TYPE (arg0);
-
   /* Make sure shorter operand is extended the right way
 to match the longer operand.  */
   primarg1 = fold_convert (signed_or_unsigned_type_for

so far it seems to work.