Hi! The http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=193539 change broke the following testcase on i386. The problem is that it can return the result in wider mode than callers expect, causing either ICEs or other issues later on.
It is fine to perform the cmove in promoted mode, but we should convert it to the right mode at the end in order not to confuse callers. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2013-03-06 Jakub Jelinek <ja...@redhat.com> PR middle-end/56548 * expr.c (expand_cond_expr_using_cmove): When expanding cmove in promoted mode, convert the result back to the original mode. * gcc.dg/pr56548.c: New test. --- gcc/expr.c.jj 2013-02-25 20:29:52.000000000 +0100 +++ gcc/expr.c 2013-03-06 11:13:23.683387708 +0100 @@ -7884,6 +7884,7 @@ expand_cond_expr_using_cmove (tree treeo tree type = TREE_TYPE (treeop1); int unsignedp = TYPE_UNSIGNED (type); enum machine_mode mode = TYPE_MODE (type); + enum machine_mode orig_mode = mode; /* If we cannot do a conditional move on the mode, try doing it with the promoted mode. */ @@ -7949,7 +7950,7 @@ expand_cond_expr_using_cmove (tree treeo rtx seq = get_insns (); end_sequence (); emit_insn (seq); - return temp; + return convert_modes (orig_mode, mode, temp, 0); } /* Otherwise discard the sequence and fall back to code with --- gcc/testsuite/gcc.dg/pr56548.c.jj 2013-03-06 11:16:39.754325708 +0100 +++ gcc/testsuite/gcc.dg/pr56548.c 2013-03-06 11:16:12.000000000 +0100 @@ -0,0 +1,16 @@ +/* PR middle-end/56548 */ +/* { dg-do compile } */ +/* { dg-options "-O3" } */ +/* { dg-additional-options "-march=pentium3" { target { { i?86-*-* x86_64-*-* } && ia32 } } } */ + +short +foo (short x) +{ + int i; + + for (i = 0; i < 3; i++) + if (x > 0) + x--; + + return x; +} Jakub