From e86c0101ae59b32c3f10edcca78398cbf8848eaa Mon Sep 17 00:00:00 2001 From: Steven Bosscher Date: Thu, 24 Jan 2013 10:30:26 +0000 Subject: [PATCH] re PR inline-asm/55934 (LRA inline asm error recovery) gcc/ PR inline-asm/55934 * lra-assigns.c (assign_by_spills): Throw away the pattern of asms that have operands with impossible constraints. Add a FIXME for a speed-up opportunity. * lra-constraints.c (process_alt_operands): Verify that a class selected from constraints on asms is valid for the operand mode. (curr_insn_transform): Remove incorrect comment. testsuite/ PR inline-asm/55934 * gcc.target/i386/pr55934.c: New test. From-SVN: r195420 --- gcc/ChangeLog | 10 ++++++++++ gcc/lra-assigns.c | 20 ++++++++++++++++++++ gcc/lra-constraints.c | 20 ++++++++++++++++---- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.target/i386/pr55934.c | 11 +++++++++++ 5 files changed, 62 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/pr55934.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3bf5cf5a372..eedd4d6d8dc 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2013-01-24 Steven Bosscher + + PR inline-asm/55934 + * lra-assigns.c (assign_by_spills): Throw away the pattern of asms + that have operands with impossible constraints. + Add a FIXME for a speed-up opportunity. + * lra-constraints.c (process_alt_operands): Verify that a class + selected from constraints on asms is valid for the operand mode. + (curr_insn_transform): Remove incorrect comment. + 2013-01-23 Uros Bizjak * config/i386/i386.md (*movdf_internal_rex64): Disparage alternatives diff --git a/gcc/lra-assigns.c b/gcc/lra-assigns.c index 578bcaeda89..33666fd07b1 100644 --- a/gcc/lra-assigns.c +++ b/gcc/lra-assigns.c @@ -1240,6 +1240,23 @@ assign_by_spills (void) asm_p = true; error_for_asm (insn, "% operand has impossible constraints"); + /* Avoid further trouble with this insn. + For asm goto, instead of fixing up all the edges + just clear the template and clear input operands + (asm goto doesn't have any output operands). */ + if (JUMP_P (insn)) + { + rtx asm_op = extract_asm_operands (PATTERN (insn)); + ASM_OPERANDS_TEMPLATE (asm_op) = ggc_strdup (""); + ASM_OPERANDS_INPUT_VEC (asm_op) = rtvec_alloc (0); + ASM_OPERANDS_INPUT_CONSTRAINT_VEC (asm_op) = rtvec_alloc (0); + lra_update_insn_regno_info (insn); + } + else + { + PATTERN (insn) = gen_rtx_USE (VOIDmode, const0_rtx); + lra_set_insn_deleted (insn); + } } } lra_assert (asm_p); @@ -1263,6 +1280,9 @@ assign_by_spills (void) bitmap_ior_into (&changed_insns, &lra_reg_info[sorted_pseudos[i]].insn_bitmap); } + + /* FIXME: Look up the changed insns in the cached LRA insn data using + an EXECUTE_IF_SET_IN_BITMAP over changed_insns. */ FOR_EACH_BB (bb) FOR_BB_INSNS (bb, insn) if (bitmap_bit_p (&changed_insns, INSN_UID (insn))) diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c index 01c8cf143cf..03728b78f42 100644 --- a/gcc/lra-constraints.c +++ b/gcc/lra-constraints.c @@ -1847,11 +1847,27 @@ process_alt_operands (int only_alternative) int const_to_mem = 0; bool no_regs_p; + /* If this alternative asks for a specific reg class, see if there + is at least one allocatable register in that class. */ no_regs_p = (this_alternative == NO_REGS || (hard_reg_set_subset_p (reg_class_contents[this_alternative], lra_no_alloc_regs))); + + /* For asms, verify that the class for this alternative is possible + for the mode that is specified. */ + if (!no_regs_p && REG_P (op) && INSN_CODE (curr_insn) < 0) + { + int i; + for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) + if (HARD_REGNO_MODE_OK (i, mode) + && in_hard_reg_set_p (reg_class_contents[this_alternative], mode, i)) + break; + if (i == FIRST_PSEUDO_REGISTER) + winreg = false; + } + /* If this operand accepts a register, and if the register class has at least one allocatable register, then this operand can be reloaded. */ @@ -2742,10 +2758,6 @@ curr_insn_transform (void) swap_operands (commutative); } - /* The operands don't meet the constraints. goal_alt describes the - alternative that we could reach by reloading the fewest operands. - Reload so as to fit it. */ - if (! alt_p && ! sec_mem_p) { /* No alternative works with reloads?? */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 8bcbca513a2..9dda502e093 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2013-01-24 Steven Bosscher + + PR inline-asm/55934 + * gcc.target/i386/pr55934.c: New test. + 2013-01-23 Janus Weil PR fortran/56081 diff --git a/gcc/testsuite/gcc.target/i386/pr55934.c b/gcc/testsuite/gcc.target/i386/pr55934.c new file mode 100644 index 00000000000..ea489559c93 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr55934.c @@ -0,0 +1,11 @@ +/* PR inline-asm/55934 */ +/* { dg-do compile } */ +/* { dg-require-effective-target sse } */ +/* { dg-options "-std=c99 -msse" } */ +_Complex float +foo (void) +{ + _Complex float x; + __asm ("" : "=x" (x)); /* { dg-error "inconsistent .* constraint" } */ + return x; +}