[PR98777] LRA: Use preliminary created pseudo for in LRA elimination subpass LRA did not extend ira_reg_equiv after generation of a pseudo in eliminate_regs_in_insn which might results in LRA crash. It is better not to extend ira_reg_equiv but to use preliminary generated pseudo. The patch implements it. gcc/ChangeLog: PR rtl-optimization/98777 * lra-int.h (lra_pmode_pseudo): New extern. * lra.c (lra_pmode_pseudo): New global. (lra): Set it up. * lra-eliminations.c (eliminate_regs_in_insn): Use it. gcc/testsuite/ChangeLog: PR rtl-optimization/98777 * gcc.target/riscv/pr98777.c: New. diff --git a/gcc/lra-eliminations.c b/gcc/lra-eliminations.c index 5b9717574ed..c97f9ca4c68 100644 --- a/gcc/lra-eliminations.c +++ b/gcc/lra-eliminations.c @@ -1059,7 +1059,7 @@ eliminate_regs_in_insn (rtx_insn *insn, bool replace_p, bool first_p, && REGNO (reg1) < FIRST_PSEUDO_REGISTER && REGNO (reg2) >= FIRST_PSEUDO_REGISTER && GET_MODE (reg1) == Pmode - && !have_addptr3_insn (gen_reg_rtx (Pmode), reg1, + && !have_addptr3_insn (lra_pmode_pseudo, reg1, XEXP (XEXP (SET_SRC (set), 0), 1))) { XEXP (XEXP (SET_SRC (set), 0), 0) = op2; diff --git a/gcc/lra-int.h b/gcc/lra-int.h index 1b8f7b6ae61..4dadccc79f4 100644 --- a/gcc/lra-int.h +++ b/gcc/lra-int.h @@ -324,6 +324,7 @@ extern lra_copy_t lra_get_copy (int); extern int lra_new_regno_start; extern int lra_constraint_new_regno_start; extern int lra_bad_spill_regno_start; +extern rtx lra_pmode_pseudo; extern bitmap_head lra_inheritance_pseudos; extern bitmap_head lra_split_regs; extern bitmap_head lra_subreg_reload_pseudos; diff --git a/gcc/lra.c b/gcc/lra.c index aa49de6f154..5a4b6638913 100644 --- a/gcc/lra.c +++ b/gcc/lra.c @@ -2192,6 +2192,9 @@ int lra_constraint_new_regno_start; it is possible. */ int lra_bad_spill_regno_start; +/* A pseudo of Pmode. */ +rtx lra_pmode_pseudo; + /* Inheritance pseudo regnos before the new spill pass. */ bitmap_head lra_inheritance_pseudos; @@ -2255,6 +2258,7 @@ lra (FILE *f) lra_dump_file = f; lra_asm_error_p = false; + lra_pmode_pseudo = gen_reg_rtx (Pmode); timevar_push (TV_LRA); diff --git a/gcc/testsuite/gcc.target/riscv/pr98777.c b/gcc/testsuite/gcc.target/riscv/pr98777.c new file mode 100644 index 00000000000..ea2c2f9ca64 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/pr98777.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-fstrict-aliasing -O" } */ + +typedef struct { + _Complex e; + _Complex f; + _Complex g; + _Complex h; + _Complex i; + _Complex j; + _Complex k; + _Complex l; + _Complex m; + _Complex n; + _Complex o; + _Complex p; +} Scl16; + +Scl16 g1sScl16, g2sScl16, g3sScl16, g4sScl16, g5sScl16, g6sScl16, g7sScl16, + g8sScl16, g9sScl16, g10sScl16, g11sScl16, g12sScl16, g13sScl16, g14sScl16, + g15sScl16, g16sScl16; + +void testvaScl16(); + +void +testitScl16() { + testvaScl16(g10sScl16, g11sScl16, g12sScl16, g13sScl16, g14sScl16, g1sScl16, + g2sScl16, g3sScl16, g4sScl16, g5sScl16, g6sScl16, g7sScl16, + g8sScl16, g9sScl16, g10sScl16, g11sScl16, g12sScl16, g13sScl16, + g14sScl16, g15sScl16, g16sScl16); +}