diff --git a/gcc/cse.c b/gcc/cse.c index c1c7d0ca27b73c4b944b4719f95fece74e0358d5..08295246c594109e947276051c6776e4cabca4ec 100644 --- a/gcc/cse.c +++ b/gcc/cse.c @@ -1537,6 +1537,17 @@ insert_with_costs (rtx x, struct table_elt *classp, unsigned int hash, if (REG_P (x) && REGNO (x) < FIRST_PSEUDO_REGISTER) add_to_hard_reg_set (&hard_regs_in_table, GET_MODE (x), REGNO (x)); + /* We cannot allow a duplicate to be entered into the equivalence sets + and so we should perform a check before we do any allocations or + change the buckets. */ + if (classp) + { + struct table_elt *p; + for (p = classp; p; p = p->next_same_value) + if (exp_equiv_p (p->exp, x, 1, false)) + return p; + } + /* Put an element for X into the right hash bucket. */ elt = free_element_chain; diff --git a/gcc/testsuite/gcc.target/i386/pr103404.c b/gcc/testsuite/gcc.target/i386/pr103404.c new file mode 100644 index 0000000000000000000000000000000000000000..66f33645301db09503fc0977fd0f061a19e56ea5 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr103404.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-Og -fcse-follow-jumps -fno-dce -fno-early-inlining -fgcse -fharden-conditional-branches -frerun-cse-after-loop -fno-tree-ccp -mavx5124fmaps -std=c99 -w" } */ + +typedef unsigned __attribute__((__vector_size__ (4))) U; +typedef unsigned __attribute__((__vector_size__ (16))) V; +typedef unsigned __attribute__((__vector_size__ (64))) W; + +int x, y; + +V v; +W w; + +inline +int bar (U a) +{ + a |= x; + W k = + __builtin_shufflevector (v, 5 / a, + 2, 4, 0, 2, 4, 1, 0, 1, + 1, 2, 1, 3, 0, 4, 4, 0); + w = k; + y = 0; +} + +int +foo () +{ + bar ((U){0xffffffff}); + for (unsigned i; i < sizeof (foo);) + ; +} +