re PR tree-optimization/86659 (gnat.dg/sso/q[23].adb FAIL)
authorEric Botcazou <ebotcazou@adacore.com>
Mon, 8 Oct 2018 22:47:32 +0000 (22:47 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Mon, 8 Oct 2018 22:47:32 +0000 (22:47 +0000)
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.

From-SVN: r264942

gcc/ChangeLog
gcc/gimple-match-head.c
gcc/gimple-match.h

index 8e06be7620baff1a3d3671292c688c9188a9a77d..392728d48e5d36b1faccad962eadf5650a10845a 100644 (file)
@@ -1,3 +1,13 @@
+2018-09-28  Eric Botcazou  <ebotcazou@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.
+        
 2018-10-08  Richard Sandiford  <richard.sandiford@arm.com>
 
        PR middle-end/63155
index 414007ec1f9ece6ba112387c9383938adce87950..d6c60ab34db6eafcc9e2b8a5d077a8734f5bf5ba 100644 (file)
@@ -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_match_op *res_op, gimple_seq *seq,
                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);
              }
index 704fa76c0a4a9ca76eba5556e02f04b4eadecfa2..79b9459f44410602d74e32dfe37823be97afcbf5 100644 (file)
@@ -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;
 
@@ -246,6 +251,19 @@ gimple_match_op::set_op (code_helper code_in, tree type_in,
   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;
+}
+
 inline void
 gimple_match_op::set_op (code_helper code_in, tree type_in,
                         tree op0, tree op1, tree op2, tree op3)