The following patch fixes
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59858
The patch was successfully bootstrapped and tested on x86/x86-64.
Committed as rev. 206897.
2014-01-21 Vladimir Makarov
PR rtl-optimization/59858
* gcc.target/arm/pr59858.c: New.
2014-01-21 Vladimir Makarov
PR rtl-optimization/59858
* gcc.target/arm/pr59858.c: New.
Index: lra-constraints.c
===
--- lra-constraints.c (revision 206844)
+++ lra-constraints.c (working copy)
@@ -688,9 +688,10 @@ operands_match_p (rtx x, rtx y, int y_ha
/* True if C is a non-empty register class that has too few registers
to be safely used as a reload target class. */
-#define SMALL_REGISTER_CLASS_P(C) \
- (reg_class_size [(C)] == 1 \
- || (reg_class_size [(C)] >= 1 && targetm.class_likely_spilled_p (C)))
+#define SMALL_REGISTER_CLASS_P(C) \
+ (ira_class_hard_regs_num [(C)] == 1 \
+ || (ira_class_hard_regs_num [(C)] >= 1 \
+ && targetm.class_likely_spilled_p (C)))
/* If REG is a reload pseudo, try to make its class satisfying CL. */
static void
@@ -2113,17 +2114,25 @@ process_alt_operands (int only_alternati
}
/* If the operand is dying, has a matching constraint,
and satisfies constraints of the matched operand
- which failed to satisfy the own constraints, we do
- not need to generate a reload insn for this
- operand. */
- if (!(this_alternative_matches >= 0
- && !curr_alt_win[this_alternative_matches]
- && REG_P (op)
- && find_regno_note (curr_insn, REG_DEAD, REGNO (op))
- && (hard_regno[nop] >= 0
- ? in_hard_reg_set_p (this_alternative_set,
- mode, hard_regno[nop])
- : in_class_p (op, this_alternative, NULL
+ which failed to satisfy the own constraints, probably
+ the reload for this operand will be gone. */
+ if (this_alternative_matches >= 0
+ && !curr_alt_win[this_alternative_matches]
+ && REG_P (op)
+ && find_regno_note (curr_insn, REG_DEAD, REGNO (op))
+ && (hard_regno[nop] >= 0
+ ? in_hard_reg_set_p (this_alternative_set,
+ mode, hard_regno[nop])
+ : in_class_p (op, this_alternative, NULL)))
+ {
+ if (lra_dump_file != NULL)
+ fprintf
+ (lra_dump_file,
+ "%d Dying matched operand reload: reject++\n",
+ nop);
+ reject++;
+ }
+ else
{
/* Strict_low_part requires to reload the register
not the sub-register. In this case we should
Index: testsuite/gcc.target/arm/pr59858.c
===
--- testsuite/gcc.target/arm/pr59858.c (revision 0)
+++ testsuite/gcc.target/arm/pr59858.c (working copy)
@@ -0,0 +1,162 @@
+/* { dg-do compile } */
+/* { dg-options "-march=armv5te -marm -mthumb-interwork -Wall -Wstrict-prototypes -Wstrict-aliasing -funsigned-char -fno-builtin -fno-asm -msoft-float -std=gnu99 -mlittle-endian -mthumb -fno-stack-protector -Os -g -feliminate-unused-debug-types -funit-at-a-time -fmerge-all-constants -fstrict-aliasing -fno-tree-loop-optimize -fno-tree-dominator-opts -fno-strength-reduce -fPIC -w" } */
+
+typedef enum {
+ REG_ENOSYS = -1,
+} reg_errcode_t;
+typedef unsigned long int bitset_word_t;
+typedef bitset_word_t bitset_t[(256 / (sizeof (bitset_word_t) * 8))];
+typedef bitset_word_t *re_bitset_ptr_t;
+typedef const bitset_word_t *re_const_bitset_ptr_t;
+typedef struct {
+ int nelem;
+ int *elems;
+} re_node_set;
+typedef enum {
+ CHARACTER = 1,
+} re_token_type_t;
+typedef struct {
+ re_token_type_t type:8;
+ unsigned int word_char:1;
+} re_token_t;
+struct re_string_t {
+ const unsigned char *raw_mbs;
+ int raw_mbs_idx;
+ int cur_idx;
+ unsigned int tip_context;
+ re_const_bitset_ptr_t word_char;
+};
+typedef struct re_string_t re_string_t;
+typedef struct re_dfa_t re_dfa_t;
+struct re_dfastate_t {
+ re_node_set nodes;
+};
+typedef struct re_dfastate_t re_dfastate_t;
+typedef struct {
+ re_dfastate_t **array;
+} state_array_t;
+typedef struct {
+ state_array_t path;
+} re_sub_match_last_t;
+typedef struct {
+ int nlasts;
+ re_sub_match_last_t **lasts;
+} re_sub_match_top_t;
+typedef struct {
+ re_string_t input;
+ const re_dfa_t *dfa;
+ int nsub_tops;
+ re_sub_match_top_t **sub_tops;
+} re_match_context_t;
+struct re_dfa_t {
+ re_token_t *nodes;
+ re_bitset_ptr_t sb_char;
+ int mb_cur_max;
+ bitset_t word_char;
+} bracket_elem_t;
+static reg_errcode_t
+re_string_reconstruct (
+ re_string_t * pstr,
+ int idx,
+ int eflags
+)
+{
+ int offset = idx - pstr->raw_mbs_idx;
+ int c = pstr->raw_mbs[pstr->raw_mbs_idx + offset - 1];
+ pstr->tip_context = ((pstr->word_char[c] & ((bitset_word_t) 1)) ? : (c));
+}
+
+static void match_ctx_clean (
+ re_match_context_t *
+);
+static int check_matching (
+);
+static re_dfastate_t *transit_state (
+);
+static int build_trtable (
+);
+re_search_internal (int eflags
+)
+{
+ reg_errcode_t err;
+ int incr;
+ int
+ match_f