From: Eric Botcazou Date: Tue, 1 Mar 2016 22:36:15 +0000 (+0000) Subject: re PR rtl-optimization/70007 (wrong code with -mbmi2) X-Git-Tag: releases/gcc-4.9.4~296 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3203c1c6ee1c911f06d6fda89c39b78d9ef23fe2;p=thirdparty%2Fgcc.git re PR rtl-optimization/70007 (wrong code with -mbmi2) PR rtl-optimization/70007 * gcse.c (compute_ld_motion_mems): Tidy up and also invalidate memory references present in REG_EQUAL notes attached to non-SET patterns. From-SVN: r233869 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b8bd435ece37..5b8275475006 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2016-03-01 Eric Botcazou + + PR rtl-optimization/70007 + * gcse.c (compute_ld_motion_mems): Tidy up and also invalidate memory + references present in REG_EQUAL notes attached to non-SET patterns. + 2016-02-17 Bill Schmidt Backport from mainline diff --git a/gcc/gcse.c b/gcc/gcse.c index b852aa1bf22f..e59151621ae6 100644 --- a/gcc/gcse.c +++ b/gcc/gcse.c @@ -3958,10 +3958,8 @@ compute_ld_motion_mems (void) { rtx src = SET_SRC (PATTERN (insn)); rtx dest = SET_DEST (PATTERN (insn)); - rtx note = find_reg_equal_equiv_note (insn); - rtx src_eq; - /* Check for a simple LOAD... */ + /* Check for a simple load. */ if (MEM_P (src) && simple_mem (src)) { ptr = ldst_entry (src); @@ -3976,12 +3974,11 @@ compute_ld_motion_mems (void) invalidate_any_buried_refs (src); } - if (note != 0 && REG_NOTE_KIND (note) == REG_EQUAL) - src_eq = XEXP (note, 0); - else - src_eq = NULL_RTX; - - if (src_eq != NULL_RTX + /* Check for a simple load through a REG_EQUAL note. */ + rtx note = find_reg_equal_equiv_note (insn), src_eq; + if (note + && REG_NOTE_KIND (note) == REG_EQUAL + && (src_eq = XEXP (note, 0)) && !(MEM_P (src_eq) && simple_mem (src_eq))) invalidate_any_buried_refs (src_eq); @@ -4004,7 +4001,17 @@ compute_ld_motion_mems (void) } } else - invalidate_any_buried_refs (PATTERN (insn)); + { + /* Invalidate all MEMs in the pattern and... */ + invalidate_any_buried_refs (PATTERN (insn)); + + /* ...in REG_EQUAL notes for PARALLELs with single SET. */ + rtx note = find_reg_equal_equiv_note (insn), src_eq; + if (note + && REG_NOTE_KIND (note) == REG_EQUAL + && (src_eq = XEXP (note, 0))) + invalidate_any_buried_refs (src_eq); + } } } } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index cfdf7c3d4ad0..98da2eddf5fa 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2016-03-01 Eric Botcazou + + * gcc.target/i386/pr70007.c: New test. + 2016-02-29 Harald Anlauf PR fortran/60126 diff --git a/gcc/testsuite/gcc.target/i386/pr70007.c b/gcc/testsuite/gcc.target/i386/pr70007.c new file mode 100644 index 000000000000..6b457eecb302 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr70007.c @@ -0,0 +1,29 @@ +/* PR rtl-optimization/70007 */ +/* { dg-do run } */ +/* { dg-options "-O -fgcse -mbmi2" } */ +/* { dg-require-effective-target bmi2 } */ + +typedef unsigned short v32u16 __attribute__ ((vector_size (32))); +typedef unsigned long long v32u64 __attribute__ ((vector_size (32))); +typedef unsigned __int128 u128; +typedef unsigned __int128 v32u128 __attribute__ ((vector_size (32))); + +u128 +foo (v32u16 v32u16_0, v32u64 v32u64_0, v32u64 v32u64_1) +{ + do { + v32u16_0[13] |= v32u64_1[3] = (v32u64_1[3] >> 19) | (v32u64_1[3] << 45); + v32u64_1 %= ~v32u64_1; + v32u64_0 *= (v32u64) v32u16_0; + } while (v32u64_0[0]); + return v32u64_1[3]; +} + +int +main (void) +{ + u128 x = foo((v32u16){~0xba31, 0x47c6}, (v32u64){64}, (v32u64){0, 0x8b217e2514d23242, 0xac569b6dff9f82, 0x9d4cffe03c139c}); + if (x != 0x3c74da5ca328d09) + __builtin_abort(); + return 0; +}