------- Comment #7 from rguenth at gcc dot gnu dot org  2007-04-10 15:32 -------
store_copyprop is not able to optimize this because the two array refs
r.dst[0].i use different types for the index zero (one int, one unsigned long)
and one has operand2 and operand3 set but the other not and operand_equal_p
compares not by value.  Doh.  No idea why operand_equal_p should care about
those operands as

/* Array indexing.
   Operand 0 is the array; operand 1 is a (single) array index.
   Operand 2, if present, is a copy of TYPE_MIN_VALUE of the index.
   Operand 3, if present, is the element size, measured in units of
   the alignment of the element type.  */
DEFTREECODE (ARRAY_REF, "array_ref", tcc_reference, 4)

correctly hints that those do not carry extra information.  With those "fixed"
we finally get

<bb 2>:
  d.0 = (__m128i *) d;
  # VUSE <SMT.6_18(D)>
  D.2490 = *d.0;
  # SMT.6_21 = VDEF <SMT.6_18(D)>
  D.2496 = __builtin_ia32_paddusb128 (VIEW_CONVERT_EXPR<__v16qi>(D.2490),
VIEW_CONVERT_EXPR<__v16qi>(D.2490));
  # SMT.6_23 = VDEF <SMT.6_21>
  __builtin_ia32_movntdq (d.0, VIEW_CONVERT_EXPR<__m128i>(D.2496));

as store_copyprop can replace the loaded value by the stored one.  "Fixed" as
in

Index: fold-const.c
===================================================================
*** fold-const.c        (revision 123691)
--- fold-const.c        (working copy)
*************** operand_equal_p (tree arg0, tree arg1, u
*** 2884,2894 ****

        case ARRAY_REF:
        case ARRAY_RANGE_REF:
!         /* Operands 2 and 3 may be null.  */
          return (OP_SAME (0)
!                 && OP_SAME (1)
!                 && OP_SAME_WITH_NULL (2)
!                 && OP_SAME_WITH_NULL (3));

        case COMPONENT_REF:
          /* Handle operand 2 the same as for ARRAY_REF.  Operand 0
--- 2884,2896 ----

        case ARRAY_REF:
        case ARRAY_RANGE_REF:
!         /* Operands 2 and 3 do not provide extra information.
!            Compare the array index by value if it is constant first as we
!            may have different types but same value here.  */
          return (OP_SAME (0)
!                 && (tree_int_cst_equal (TREE_OPERAND (arg0, 1),
!                                       TREE_OPERAND (arg1, 1))
!                     || OP_SAME (1)));

        case COMPONENT_REF:
          /* Handle operand 2 the same as for ARRAY_REF.  Operand 0

another thing would be to hunt down where the different typed indices are
produced and to either get rid of operands 2 and 3 from ARRAY_REF or
produce them consistently.


-- 

rguenth at gcc dot gnu dot org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
         AssignedTo|unassigned at gcc dot gnu   |rguenth at gcc dot gnu dot
                   |dot org                     |org
             Status|NEW                         |ASSIGNED
   Last reconfirmed|2007-04-10 14:37:48         |2007-04-10 15:32:01
               date|                            |


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31307

Reply via email to