if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, "\nChaining allocnos:\n");
- // Perform (modified) interval graph coloring. First sort by
- // increasing start point.
- m_sorted_allocnos.reserve (m_allocnos.length ());
- m_sorted_allocnos.splice (m_allocnos);
- m_sorted_allocnos.qsort (cmp_increasing<&allocno_info::start_point>);
-
- // During this phase, color representatives are only correct for
- // unprocessed allocno groups (where the color representative is
- // the group itself) and for groups that contain a current chain head.
- unsigned int ti = 0;
- auto_vec<chain_candidate_info> candidates;
- for (unsigned int hi = 0; hi < m_sorted_allocnos.length (); ++hi)
+ // Record conflicts of hard register and ABI conflicts before the
+ // forming of chains so chains have the updated candidates
+ for (auto *allocno1 : m_allocnos)
{
- auto *allocno1 = m_sorted_allocnos[hi];
- if (allocno1->chain_next != INVALID_ALLOCNO)
- continue;
-
// Record conflicts with direct uses for FPR hard registers.
auto *group1 = allocno1->group ();
for (unsigned int fpr = allocno1->offset; fpr < 32; ++fpr)
auto fprs = partial_fpr_clobbers (abi_id, group1->fpr_size);
group1->fpr_candidates &= ~fprs >> allocno1->offset;
}
+ if (allocno1->is_shared ())
+ {
+ auto *allocno2 = m_allocnos[allocno1->related_allocno];
+ merge_fpr_info (allocno2->group (), group1, allocno2->offset);
+ }
+ }
+
+ // Perform (modified) interval graph coloring. First sort by
+ // increasing start point.
+ m_sorted_allocnos.reserve (m_allocnos.length ());
+ m_sorted_allocnos.splice (m_allocnos);
+ m_sorted_allocnos.qsort (cmp_increasing<&allocno_info::start_point>);
+
+ // During this phase, color representatives are only correct for
+ // unprocessed allocno groups (where the color representative is
+ // the group itself) and for groups that contain a current chain head.
+ unsigned int ti = 0;
+ auto_vec<chain_candidate_info> candidates;
+ for (unsigned int hi = 0; hi < m_sorted_allocnos.length (); ++hi)
+ {
+ auto *allocno1 = m_sorted_allocnos[hi];
+ if (allocno1->chain_next != INVALID_ALLOCNO)
+ continue;
if (allocno1->is_shared ())
{
fprintf (dump_file, " Allocno %d shares the same hard register"
" as allocno %d\n", allocno1->id,
allocno1->related_allocno);
- auto *allocno2 = m_allocnos[allocno1->related_allocno];
- merge_fpr_info (allocno2->group (), group1, allocno2->offset);
m_shared_allocnos.safe_push (allocno1);
continue;
}
--- /dev/null
+/* { dg-do run } */
+/* { dg-options "-O3" } */
+/* PR target/123285 */
+
+#define BS_VEC(type, num) type __attribute__((vector_size(num * sizeof(type))))
+
+/* f used to allocate v30 to either a or b and the inline-asm
+ would clobber the v30. */
+[[gnu::noipa]]
+BS_VEC(int, 8) f(BS_VEC(int, 8) a, BS_VEC(int, 8) b)
+{
+ a+=b;
+ asm("movi v30.16b, 0":::"v30");
+ a+=b;
+ return a;
+}
+[[gnu::noipa]]
+BS_VEC(int, 8) f1(BS_VEC(int, 8) a, BS_VEC(int, 8) b)
+{
+ a+=b;
+ a+=b;
+ return a;
+}
+
+int main()
+{
+ BS_VEC(int, 8) a = {0,1,2,3,4,5,6,7};
+ BS_VEC(int, 8) b = {8,9,10,11,12,13,14};
+ BS_VEC(int, 8) c0 = f(a,b);
+ BS_VEC(int, 8) c1 = f1(a,b);
+ for(int i=0;i<8;i++)
+ if ( c0[i] != c1[i] )
+ __builtin_abort ();
+}
+
+