[Bug c/87944] Wrong code with LRA pushing stack local variable
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87944 Stefan "Bebbo" Franke changed: What|Removed |Added CC| |stefan at franke dot ms --- Comment #4 from Stefan "Bebbo" Franke --- the problem resides in lra-eliminations.c. It starts in void eliminate_regs_in_insn where a simple plus bypasses the stack offset handling: /* If we have a nonzero offset, and the source is already a simple REG, the following transformation would increase the cost of the insn by replacing a simple REG with (plus (reg sp) CST). So try only when we already had a PLUS before. */ if (known_eq (offset, 0) || plus_src) because lra_get_insn_recog_data (insn)->sp_offset is not considered. With the m68k architecture plus using lra you get this problem plus some similar ones, all related to arg / frame / stack pointer conversion with incorrect offsets. I fixed it locally with few more changes in lra-elimintaions.c
[Bug rtl-optimization/70961] Regrename ignores preferred_rename_class
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70961 Stefan "Bebbo" Franke changed: What|Removed |Added CC| |stefan at franke dot ms --- Comment #6 from Stefan "Bebbo" Franke --- Simply remove the outer loop and iterate only once: has_preferred_class = (preferred_class != NO_REGS); for (new_reg = 0; new_reg < FIRST_PSEUDO_REGISTER; new_reg++) { if (has_preferred_class && !TEST_HARD_REG_BIT(reg_class_contents[preferred_class], new_reg)) continue; if (!check_new_reg_p (old_reg, new_reg, this_head, *unavailable)) continue; if (!best_rename) return new_reg; /* In the first pass, we force the renaming of registers that don't belong to PREFERRED_CLASS to registers that do, even though the latters were used not very long ago. Also use a register if no best_new_reg was found till now */ if ((tick[best_new_reg] > tick[new_reg] || (old_reg == best_new_reg && new_reg < old_reg))) best_new_reg = new_reg; } The last "if" is my experimental version. I am also testing (with m68k) an extended preferred_rename_class2 method, which uses the register to return a maybe better class: preferred_class = (enum reg_class) targetm.preferred_rename_class2 ( super_class, old_reg); And yes, the code is smaller and faster.
[Bug rtl-optimization/80126] New: df_ref_change_reg_with_loc does not update hard_regs_live_count
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80126 Bug ID: 80126 Summary: df_ref_change_reg_with_loc does not update hard_regs_live_count Product: gcc Version: 6.3.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: rtl-optimization Assignee: unassigned at gcc dot gnu.org Reporter: stefan at franke dot ms Target Milestone: --- The method static void df_ref_change_reg_with_loc_1 (struct df_reg_info *old_df, struct df_reg_info *new_df, unsigned int new_regno, rtx loc) does not update the hard_regs_live_count. Old: ... struct df_insn_info *insn_info = DF_REF_INSN_INFO (the_ref); DF_REF_REGNO (the_ref) = new_regno; ... Fixed: ... struct df_insn_info *insn_info = DF_REF_INSN_INFO (the_ref); if (DF_REF_FLAGS_IS_SET(the_ref, DF_HARD_REG_LIVE)) { --df->hard_regs_live_count[DF_REF_REGNO(the_ref)]; ++df->hard_regs_live_count[new_regno]; } DF_REF_REGNO (the_ref) = new_regno; ...
[Bug rtl-optimization/80127] New: regrename_do_replace does not update the df refs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80127 Bug ID: 80127 Summary: regrename_do_replace does not update the df refs Product: gcc Version: 6.3.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: rtl-optimization Assignee: unassigned at gcc dot gnu.org Reporter: stefan at franke dot ms Target Milestone: --- The method regrename_do_replace does neither update the df refs nor reset the ever_live flag. Also the passes for stack variables are scheduled to early. This leads to eliminated variables which are still pushed/popped to/from stack but are never used. Old code: bool regrename_do_replace (struct du_head *head, int regno) { ... mode = GET_MODE(*head->first->loc); head->renamed = 1; head->regno = regno; head->nregs = hard_regno_nregs[regno][mode]; return true; } My code: bool regrename_do_replace (struct du_head *head, int regno) { ... mode = GET_MODE(*head->first->loc); head->renamed = 1; head->regno = regno; head->nregs = hard_regno_nregs[regno][mode]; /* SBF: also update the current df info, move from base_regno -> regno. */ if (base_regno < FIRST_PSEUDO_REGISTER && regno < FIRST_PSEUDO_REGISTER) for (chain = head->first; chain; chain = chain->next_use) { if (DEBUG_INSN_P (chain->insn)) continue; /* undo regno patch - will be patched again */ if (REGNO (*chain->loc) == regno) SET_REGNO(*chain->loc, base_regno); df_ref_change_reg_with_loc (*chain->loc, regno); SET_REGNO(*chain->loc, regno); } /* SBF: Mark the old regno as no longer used. */ if (!df->hard_regs_live_count[base_regno]) df_set_regs_ever_live (base_regno, false); return true; } I also moved the stack creation passed after regrename: passes.def: ... NEXT_PASS (pass_regrename); NEXT_PASS (pass_cprop_hardreg); NEXT_PASS (pass_thread_prologue_and_epilogue); NEXT_PASS (pass_rtl_dse2); NEXT_PASS (pass_stack_adjustments); ... => No more push/pop for unused variables due to regrename.
[Bug tree-optimization/99364] New: Regression: loops not optimized to count to 0/-1
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99364 Bug ID: 99364 Summary: Regression: loops not optimized to count to 0/-1 Product: gcc Version: tree-ssa Status: UNCONFIRMED Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: stefan at franke dot ms Target Milestone: --- consider this simple loop: ``` void ArrayFill2(int *array, int len) { int i = 0; for(; i < len; ++i) array[i] = 50; } ``` gcc 2.93 was able to convert this into a loop counting to zero. gcc 6/7/8/9/10/11 can't do that. if you change the code above: ``` void ArrayFill2(int *array) { int i = 0; int len = 42; for(; i < len; ++i) array[i] = 50; } ``` then it works and you get this after ivcanon: ``` int i; unsigned int i.0_4; unsigned int _5; int * _7; unsigned int ivtmp_15; unsigned int ivtmp_16; : : # i_13 = PHI # ivtmp_16 = PHI i.0_4 = (unsigned int) i_13; _5 = i.0_4 * 4; _7 = array_6(D) + _5; *_7 = 50; i_9 = i_13 + 1; ivtmp_15 = ivtmp_16 - 1; if (ivtmp_15 != 0) goto ; else goto ; : goto ; : return; ``` so the expected result for the version above, with len as parameter would be something like this where the constant loop count is replaced by len-1: ``` int i; unsigned int i.0_4; unsigned int _5; int * _7; int ivtmp_14 unsigned int ivtmp_15; unsigned int ivtmp_16; : ivtmp_14 = len_4(D) - 1; : # i_13 = PHI # ivtmp_16 = PHI i.0_4 = (unsigned int) i_13; _5 = i.0_4 * 4; _7 = array_6(D) + _5; *_7 = 50; i_9 = i_13 + 1; ivtmp_15 = ivtmp_16 - 1; if (ivtmp_15 != 0) goto ; else goto ; : goto ; : return; ``` To handle this tree-ssa-loop-ivcanon must be able to handle no only const_int loop limits but also a const loop limit provided in a variable.