summaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-sccvn.c
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2020-08-04 14:10:45 +0200
committerRichard Biener <rguenther@suse.de>2020-08-04 15:29:19 +0200
commit1af5cdd77985daf76130f527deac425c43df9f49 (patch)
treeb9f60d270eeda2fded7364104ac18674414d3c9b /gcc/tree-ssa-sccvn.c
parent7bd72dd5a385dfa6d49cfe640cefc9ed187361d3 (diff)
tree-optimization/88240 - stopgap for floating point code-hoisting issues
This adds a stopgap measure to avoid performing code-hoisting on mixed type loads when the load we'd insert in the hoisting position would be a floating point one. This is because certain targets (hello x87) cannot perform floating point loads without possibly altering the bit representation and thus cannot be used in place of integral loads. 2020-08-04 Richard Biener <rguenther@suse.de> PR tree-optimization/88240 * tree-ssa-sccvn.h (vn_reference_s::punned): New flag. * tree-ssa-sccvn.c (vn_reference_insert): Initialize punned. (vn_reference_insert_pieces): Likewise. (visit_reference_op_call): Likewise. (visit_reference_op_load): Track whether a ref was punned. * tree-ssa-pre.c (do_hoist_insertion): Refuse to perform hoist insertion on punned floating point loads. * gcc.target/i386/pr88240.c: New testcase.
Diffstat (limited to 'gcc/tree-ssa-sccvn.c')
-rw-r--r--gcc/tree-ssa-sccvn.c13
1 files changed, 12 insertions, 1 deletions
diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c
index 2e925a1afbf..934ae40670d 100644
--- a/gcc/tree-ssa-sccvn.c
+++ b/gcc/tree-ssa-sccvn.c
@@ -3601,6 +3601,7 @@ vn_reference_insert (tree op, tree result, tree vuse, tree vdef)
vr1->vuse = vuse_ssa_val (vuse);
vr1->operands = valueize_shared_reference_ops_from_ref (op, &tem).copy ();
vr1->type = TREE_TYPE (op);
+ vr1->punned = 0;
ao_ref op_ref;
ao_ref_init (&op_ref, op);
vr1->set = ao_ref_alias_set (&op_ref);
@@ -3660,6 +3661,7 @@ vn_reference_insert_pieces (tree vuse, alias_set_type set,
vr1->vuse = vuse_ssa_val (vuse);
vr1->operands = valueize_refs (operands);
vr1->type = type;
+ vr1->punned = 0;
vr1->set = set;
vr1->base_set = base_set;
vr1->hashcode = vn_reference_compute_hash (vr1);
@@ -4892,6 +4894,7 @@ visit_reference_op_call (tree lhs, gcall *stmt)
them here. */
vr2->operands = vr1.operands.copy ();
vr2->type = vr1.type;
+ vr2->punned = vr1.punned;
vr2->set = vr1.set;
vr2->base_set = vr1.base_set;
vr2->hashcode = vr1.hashcode;
@@ -4918,10 +4921,11 @@ visit_reference_op_load (tree lhs, tree op, gimple *stmt)
bool changed = false;
tree last_vuse;
tree result;
+ vn_reference_t res;
last_vuse = gimple_vuse (stmt);
result = vn_reference_lookup (op, gimple_vuse (stmt),
- default_vn_walk_kind, NULL, true, &last_vuse);
+ default_vn_walk_kind, &res, true, &last_vuse);
/* We handle type-punning through unions by value-numbering based
on offset and size of the access. Be prepared to handle a
@@ -4943,6 +4947,13 @@ visit_reference_op_load (tree lhs, tree op, gimple *stmt)
gimple_match_op res_op (gimple_match_cond::UNCOND,
VIEW_CONVERT_EXPR, TREE_TYPE (op), result);
result = vn_nary_build_or_lookup (&res_op);
+ if (result
+ && TREE_CODE (result) == SSA_NAME
+ && VN_INFO (result)->needs_insertion)
+ /* Track whether this is the canonical expression for different
+ typed loads. We use that as a stopgap measure for code
+ hoisting when dealing with floating point loads. */
+ res->punned = true;
}
/* When building the conversion fails avoid inserting the reference