[Bug tree-optimization/81814] Incorrect behaviour at -O0 (conditional operator)
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)
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)
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)
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)
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)
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)
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)
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.