Hi,
this is a regression introduced by the canonicalization of BIT_FIELD_REF in
match.pd, which totally disregards the REF_REVERSE_STORAGE_ORDER flag, and
visible as the failure of gnat.dg/sso/q[23].adb on SPARC 64-bit. But the
underlying issue of the missing propagation of the flag during GIMPLE folding
has probably been latent for quite some time on all active branches.
Tested on x86-64/Linux and SPARC/Solaris, OK for mainline? And branches?
2018-09-28 Eric Botcazou <ebotca...@adacore.com>
PR tree-optimization/86659
* gimple-match.h (struct gimple_match_op): Add reverse field.
(gimple_match_op::set_op): New overloaded method.
* gimple-match-head.c (maybe_build_generic_op) <BIT_FIELD_REF>: Set
the REF_REVERSE_STORAGE_ORDER flag on the value.
(gimple_simplify) <GIMPLE_ASSIGN>: For BIT_FIELD_REF, propagate the
REF_REVERSE_STORAGE_ORDER flag and avoid simplifying if it is set.
--
Eric Botcazou
Index: gimple-match.h
===================================================================
--- gimple-match.h (revision 264686)
+++ gimple-match.h (working copy)
@@ -98,6 +98,7 @@ struct gimple_match_op
void set_op (code_helper, tree, tree);
void set_op (code_helper, tree, tree, tree);
void set_op (code_helper, tree, tree, tree, tree);
+ void set_op (code_helper, tree, tree, tree, tree, bool);
void set_op (code_helper, tree, tree, tree, tree, tree);
void set_op (code_helper, tree, tree, tree, tree, tree, tree);
void set_value (tree);
@@ -117,6 +118,10 @@ struct gimple_match_op
/* The type of the result. */
tree type;
+ /* For a BIT_FIELD_REF, whether the group of bits is stored in reverse order
+ from the target order. */
+ bool reverse;
+
/* The number of operands to CODE. */
unsigned int num_ops;
@@ -243,6 +248,19 @@ gimple_match_op::set_op (code_helper cod
num_ops = 3;
ops[0] = op0;
ops[1] = op1;
+ ops[2] = op2;
+}
+
+inline void
+gimple_match_op::set_op (code_helper code_in, tree type_in,
+ tree op0, tree op1, tree op2, bool reverse_in)
+{
+ code = code_in;
+ type = type_in;
+ reverse = reverse_in;
+ num_ops = 3;
+ ops[0] = op0;
+ ops[1] = op1;
ops[2] = op2;
}
Index: gimple-match-head.c
===================================================================
--- gimple-match-head.c (revision 264686)
+++ gimple-match-head.c (working copy)
@@ -445,16 +445,20 @@ void
maybe_build_generic_op (gimple_match_op *res_op)
{
tree_code code = (tree_code) res_op->code;
+ tree val;
switch (code)
{
case REALPART_EXPR:
case IMAGPART_EXPR:
case VIEW_CONVERT_EXPR:
- res_op->set_value (build1 (code, res_op->type, res_op->ops[0]));
+ val = build1 (code, res_op->type, res_op->ops[0]);
+ res_op->set_value (val);
break;
case BIT_FIELD_REF:
- res_op->set_value (build3 (code, res_op->type, res_op->ops[0],
- res_op->ops[1], res_op->ops[2]));
+ val = build3 (code, res_op->type, res_op->ops[0], res_op->ops[1],
+ res_op->ops[2]);
+ REF_REVERSE_STORAGE_ORDER (val) = res_op->reverse;
+ res_op->set_value (val);
break;
default:;
}
@@ -853,7 +857,10 @@ gimple_simplify (gimple *stmt, gimple_ma
op0 = do_valueize (op0, top_valueize, valueized);
res_op->set_op (code, type, op0,
TREE_OPERAND (rhs1, 1),
- TREE_OPERAND (rhs1, 2));
+ TREE_OPERAND (rhs1, 2),
+ REF_REVERSE_STORAGE_ORDER (rhs1));
+ if (res_op->reverse)
+ return valueized;
return (gimple_resimplify3 (seq, res_op, valueize)
|| valueized);
}