Patchwork [x32] PATCH: PR target/47364: [x32] internal compiler error: in emit_move_insn, at expr.c:3355

login
register
mail settings
Submitter H.J. Lu
Date Jan. 19, 2011, 9:39 p.m.
Message ID <20110119213953.GA3470@intel.com>
Download mbox | patch
Permalink /patch/79602/
State New
Headers show

Comments

H.J. Lu - Jan. 19, 2011, 9:39 p.m.
On Wed, Jan 19, 2011 at 12:55:01PM -0800, H.J. Lu wrote:
> ix86_legitimize_address needs to convert address to Pmode if needed.
> Checked into x32 branch.
> 
> 
> H.J.
> ---
> commit 1a67c864beb4a9d0c43092e235ccaf32a6c4a7cc
> Author: H.J. Lu <hjl.tools@gmail.com>
> Date:   Wed Jan 19 12:51:08 2011 -0800
> 
>     Convert to Pmode if needed in ix86_legitimize_address.
> 
> diff --git a/gcc/ChangeLog.x32 b/gcc/ChangeLog.x32
> index 2a164b2..65694af 100644
> --- a/gcc/ChangeLog.x32
> +++ b/gcc/ChangeLog.x32
> @@ -1,5 +1,11 @@
>  2011-01-19  H.J. Lu  <hongjiu.lu@intel.com>
>  
> +	PR target/47364
> +	* config/i386/i386.c (ix86_legitimize_address): Convert to
> +	Pmode if needed.
> +

Another problem is we don't properly expand builtin strlen when
Pmode != ptr_mode.  Fixed by this patch.

H.J.
---
commit ef4568578a53e96d810e336168125bb49a4d4a49
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Wed Jan 19 13:36:34 2011 -0800

    Properly handle Pmode != ptr_mode when expanding builtin strlen.

Patch

diff --git a/gcc/ChangeLog.x32 b/gcc/ChangeLog.x32
index 65694af..36ac432 100644
--- a/gcc/ChangeLog.x32
+++ b/gcc/ChangeLog.x32
@@ -1,6 +1,15 @@ 
 2011-01-19  H.J. Lu  <hongjiu.lu@intel.com>
 
 	PR target/47364
+	* builtins.c (expand_builtin_strlen): Convert to Pmode if PAT
+	isn't in Pmode.
+
+	* config/i386/i386.c (ix86_expand_strlen): Handle GET_MODE (out)
+	!= Pmode.
+
+2011-01-19  H.J. Lu  <hongjiu.lu@intel.com>
+
+	PR target/47364
 	* config/i386/i386.c (ix86_legitimize_address): Convert to
 	Pmode if needed.
 
diff --git a/gcc/builtins.c b/gcc/builtins.c
index ec0aecf..fe1c04a 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -3436,7 +3436,11 @@  expand_builtin_strlen (tree exp, rtx target,
       start_sequence ();
       pat = expand_expr (src, src_reg, ptr_mode, EXPAND_NORMAL);
       if (pat != src_reg)
-	emit_move_insn (src_reg, pat);
+	{
+	  if (GET_MODE (pat) != Pmode)
+	    pat = convert_to_mode (Pmode, pat, 1);
+	  emit_move_insn (src_reg, pat);
+	}
       pat = get_insns ();
       end_sequence ();
 
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index e18fcb6..55732de 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -21661,6 +21661,8 @@  ix86_expand_strlen (rtx out, rtx src, rtx eoschar, rtx align)
          often used and I use one fewer register for the lifetime of
          output_strlen_unroll() this is better.  */
 
+      if (GET_MODE (out) != Pmode)
+	out = convert_to_mode (Pmode, out, 1);
       emit_move_insn (out, addr);
 
       ix86_expand_strlensi_unroll_1 (out, src, align);
@@ -21692,7 +21694,15 @@  ix86_expand_strlen (rtx out, rtx src, rtx eoschar, rtx align)
 						 scratch4), UNSPEC_SCAS);
       emit_insn (gen_strlenqi_1 (scratch1, scratch3, unspec));
       emit_insn (ix86_gen_one_cmpl2 (scratch2, scratch1));
-      emit_insn (ix86_gen_add3 (out, scratch2, constm1_rtx));
+      if (GET_MODE (out) != Pmode)
+	{
+	  rtx scratch5 = gen_reg_rtx (Pmode);
+	  emit_insn (ix86_gen_add3 (scratch5, scratch2, constm1_rtx));
+	  scratch5 = convert_to_mode (GET_MODE (out), scratch5, 1);
+	  emit_move_insn (out, scratch5);
+	}
+      else
+	emit_insn (ix86_gen_add3 (out, scratch2, constm1_rtx));
     }
   return true;
 }
diff --git a/gcc/testsuite/ChangeLog.x32 b/gcc/testsuite/ChangeLog.x32
index 02be22b..4b1e5f8 100644
--- a/gcc/testsuite/ChangeLog.x32
+++ b/gcc/testsuite/ChangeLog.x32
@@ -1,5 +1,10 @@ 
 2011-01-19  H.J. Lu  <hongjiu.lu@intel.com>
 
+	PR target/47364
+	* gcc.target/i386/pr47364-2.c: New.
+
+2011-01-19  H.J. Lu  <hongjiu.lu@intel.com>
+
 	* gcc.target/i386/pr47364.c: Moved to ...
 	* gcc.target/i386/pr47364-1.c: This.
 
diff --git a/gcc/testsuite/gcc.target/i386/pr47364-2.c b/gcc/testsuite/gcc.target/i386/pr47364-2.c
new file mode 100644
index 0000000..8c93d6f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr47364-2.c
@@ -0,0 +1,11 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+extern __SIZE_TYPE__ strlen (const char *);
+void foo (char *, const char *);
+int bar (const char *prefix)
+{
+    char buff[256];
+    foo (buff, prefix);
+    return strlen(buff);
+}