re PR middle-end/70370 (ICE in execute_todo, at passes.c:2003 when using __real__ or __imag__ as lvalue in asm)

2016-03-24  Richard Biener  <rguenther@suse.de>

	PR middle-end/70370
	* gimplify.c (gimplify_asm_expr): Handle !allows_mem outputs
	with register bases.

	* gcc.dg/torture/pr70370.c: New testcase.

From-SVN: r234453
This commit is contained in:
Richard Biener 2016-03-24 12:19:56 +00:00 committed by Richard Biener
parent ea064934b6
commit ed87de5583
4 changed files with 82 additions and 0 deletions

View File

@ -1,3 +1,9 @@
2016-03-24 Richard Biener <rguenther@suse.de>
PR middle-end/70370
* gimplify.c (gimplify_asm_expr): Handle !allows_mem outputs
with register bases.
2016-03-24 Richard Biener <rguenther@suse.de>
PR tree-optimization/70372

View File

@ -5191,6 +5191,32 @@ gimplify_asm_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
ret = tret;
}
/* If the constraint does not allow memory make sure we gimplify
it to a register if it is not already but its base is. This
happens for complex and vector components. */
if (!allows_mem)
{
tree op = TREE_VALUE (link);
if (! is_gimple_val (op)
&& is_gimple_reg_type (TREE_TYPE (op))
&& is_gimple_reg (get_base_address (op)))
{
tree tem = create_tmp_reg (TREE_TYPE (op));
tree ass;
if (is_inout)
{
ass = build2 (MODIFY_EXPR, TREE_TYPE (tem),
tem, unshare_expr (op));
gimplify_and_add (ass, pre_p);
}
ass = build2 (MODIFY_EXPR, TREE_TYPE (tem), op, tem);
gimplify_and_add (ass, post_p);
TREE_VALUE (link) = tem;
tret = GS_OK;
}
}
vec_safe_push (outputs, link);
TREE_CHAIN (link) = NULL_TREE;

View File

@ -1,3 +1,8 @@
2016-03-24 Richard Biener <rguenther@suse.de>
PR middle-end/70370
* gcc.dg/torture/pr70370.c: New testcase.
2016-03-24 Tom de Vries <tom@codesourcery.com>
* gfortran.dg/goacc/data-tree.f95: Add missing initialization.

View File

@ -0,0 +1,45 @@
/* { dg-do compile } */
_Complex float
test1 (_Complex float f)
{
__asm__ ("" : "+r" (__real f));
return f;
}
_Complex float
test2 (_Complex float f)
{
__asm__ ("" : "=r" (__real f));
return f;
}
struct X { int i; };
struct X
test3 (struct X x)
{
__asm__ ("" : "=r" (x.i));
return x;
}
struct X
test4 (struct X x)
{
__asm__ ("" : "+r" (x.i));
return x;
}
struct X
test5 (struct X x)
{
__asm__ ("" : "=r" (x));
return x;
}
struct X
test6 (struct X x)
{
__asm__ ("" : "+r" (x));
return x;
}