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.