diff mbox

Fix expand_cond_expr_using_cmove (PR middle-end/56548)

Message ID 20130306154732.GU12913@tucnak.redhat.com
State New
Headers show

Commit Message

Jakub Jelinek March 6, 2013, 3:47 p.m. UTC
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  <jakub@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.


	Jakub

Comments

Richard Henderson March 6, 2013, 5:13 p.m. UTC | #1
On 03/06/2013 07:47 AM, Jakub Jelinek wrote:
> 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  <jakub@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.

Ok.


r~
diff mbox

Patch

--- 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;
+}