https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121649

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |law at gcc dot gnu.org

--- Comment #4 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Most likely CSE, yes.
(insn 1126 1125 1127 2 (set (reg:DI 673)
        (const_int 3 [0x3])) "pr121649.c":63:3 104 {*movdi_aarch64}
     (nil))
...
(insn 1173 1172 1174 2 (set (reg:V8QI 33 v1)
        (const_vector:V8QI [
                (const_int 3 [0x3])
                (const_int -4 [0xfffffffffffffffc])
                (const_int 0 [0]) repeated x6
            ])) "pr121649.c":63:3 1325 {*aarch64_simd_movv8qi}
     (nil))
...
(insn 1175 1174 1176 2 (set (reg:QI 7 x7)
        (subreg:QI (reg:DI 673) 0)) "pr121649.c":63:3 101 {*movqi_aarch64}
     (expr_list:REG_DEAD (reg:DI 673)
        (expr_list:REG_EQUAL (const_int 3 [0x3])
            (nil))))
...
(insn 1178 1177 1179 2 (set (reg:QI 4 x4)
        (vec_select:QI (reg:V8QI 33 v1)
            (parallel [
                    (const_int 1 [0x1])
                ]))) "pr121649.c":63:3 2968 {aarch64_get_lanev8qi}
     (expr_list:REG_EQUAL (const_int -4 [0xfffffffffffffffc])
        (nil)))

So, what I see is before cse_insn on 1175 during cse2, we have correct
const_rtx remembered both for (reg:DI 673) and (reg:V8QI 33 v1).
But then we trigger
      if (elt && src_eqv_here && src_eqv_elt)
        {
          if (elt->first_same_value != src_eqv_elt->first_same_value)
            {
              /* The REG_EQUAL is indicating that two formerly distinct
                 classes are now equivalent.  So merge them.  */
              merge_equiv_classes (elt, src_eqv_elt);
              src_eqv_hash = HASH (src_eqv, elt->mode);
              src_eqv_elt = lookup (src_eqv, src_eqv_hash, elt->mode);
            }

          src_eqv_here = 0;
        }
elt->first_same_value->exp is
(subreg:QI (reg:DI 673) 0)
and elt->first_same_value->next_same_value->exp is
(mem:QI (reg/f:DI 31 sp) [0  S1 A64])
and elt == elt->first_same_value.
src_eqv_elt->first_same_value->exp
(reg:QI 33 v1)
src_eqv_elt->first_same_value->next_same_value->exp
(const_int 3 [0x3])
and src_eqv_elt == src_eqv_elt->first_same_value->next_same_value
Now all of this is correct, (subreg:QI (reg:DI 673) 0) and (mem:QI (reg/f:DI 31
sp) [0  S1 A64]) and (reg:QI 33 v1) and (const_int 3 [0x3]) have the same
value.
Despite that, merging the two classes is harmful in this case, while the value
is ok
for (reg:QI 33 v1), it is not for (reg:V8QI 33 v1).
          if (REG_P (exp))
            {
              need_rehash = REGNO_QTY_VALID_P (REGNO (exp));
              delete_reg_equiv (REGNO (exp));
            }
in merge_classes will forget the remembered
(const_vector:V8QI [
                (const_int 3 [0x3])
                (const_int -4 [0xfffffffffffffffc])
                (const_int 0 [0]) repeated x6])
value and insert_regs (exp, class1, false) (or insert (exp, class1, hash, mode)
?) will
remember
(const_vector:V8QI [
                (const_int 3 [0x3])
                (const_int 0 [0]) repeated x7])
instead.

Reply via email to