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 Feb. 19, 2011, 2:57 p.m.
Message ID <20110219145753.GA31125@intel.com>
Download mbox | patch
Permalink /patch/83695/
State New
Headers show

Comments

H.J. Lu - Feb. 19, 2011, 2:57 p.m.
On Wed, Jan 19, 2011 at 01:39:53PM -0800, H.J. Lu wrote:
> 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.
> 
> 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.
> +

This patch is incorrect.  Changes to ix86_expand_strlen caused:

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47812

The real bug is in expand_builtin_strlen. "result" should be in Pmode,
not in insn_mode.  This patch fixes it.


H.J.
---
From 5a57aac571f503ff652f47231904ecb4863cc4f6 Mon Sep 17 00:00:00 2001
From: H.J. Lu <hjl.tools@gmail.com>
Date: Sat, 19 Feb 2011 06:49:47 -0800
Subject: [PATCH] Properly handle target not in Pmode when expanding strlen.

---
 gcc/ChangeLog.x32                        |    8 ++++++++
 gcc/builtins.c                           |    4 ++--
 gcc/config/i386/i386.c                   |   12 +-----------
 gcc/testsuite/ChangeLog.x32              |    5 +++++
 gcc/testsuite/gcc.dg/torture/pr47364-1.c |    8 ++++++++
 5 files changed, 24 insertions(+), 13 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/torture/pr47364-1.c

Patch

diff --git a/gcc/ChangeLog.x32 b/gcc/ChangeLog.x32
index 3430a75..735d831 100644
--- a/gcc/ChangeLog.x32
+++ b/gcc/ChangeLog.x32
@@ -1,3 +1,11 @@ 
+2011-02-19  H.J. Lu  <hongjiu.lu@intel.com>
+
+	PR middle-end/47364
+	* builtins.c (expand_builtin_strlen): Properly handle target
+	not in Pmode.
+
+	* config/i386/i386.c (ix86_expand_strlen): Revet the last change.
+
 2011-02-18  H.J. Lu  <hongjiu.lu@intel.com>
 
 	PR target/47744
diff --git a/gcc/builtins.c b/gcc/builtins.c
index e6e7ac5..894aa38 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -3408,9 +3408,9 @@  expand_builtin_strlen (tree exp, rtx target,
       result = target;
       if (! (result != 0
 	     && REG_P (result)
-	     && GET_MODE (result) == insn_mode
+	     && GET_MODE (result) == Pmode
 	     && REGNO (result) >= FIRST_PSEUDO_REGISTER))
-	result = gen_reg_rtx (insn_mode);
+	result = gen_reg_rtx (Pmode);
 
       /* Make a place to hold the source address.  We will not expand
 	 the actual source until we are sure that the expansion will
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index d5af8c8..ac66831 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -21902,8 +21902,6 @@  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);
@@ -21935,15 +21933,7 @@  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));
-      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));
+      emit_insn (ix86_gen_add3 (out, scratch2, constm1_rtx));
     }
   return true;
 }
diff --git a/gcc/testsuite/ChangeLog.x32 b/gcc/testsuite/ChangeLog.x32
index eac343d..1e0dd89 100644
--- a/gcc/testsuite/ChangeLog.x32
+++ b/gcc/testsuite/ChangeLog.x32
@@ -1,3 +1,8 @@ 
+2011-02-19  H.J. Lu  <hongjiu.lu@intel.com>
+
+	PR middle-end/47364
+	* gcc.dg/torture/pr47364-1.c: New.
+
 2011-02-18  H.J. Lu  <hongjiu.lu@intel.com>
 
 	PR target/47744
diff --git a/gcc/testsuite/gcc.dg/torture/pr47364-1.c b/gcc/testsuite/gcc.dg/torture/pr47364-1.c
new file mode 100644
index 0000000..3ac6999
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr47364-1.c
@@ -0,0 +1,8 @@ 
+/* { dg-do run } */
+
+char one[50] = "ijk";
+int
+main (void)
+{
+  return __builtin_strlen (one) != 3;
+}