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

Reply via email to