diff mbox

[PR,60556] Fix ICE on platforms with signed pointer extension.

Message ID 48fc611a-fb75-4ced-a07b-52909c558f74@BAMAIL02.ba.imgtec.org
State New
Headers show

Commit Message

Steve Ellcey March 20, 2014, 4:48 p.m. UTC
This patch fixes pr60556, a GCC ICE.  The problem is in convert_move where,
if we are trying to put a 32 bit address into a 64 bit destination we
can wind up calling emit_move_insn with NULL_RTX as a source.

The problem comes when creating fill_value.  If unsignedp is false
then we call emit_store_flag to set fill_value.  If lowfrom is a symbol
reference then emit_store_flag returns NULL_RTX (because symbol references
are constant) and we wind up calling emit_move_insn with NULL_RTX as a
source and getting an ICE.

My fix is to check for a symbol reference up where we are already 
checking for memory references and force the symbol into a register
before calling emit_store_flag.  This will prevent emit_store_flag
from returning NULL_RTX.  In theory we could force the symbol
reference into a register only if unsignedp is false, but I think
it is cleaner to always put the symbol reference into a register.

Tested on mips-mti-linux-gnu with no regressions.

OK for checkin?

Steve Ellcey
sellcey@mips.com


2014-03-20  Steve Ellcey  <sellcey@mips.com>

	PR middle-end/60556
	* expr.c (convert_move): Force symbol references into register.

Comments

Steve Ellcey April 10, 2014, 7:57 p.m. UTC | #1
Patch ping.  This is not a regression as I can reproduce it on GCC 4.8.*
but it is an ICE on legal C code.  Any chance of having it approved for
4.9?

Steve Ellcey
sellcey@mips.com


On Thu, 2014-03-20 at 09:48 -0700, Steve Ellcey wrote:
> This patch fixes pr60556, a GCC ICE.  The problem is in convert_move where,
> if we are trying to put a 32 bit address into a 64 bit destination we
> can wind up calling emit_move_insn with NULL_RTX as a source.
> 
> The problem comes when creating fill_value.  If unsignedp is false
> then we call emit_store_flag to set fill_value.  If lowfrom is a symbol
> reference then emit_store_flag returns NULL_RTX (because symbol references
> are constant) and we wind up calling emit_move_insn with NULL_RTX as a
> source and getting an ICE.
> 
> My fix is to check for a symbol reference up where we are already 
> checking for memory references and force the symbol into a register
> before calling emit_store_flag.  This will prevent emit_store_flag
> from returning NULL_RTX.  In theory we could force the symbol
> reference into a register only if unsignedp is false, but I think
> it is cleaner to always put the symbol reference into a register.
> 
> Tested on mips-mti-linux-gnu with no regressions.
> 
> OK for checkin?
> 
> Steve Ellcey
> sellcey@mips.com
> 
> 
> 2014-03-20  Steve Ellcey  <sellcey@mips.com>
> 
> 	PR middle-end/60556
> 	* expr.c (convert_move): Force symbol references into register.
> 
> 
> diff --git a/gcc/expr.c b/gcc/expr.c
> index be62c53..d065588 100644
> --- a/gcc/expr.c
> +++ b/gcc/expr.c
> @@ -533,7 +533,8 @@ convert_move (rtx to, rtx from, int unsignedp)
>           conversion sequence might require several references to it and we
>           must ensure we're getting the same value every time.  */
>  
> -      if (MEM_P (from) || reg_overlap_mentioned_p (to, from))
> +      if (MEM_P (from) || GET_CODE (from) == SYMBOL_REF
> +	  || reg_overlap_mentioned_p (to, from))
>  	from = force_reg (from_mode, from);
>  
>        /* Get a copy of FROM widened to a word, if necessary.  */
> 
> 
> 
> 2014-03-20  Steve Ellcey  <sellcey@mips.com>
> 
> 	PR middle-end/60556
> 	gcc.dg/pr60556.c: New.
> 
> 
> diff --git a/gcc/testsuite/gcc.dg/pr60556.c b/gcc/testsuite/gcc.dg/pr60556.c
> new file mode 100644
> index 0000000..3b5bbe5
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/pr60556.c
> @@ -0,0 +1,7 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2" } */
> +
> +int g (int);
> +unsigned long long f(void) {
> + return (unsigned long long)(long)&g;
> +}
diff mbox

Patch

diff --git a/gcc/expr.c b/gcc/expr.c
index be62c53..d065588 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -533,7 +533,8 @@  convert_move (rtx to, rtx from, int unsignedp)
          conversion sequence might require several references to it and we
          must ensure we're getting the same value every time.  */
 
-      if (MEM_P (from) || reg_overlap_mentioned_p (to, from))
+      if (MEM_P (from) || GET_CODE (from) == SYMBOL_REF
+	  || reg_overlap_mentioned_p (to, from))
 	from = force_reg (from_mode, from);
 
       /* Get a copy of FROM widened to a word, if necessary.  */



2014-03-20  Steve Ellcey  <sellcey@mips.com>

	PR middle-end/60556
	gcc.dg/pr60556.c: New.


diff --git a/gcc/testsuite/gcc.dg/pr60556.c b/gcc/testsuite/gcc.dg/pr60556.c
new file mode 100644
index 0000000..3b5bbe5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr60556.c
@@ -0,0 +1,7 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+int g (int);
+unsigned long long f(void) {
+ return (unsigned long long)(long)&g;
+}