aboutsummaryrefslogtreecommitdiff
path: root/gcc/cfgexpand.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cfgexpand.c')
-rw-r--r--gcc/cfgexpand.c32
1 files changed, 31 insertions, 1 deletions
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index 86efa22..b270a4d 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -4616,7 +4616,8 @@ expand_debug_expr (tree exp)
op0 = copy_rtx (op0);
if (op0 == orig_op0)
op0 = shallow_copy_rtx (op0);
- set_mem_attributes (op0, exp, 0);
+ if (TREE_CODE (tem) != SSA_NAME)
+ set_mem_attributes (op0, exp, 0);
}
if (known_eq (bitpos, 0) && mode == GET_MODE (op0))
@@ -6126,6 +6127,29 @@ discover_nonconstant_array_refs_r (tree * tp, int *walk_subtrees,
return NULL_TREE;
}
+/* If there's a chance to get a pseudo for t then if it would be of float mode
+ and the actual access is via an integer mode (lowered memcpy or similar
+ access) then avoid the register expansion if the mode likely is not storage
+ suitable for raw bits processing (like XFmode on i?86). */
+
+static void
+avoid_type_punning_on_regs (tree t)
+{
+ machine_mode access_mode = TYPE_MODE (TREE_TYPE (t));
+ if (access_mode != BLKmode
+ && !SCALAR_INT_MODE_P (access_mode))
+ return;
+ tree base = get_base_address (t);
+ if (DECL_P (base)
+ && !TREE_ADDRESSABLE (base)
+ && FLOAT_MODE_P (DECL_MODE (base))
+ && maybe_lt (GET_MODE_PRECISION (DECL_MODE (base)),
+ GET_MODE_BITSIZE (GET_MODE_INNER (DECL_MODE (base))))
+ /* Double check in the expensive way we really would get a pseudo. */
+ && use_register_for_decl (base))
+ TREE_ADDRESSABLE (base) = 1;
+}
+
/* RTL expansion is not able to compile array references with variable
offsets for arrays stored in single register. Discover such
expressions and mark variables as addressable to avoid this
@@ -6159,6 +6183,12 @@ discover_nonconstant_array_refs (void)
default:
break;
}
+ if (gimple_vdef (stmt))
+ {
+ tree t = gimple_get_lhs (stmt);
+ if (t && REFERENCE_CLASS_P (t))
+ avoid_type_punning_on_regs (t);
+ }
}
}
}