static tree
c_genericize_control_r (tree *stmt_p, int *walk_subtrees, void *data)
{
+ tree stmt = *stmt_p;
+ /* Mark stores to parts of complex automatic non-addressable
+ variables as DECL_NOT_GIMPLE_REG_P for -O0. This can't be
+ done during gimplification. See PR119120. */
+ if (TREE_CODE (stmt) == MODIFY_EXPR
+ && (TREE_CODE (TREE_OPERAND (stmt, 0)) == REALPART_EXPR
+ || TREE_CODE (TREE_OPERAND (stmt, 0)) == IMAGPART_EXPR)
+ && !optimize
+ && DECL_P (TREE_OPERAND (TREE_OPERAND (stmt, 0), 0))
+ && is_gimple_reg (TREE_OPERAND (TREE_OPERAND (stmt, 0), 0)))
+ DECL_NOT_GIMPLE_REG_P (TREE_OPERAND (TREE_OPERAND (stmt, 0), 0)) = 1;
+
c_genericize_control_stmt (stmt_p, walk_subtrees, data,
c_genericize_control_r, NULL);
return NULL;
TREE_TYPE (stmt), TREE_OPERAND (stmt, 0));
break;
+ case MODIFY_EXPR:
+ /* Mark stores to parts of complex automatic non-addressable
+ variables as DECL_NOT_GIMPLE_REG_P for -O0. This can't be
+ done during gimplification. See PR119120. */
+ if ((TREE_CODE (TREE_OPERAND (stmt, 0)) == REALPART_EXPR
+ || TREE_CODE (TREE_OPERAND (stmt, 0)) == IMAGPART_EXPR)
+ && !optimize
+ && DECL_P (TREE_OPERAND (TREE_OPERAND (stmt, 0), 0))
+ && is_gimple_reg (TREE_OPERAND (TREE_OPERAND (stmt, 0), 0)))
+ DECL_NOT_GIMPLE_REG_P (TREE_OPERAND (TREE_OPERAND (stmt, 0), 0)) = 1;
+ break;
+
default:
if (IS_TYPE_OR_DECL_P (stmt))
*walk_subtrees = 0;
--- /dev/null
+/* PR target/119120 */
+/* { dg-do compile } */
+/* { dg-options "-O0 -fdump-tree-optimized" } */
+/* { dg-final { scan-tree-dump "REALPART_EXPR <r> = " "optimized" } } */
+/* { dg-final { scan-tree-dump "IMAGPART_EXPR <r> = " "optimized" } } */
+/* { dg-final { scan-tree-dump "REALPART_EXPR <s> = " "optimized" } } */
+/* { dg-final { scan-tree-dump-not "(REAL|IMAG)PART_EXPR <t> = " "optimized" } } */
+/* { dg-final { scan-tree-dump-not "(REAL|IMAG)PART_EXPR <u> = " "optimized" } } */
+
+__complex__ double
+foo (void)
+{
+ __complex__ double r;
+ __imag__ r = 2.0;
+ __real__ r = 1.0;
+ return r + 1.0;
+}
+
+__complex__ float
+bar (float x, float y)
+{
+ __complex__ float s = x + y * 1.0fi;
+ __real__ s = 1.0f;
+ return s + 1.0f;
+}
+
+__complex__ float
+baz (float x, float y)
+{
+ __complex__ float t = x + y * 1.0fi;
+ return t + 1.0f;
+}
+
+__complex__ float
+qux (__complex__ float x)
+{
+ __complex__ float u;
+ u = x;
+ return u + 1.0f;
+}