HI, I'm trying to port a new 32bit target to GCC 4.8.0 with LRA enabled
There is an error case which generates following RTL (insn 536 267 643 3 (set (reg/f:SI 0 $r0 [477]) <== r477 assign to r0 (plus:SI (reg/f:SI 31 $sp) (const_int 112 [0x70]))) test2.c:95 64 {*addsi3} (nil)) (insn 643 536 537 3 (set (reg/f:SI 0 $r0 [565]) <== r565 assign to r0, and corrupt the usage of r477 (reg/f:SI 31 $sp)) test2.c:95 44 {*movsi} (nil)) (insn 537 643 538 3 (set (reg/v:SI 13 $r13 [orig:61 i14 ] [61]) (mem/c:SI (plus:SI (reg/f:SI 0 $r0 [565]) <== use r565 (const_int 136 [0x88])) [5 %sfp+24 S4 A32])) test2.c:95 39 {*load_si} (expr_list:REG_DEAD (reg/f:SI 0 $r0 [565]) (nil))) ... (insn 539 540 270 3 (set (reg:SI 0 $r0 [479]) (plus:SI (reg/f:SI 0 $r0 [477]) (reg:SI 5 $r5 [480]))) test2.c:95 62 {*add_16bit} (expr_list:REG_DEAD (reg:SI 5 $r5 [480]) (expr_list:REG_DEAD (reg/f:SI 0 $r0 [477]) <== use r477 which should be $sp +112 Note that the live ranges of r477 and r565 are overlapped but assigned same register $r0. (r31 is stack pointer) By tracing LRA process, I noticed that when r477 is created, the lra_reg_info[r477].val = lra_reg_info[r31] due to (set r477 r31). But after lra_eliminate(), the stack offset changes and r477 is equal to r31+112 instead. In next lra-iteration round, r565 is created, and r565 = r31. In that case, register content of r477 should treat as not equal to r565 due to eliminate offset have been changed. Otherwise, r565 and r477 may assign to same hard register. To recognize that, I record the eliminate offset when the pseudo register have been created. Register content are the same only when lra_reg_info[].val and lra_reg_info[].offset are equal. gcc/lra-assigns.c | 6 ++++-- gcc/lra-int.h | 2 ++ gcc/lra.c | 12 +++++++++++- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/gcc/lra-assigns.c b/gcc/lra-assigns.c index b204513..daf0aa9 100644 --- a/gcc/lra-assigns.c +++ b/gcc/lra-assigns.c @@ -448,7 +448,7 @@ find_hard_regno_for (int regno, int *cost, int try_only_hard_regno) int hr, conflict_hr, nregs; enum machine_mode biggest_mode; unsigned int k, conflict_regno; - int val, biggest_nregs, nregs_diff; + int offset, val, biggest_nregs, nregs_diff; enum reg_class rclass; bitmap_iterator bi; bool *rclass_intersect_p; @@ -508,9 +508,11 @@ find_hard_regno_for (int regno, int *cost, int try_only_hard_regno) #endif sparseset_clear_bit (conflict_reload_and_inheritance_pseudos, regno); val = lra_reg_info[regno].val; + offset = lra_reg_info[regno].offset; CLEAR_HARD_REG_SET (impossible_start_hard_regs); EXECUTE_IF_SET_IN_SPARSESET (live_range_hard_reg_pseudos, conflict_regno) - if (val == lra_reg_info[conflict_regno].val) + if ((val == lra_reg_info[conflict_regno].val) + && (offset == lra_reg_info[conflict_regno].offset)) { conflict_hr = live_pseudos_reg_renumber[conflict_regno]; nregs = (hard_regno_nregs[conflict_hr] diff --git a/gcc/lra-int.h b/gcc/lra-int.h index 98f2ff7..8ae4eb0 100644 --- a/gcc/lra-int.h +++ b/gcc/lra-int.h @@ -116,6 +116,8 @@ struct lra_reg /* Value holding by register. If the pseudos have the same value they do not conflict. */ int val; + /* Eliminate offset of the pseduo have been created. */ + int offset; /* These members are set up in lra-lives.c and updated in lra-coalesce.c. */ /* The biggest size mode in which each pseudo reg is referred in diff --git a/gcc/lra.c b/gcc/lra.c index 9df24b5..69962be 100644 --- a/gcc/lra.c +++ b/gcc/lra.c @@ -194,7 +194,17 @@ lra_create_new_reg (enum machine_mode md_mode, rtx original, new_reg = lra_create_new_reg_with_unique_value (md_mode, original, rclass, title); if (original != NULL_RTX && REG_P (original)) - lra_reg_info[REGNO (new_reg)].val = lra_reg_info[REGNO (original)].val; + { + lra_reg_info[REGNO (new_reg)].val = lra_reg_info[REGNO (original)].val; + + rtx x = lra_eliminate_regs (original, VOIDmode, NULL_RTX); + + if (GET_CODE (x) == PLUS + && GET_CODE (XEXP (x, 1)) == CONST_INT) + lra_reg_info[REGNO (new_reg)].offset = INTVAL (XEXP (x, 1)); + else + lra_reg_info[REGNO (new_reg)].offset = 0; + } return new_reg; } -- 1.7.9.5 Comments? Thanks Best regards, Shiva