diff options
author | Richard Biener <rguenther@suse.de> | 2021-08-16 15:17:08 +0200 |
---|---|---|
committer | Richard Biener <rguenther@suse.de> | 2021-08-17 09:24:21 +0200 |
commit | 0215b3559e55f39f38e10984a804c53907f7491c (patch) | |
tree | e68670344dedba214ac58bb684efe45e21c2cfab /gcc/tree-ssa-sccvn.c | |
parent | 75a7176575c409940b66020def23508f5701f5fb (diff) | |
download | gcc-0215b3559e55f39f38e10984a804c53907f7491c.zip gcc-0215b3559e55f39f38e10984a804c53907f7491c.tar.gz gcc-0215b3559e55f39f38e10984a804c53907f7491c.tar.bz2 |
tree-optimization/101925 - fix VN with reverse storage order
This fixes value-numbering breaking reverse storage order accesses
due to a missed check. It adds a new overload for
reverse_storage_order_for_component_p and sets reversed on the
VN IL ops for component and array accesses accordingly.
It also compares the reversed reference ops flag on reference
lookup.
2021-08-16 Richard Biener <rguenther@suse.de>
PR tree-optimization/101925
* tree-ssa-sccvn.c (copy_reference_ops_from_ref): Set
reverse on COMPONENT_REF and ARRAY_REF according to
what reverse_storage_order_for_component_p does.
(vn_reference_eq): Compare reversed on reference ops.
(reverse_storage_order_for_component_p): New overload.
(vn_reference_lookup_3): Check reverse_storage_order_for_component_p
on the reference looked up.
* gcc.dg/sso-16.c: New testcase.
Diffstat (limited to 'gcc/tree-ssa-sccvn.c')
-rw-r--r-- | gcc/tree-ssa-sccvn.c | 33 |
1 files changed, 32 insertions, 1 deletions
diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c index 01fffcd..82bd10b 100644 --- a/gcc/tree-ssa-sccvn.c +++ b/gcc/tree-ssa-sccvn.c @@ -797,6 +797,7 @@ vn_reference_eq (const_vn_reference_t const vr1, const_vn_reference_t const vr2) vn_reference_op_t vro1, vro2; vn_reference_op_s tem1, tem2; bool deref1 = false, deref2 = false; + bool reverse1 = false, reverse2 = false; for (; vr1->operands.iterate (i, &vro1); i++) { if (vro1->opcode == MEM_REF) @@ -804,6 +805,7 @@ vn_reference_eq (const_vn_reference_t const vr1, const_vn_reference_t const vr2) /* Do not look through a storage order barrier. */ else if (vro1->opcode == VIEW_CONVERT_EXPR && vro1->reverse) return false; + reverse1 |= vro1->reverse; if (known_eq (vro1->off, -1)) break; off1 += vro1->off; @@ -815,11 +817,12 @@ vn_reference_eq (const_vn_reference_t const vr1, const_vn_reference_t const vr2) /* Do not look through a storage order barrier. */ else if (vro2->opcode == VIEW_CONVERT_EXPR && vro2->reverse) return false; + reverse2 |= vro2->reverse; if (known_eq (vro2->off, -1)) break; off2 += vro2->off; } - if (maybe_ne (off1, off2)) + if (maybe_ne (off1, off2) || reverse1 != reverse2) return false; if (deref1 && vro1->opcode == ADDR_EXPR) { @@ -916,6 +919,9 @@ copy_reference_ops_from_ref (tree ref, vec<vn_reference_op_s> *result) temp.type = NULL_TREE; temp.op0 = TREE_OPERAND (ref, 1); temp.op1 = TREE_OPERAND (ref, 2); + temp.reverse = (AGGREGATE_TYPE_P (TREE_TYPE (TREE_OPERAND (ref, 0))) + && TYPE_REVERSE_STORAGE_ORDER + (TREE_TYPE (TREE_OPERAND (ref, 0)))); { tree this_offset = component_ref_field_offset (ref); if (this_offset @@ -962,6 +968,9 @@ copy_reference_ops_from_ref (tree ref, vec<vn_reference_op_s> *result) * vn_ref_op_align_unit (&temp)); off.to_shwi (&temp.off); } + temp.reverse = (AGGREGATE_TYPE_P (TREE_TYPE (TREE_OPERAND (ref, 0))) + && TYPE_REVERSE_STORAGE_ORDER + (TREE_TYPE (TREE_OPERAND (ref, 0)))); } break; case VAR_DECL: @@ -1583,6 +1592,26 @@ contains_storage_order_barrier_p (vec<vn_reference_op_s> ops) return false; } +/* Return true if OPS represent an access with reverse storage order. */ + +static bool +reverse_storage_order_for_component_p (vec<vn_reference_op_s> ops) +{ + unsigned i = 0; + if (ops[i].opcode == REALPART_EXPR || ops[i].opcode == IMAGPART_EXPR) + ++i; + switch (ops[i].opcode) + { + case ARRAY_REF: + case COMPONENT_REF: + case BIT_FIELD_REF: + case MEM_REF: + return ops[i].reverse; + default: + return false; + } +} + /* Transform any SSA_NAME's in a vector of vn_reference_op_s structures into their value numbers. This is done in-place, and the vector passed in is returned. *VALUEIZED_ANYTHING will specify @@ -2899,6 +2928,7 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *data_, routines to extract the assigned bits. */ else if (known_eq (ref->size, maxsize) && is_gimple_reg_type (vr->type) + && !reverse_storage_order_for_component_p (vr->operands) && !contains_storage_order_barrier_p (vr->operands) && gimple_assign_single_p (def_stmt) && CHAR_BIT == 8 @@ -3050,6 +3080,7 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *data_, to access pieces from or we can combine to a larger entity. */ else if (known_eq (ref->size, maxsize) && is_gimple_reg_type (vr->type) + && !reverse_storage_order_for_component_p (vr->operands) && !contains_storage_order_barrier_p (vr->operands) && gimple_assign_single_p (def_stmt) && TREE_CODE (gimple_assign_rhs1 (def_stmt)) == SSA_NAME) |