From 6c4d60f80aae979c4c317e5274babd404429f4cf Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Fri, 23 Jan 2015 20:55:16 +0100 Subject: [PATCH] re PR rtl-optimization/63637 (CSE on x86 asm()-s no longer working due to PR/60663 fix) PR rtl-optimization/63637 PR rtl-optimization/60663 * cse.c (merge_equiv_classes): Set new_elt->cost to MAX_COST if elt->cost is MAX_COST for ASM_OPERANDS. (find_sets_in_insn): Fix up comment typo. (cse_insn): Don't set src_volatile for all non-volatile ASM_OPERANDS in PARALLELs, but just those with multiple outputs or with "memory" clobber. Set elt->cost to MAX_COST for ASM_OPERANDS in PARALLEL. Set src_elt->cost to MAX_COST if new_src is ASM_OPERANDS and elt->cost is MAX_COST. * gcc.dg/pr63637-1.c: New test. * gcc.dg/pr63637-2.c: New test. * gcc.dg/pr63637-3.c: New test. * gcc.dg/pr63637-4.c: New test. * gcc.dg/pr63637-5.c: New test. * gcc.dg/pr63637-6.c: New test. * gcc.target/i386/pr63637-1.c: New test. * gcc.target/i386/pr63637-2.c: New test. * gcc.target/i386/pr63637-3.c: New test. * gcc.target/i386/pr63637-4.c: New test. * gcc.target/i386/pr63637-5.c: New test. * gcc.target/i386/pr63637-6.c: New test. From-SVN: r220059 --- gcc/ChangeLog | 13 ++++++++ gcc/cse.c | 40 +++++++++++++++++++---- gcc/testsuite/ChangeLog | 17 ++++++++++ gcc/testsuite/gcc.dg/pr63637-1.c | 15 +++++++++ gcc/testsuite/gcc.dg/pr63637-2.c | 15 +++++++++ gcc/testsuite/gcc.dg/pr63637-3.c | 15 +++++++++ gcc/testsuite/gcc.dg/pr63637-4.c | 15 +++++++++ gcc/testsuite/gcc.dg/pr63637-5.c | 15 +++++++++ gcc/testsuite/gcc.dg/pr63637-6.c | 15 +++++++++ gcc/testsuite/gcc.target/i386/pr63637-1.c | 15 +++++++++ gcc/testsuite/gcc.target/i386/pr63637-2.c | 15 +++++++++ gcc/testsuite/gcc.target/i386/pr63637-3.c | 15 +++++++++ gcc/testsuite/gcc.target/i386/pr63637-4.c | 15 +++++++++ gcc/testsuite/gcc.target/i386/pr63637-5.c | 15 +++++++++ gcc/testsuite/gcc.target/i386/pr63637-6.c | 15 +++++++++ 15 files changed, 243 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/pr63637-1.c create mode 100644 gcc/testsuite/gcc.dg/pr63637-2.c create mode 100644 gcc/testsuite/gcc.dg/pr63637-3.c create mode 100644 gcc/testsuite/gcc.dg/pr63637-4.c create mode 100644 gcc/testsuite/gcc.dg/pr63637-5.c create mode 100644 gcc/testsuite/gcc.dg/pr63637-6.c create mode 100644 gcc/testsuite/gcc.target/i386/pr63637-1.c create mode 100644 gcc/testsuite/gcc.target/i386/pr63637-2.c create mode 100644 gcc/testsuite/gcc.target/i386/pr63637-3.c create mode 100644 gcc/testsuite/gcc.target/i386/pr63637-4.c create mode 100644 gcc/testsuite/gcc.target/i386/pr63637-5.c create mode 100644 gcc/testsuite/gcc.target/i386/pr63637-6.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 80071ddcf1c..34e8ad1e651 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +2015-01-23 Jakub Jelinek + + PR rtl-optimization/63637 + PR rtl-optimization/60663 + * cse.c (merge_equiv_classes): Set new_elt->cost to MAX_COST + if elt->cost is MAX_COST for ASM_OPERANDS. + (find_sets_in_insn): Fix up comment typo. + (cse_insn): Don't set src_volatile for all non-volatile + ASM_OPERANDS in PARALLELs, but just those with multiple outputs + or with "memory" clobber. Set elt->cost to MAX_COST + for ASM_OPERANDS in PARALLEL. Set src_elt->cost to MAX_COST + if new_src is ASM_OPERANDS and elt->cost is MAX_COST. + 2015-01-23 Uros Bizjak * config/i386/sse.md (sse2_loadld): Set attribute isa to sse2 for diff --git a/gcc/cse.c b/gcc/cse.c index 4732d81a72a..7edd9011899 100644 --- a/gcc/cse.c +++ b/gcc/cse.c @@ -1807,6 +1807,8 @@ merge_equiv_classes (struct table_elt *class1, struct table_elt *class2) } new_elt = insert (exp, class1, hash, mode); new_elt->in_memory = hash_arg_in_memory; + if (GET_CODE (exp) == ASM_OPERANDS && elt->cost == MAX_COST) + new_elt->cost = MAX_COST; } } } @@ -4275,7 +4277,7 @@ find_sets_in_insn (rtx_insn *insn, struct set **psets) { int i, lim = XVECLEN (x, 0); - /* Go over the epressions of the PARALLEL in forward order, to + /* Go over the expressions of the PARALLEL in forward order, to put them in the same order in the SETS array. */ for (i = 0; i < lim; i++) { @@ -4651,12 +4653,27 @@ cse_insn (rtx_insn *insn) && REGNO (dest) >= FIRST_PSEUDO_REGISTER) sets[i].src_volatile = 1; - /* Also do not record result of a non-volatile inline asm with - more than one result or with clobbers, we do not want CSE to - break the inline asm apart. */ else if (GET_CODE (src) == ASM_OPERANDS && GET_CODE (x) == PARALLEL) - sets[i].src_volatile = 1; + { + /* Do not record result of a non-volatile inline asm with + more than one result. */ + if (n_sets > 1) + sets[i].src_volatile = 1; + + int j, lim = XVECLEN (x, 0); + for (j = 0; j < lim; j++) + { + rtx y = XVECEXP (x, 0, j); + /* And do not record result of a non-volatile inline asm + with "memory" clobber. */ + if (GET_CODE (y) == CLOBBER && MEM_P (XEXP (y, 0))) + { + sets[i].src_volatile = 1; + break; + } + } + } #if 0 /* It is no longer clear why we used to do this, but it doesn't @@ -5247,8 +5264,8 @@ cse_insn (rtx_insn *insn) ; /* Look for a substitution that makes a valid insn. */ - else if (validate_unshare_change - (insn, &SET_SRC (sets[i].rtl), trial, 0)) + else if (validate_unshare_change (insn, &SET_SRC (sets[i].rtl), + trial, 0)) { rtx new_rtx = canon_reg (SET_SRC (sets[i].rtl), insn); @@ -5610,6 +5627,12 @@ cse_insn (rtx_insn *insn) } elt = insert (src, classp, sets[i].src_hash, mode); elt->in_memory = sets[i].src_in_memory; + /* If inline asm has any clobbers, ensure we only reuse + existing inline asms and never try to put the ASM_OPERANDS + into an insn that isn't inline asm. */ + if (GET_CODE (src) == ASM_OPERANDS + && GET_CODE (x) == PARALLEL) + elt->cost = MAX_COST; sets[i].src_elt = classp = elt; } if (sets[i].src_const && sets[i].src_const_elt == 0 @@ -5923,6 +5946,9 @@ cse_insn (rtx_insn *insn) } src_elt = insert (new_src, classp, src_hash, new_mode); src_elt->in_memory = elt->in_memory; + if (GET_CODE (new_src) == ASM_OPERANDS + && elt->cost == MAX_COST) + src_elt->cost = MAX_COST; } else if (classp && classp != src_elt->first_same_value) /* Show that two things that we've seen before are diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 5b11856aacd..39a1741f745 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,20 @@ +2015-01-23 Jakub Jelinek + + PR rtl-optimization/63637 + PR rtl-optimization/60663 + * gcc.dg/pr63637-1.c: New test. + * gcc.dg/pr63637-2.c: New test. + * gcc.dg/pr63637-3.c: New test. + * gcc.dg/pr63637-4.c: New test. + * gcc.dg/pr63637-5.c: New test. + * gcc.dg/pr63637-6.c: New test. + * gcc.target/i386/pr63637-1.c: New test. + * gcc.target/i386/pr63637-2.c: New test. + * gcc.target/i386/pr63637-3.c: New test. + * gcc.target/i386/pr63637-4.c: New test. + * gcc.target/i386/pr63637-5.c: New test. + * gcc.target/i386/pr63637-6.c: New test. + 2015-01-23 Richard Biener PR testsuite/63439 diff --git a/gcc/testsuite/gcc.dg/pr63637-1.c b/gcc/testsuite/gcc.dg/pr63637-1.c new file mode 100644 index 00000000000..7a716f98c5f --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr63637-1.c @@ -0,0 +1,15 @@ +/* PR rtl-optimization/63637 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +int +foo (void) +{ + int a, b, c; + asm ("# Magic instruction" : "=r" (a)); + asm ("# Magic instruction" : "=r" (b)); + asm ("# Magic instruction" : "=r" (c)); + return a + b + c; +} + +/* { dg-final { scan-assembler-times "# Magic instruction" 1 } } */ diff --git a/gcc/testsuite/gcc.dg/pr63637-2.c b/gcc/testsuite/gcc.dg/pr63637-2.c new file mode 100644 index 00000000000..44e9d7c96ec --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr63637-2.c @@ -0,0 +1,15 @@ +/* PR rtl-optimization/63637 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +int +foo (void) +{ + int a, b, c; + asm ("# Magic instruction" : "=r" (a) : "r" (0)); + asm ("# Magic instruction" : "=r" (b) : "r" (0)); + asm ("# Magic instruction" : "=r" (c) : "r" (0)); + return a + b + c; +} + +/* { dg-final { scan-assembler-times "# Magic instruction" 1 } } */ diff --git a/gcc/testsuite/gcc.dg/pr63637-3.c b/gcc/testsuite/gcc.dg/pr63637-3.c new file mode 100644 index 00000000000..51a2ff707e4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr63637-3.c @@ -0,0 +1,15 @@ +/* PR rtl-optimization/63637 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +int +foo (void) +{ + int a, b, c; + asm ("# Magic instruction" : "=r" (a) : : "memory"); + asm ("# Magic instruction" : "=r" (b) : : "memory"); + asm ("# Magic instruction" : "=r" (c) : : "memory"); + return a + b + c; +} + +/* { dg-final { scan-assembler-times "# Magic instruction" 3 } } */ diff --git a/gcc/testsuite/gcc.dg/pr63637-4.c b/gcc/testsuite/gcc.dg/pr63637-4.c new file mode 100644 index 00000000000..1a914830c1e --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr63637-4.c @@ -0,0 +1,15 @@ +/* PR rtl-optimization/63637 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +int +foo (void) +{ + int a, b, c; + asm ("# Magic instruction" : "=r" (a) : "r" (0) : "memory"); + asm ("# Magic instruction" : "=r" (b) : "r" (0) : "memory"); + asm ("# Magic instruction" : "=r" (c) : "r" (0) : "memory"); + return a + b + c; +} + +/* { dg-final { scan-assembler-times "# Magic instruction" 3 } } */ diff --git a/gcc/testsuite/gcc.dg/pr63637-5.c b/gcc/testsuite/gcc.dg/pr63637-5.c new file mode 100644 index 00000000000..fce8593adb4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr63637-5.c @@ -0,0 +1,15 @@ +/* PR rtl-optimization/63637 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +int +foo (void) +{ + int a, b, c, d, e, f; + asm ("# Magic instruction" : "=r" (a), "=r" (d)); + asm ("# Magic instruction" : "=r" (b), "=r" (e)); + asm ("# Magic instruction" : "=r" (c), "=r" (f)); + return a + b + c; +} + +/* { dg-final { scan-assembler-times "# Magic instruction" 3 } } */ diff --git a/gcc/testsuite/gcc.dg/pr63637-6.c b/gcc/testsuite/gcc.dg/pr63637-6.c new file mode 100644 index 00000000000..1b997c43049 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr63637-6.c @@ -0,0 +1,15 @@ +/* PR rtl-optimization/63637 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +int +foo (void) +{ + int a, b, c, d, e, f; + asm ("# Magic instruction" : "=r" (a), "=r" (d) : "r" (0)); + asm ("# Magic instruction" : "=r" (b), "=r" (e) : "r" (0)); + asm ("# Magic instruction" : "=r" (c), "=r" (f) : "r" (0)); + return a + b + c; +} + +/* { dg-final { scan-assembler-times "# Magic instruction" 3 } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr63637-1.c b/gcc/testsuite/gcc.target/i386/pr63637-1.c new file mode 100644 index 00000000000..9cc9750dd13 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr63637-1.c @@ -0,0 +1,15 @@ +/* PR rtl-optimization/63637 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +int +foo (void) +{ + int a, b, c; + asm ("# Magic instruction" : "=r" (a) : : "eax"); + asm ("# Magic instruction" : "=r" (b) : : "edx"); + asm ("# Magic instruction" : "=r" (c) : : "ecx"); + return a + b + c; +} + +/* { dg-final { scan-assembler-times "# Magic instruction" 1 } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr63637-2.c b/gcc/testsuite/gcc.target/i386/pr63637-2.c new file mode 100644 index 00000000000..fc549000e8e --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr63637-2.c @@ -0,0 +1,15 @@ +/* PR rtl-optimization/63637 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +int +foo (void) +{ + int a, b, c; + asm ("# Magic instruction" : "=r" (a) : "r" (0) : "eax"); + asm ("# Magic instruction" : "=r" (b) : "r" (0) : "edx"); + asm ("# Magic instruction" : "=r" (c) : "r" (0) : "ecx"); + return a + b + c; +} + +/* { dg-final { scan-assembler-times "# Magic instruction" 1 } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr63637-3.c b/gcc/testsuite/gcc.target/i386/pr63637-3.c new file mode 100644 index 00000000000..4b631ce0f81 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr63637-3.c @@ -0,0 +1,15 @@ +/* PR rtl-optimization/63637 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +int +foo (void) +{ + int a, b, c; + asm ("# Magic instruction" : "=r" (a) : : "eax", "memory"); + asm ("# Magic instruction" : "=r" (b) : : "edx", "memory"); + asm ("# Magic instruction" : "=r" (c) : : "ecx", "memory"); + return a + b + c; +} + +/* { dg-final { scan-assembler-times "# Magic instruction" 3 } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr63637-4.c b/gcc/testsuite/gcc.target/i386/pr63637-4.c new file mode 100644 index 00000000000..7b36690bbcf --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr63637-4.c @@ -0,0 +1,15 @@ +/* PR rtl-optimization/63637 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +int +foo (void) +{ + int a, b, c; + asm ("# Magic instruction" : "=r" (a) : "r" (0) : "eax", "memory"); + asm ("# Magic instruction" : "=r" (b) : "r" (0) : "edx", "memory"); + asm ("# Magic instruction" : "=r" (c) : "r" (0) : "ecx", "memory"); + return a + b + c; +} + +/* { dg-final { scan-assembler-times "# Magic instruction" 3 } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr63637-5.c b/gcc/testsuite/gcc.target/i386/pr63637-5.c new file mode 100644 index 00000000000..f0c79b76d0a --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr63637-5.c @@ -0,0 +1,15 @@ +/* PR rtl-optimization/63637 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +int +foo (void) +{ + int a, b, c, d, e, f; + asm ("# Magic instruction" : "=r" (a), "=r" (d) : : "eax"); + asm ("# Magic instruction" : "=r" (b), "=r" (e) : : "edx"); + asm ("# Magic instruction" : "=r" (c), "=r" (f) : : "ecx"); + return a + b + c; +} + +/* { dg-final { scan-assembler-times "# Magic instruction" 3 } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr63637-6.c b/gcc/testsuite/gcc.target/i386/pr63637-6.c new file mode 100644 index 00000000000..4b0b3ba5f4b --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr63637-6.c @@ -0,0 +1,15 @@ +/* PR rtl-optimization/63637 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +int +foo (void) +{ + int a, b, c, d, e, f; + asm ("# Magic instruction" : "=r" (a), "=r" (d) : "r" (0) : "eax"); + asm ("# Magic instruction" : "=r" (b), "=r" (e) : "r" (0) : "edx"); + asm ("# Magic instruction" : "=r" (c), "=r" (f) : "r" (0) : "ecx"); + return a + b + c; +} + +/* { dg-final { scan-assembler-times "# Magic instruction" 3 } } */ -- 2.30.2