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.