Skip to content

Commit 1390bf5

Browse files
committed
[PR112445][LRA]: Fix "unable to find a register to spill" error
PR112445 is a very complicated bug occurring from interaction of constraint subpass, inheritance, and hard reg live range splitting. It is hard to debug this PR only from LRA standard logs. Therefore I added dumping all func insns at the end of complicated sub-passes (constraint, inheritance, undoing inheritance, hard reg live range splitting, and rematerialization). As such output can be quite big, it is switched only one level 7 of -fira-verbose value. The reason for the bug is a skip of live-range splitting of hard reg (dx) on the 1st live range splitting subpass. Splitting is done for reload pseudos around an original insn and its reload insns but the subpass did not recognize such insn pattern because previous inheritance and undoing inheritance subpasses extended a bit reload pseudo live range. Although we undid inheritance in question, the result code was a bit different from a code before the corresponding inheritance pass. The following fixes the bug by restoring exact code before the inheritance. gcc/ChangeLog: PR target/112445 * lra.h (lra): Add one more arg. * lra-int.h (lra_verbose, lra_dump_insns): New externals. (lra_dump_insns_if_possible): Ditto. * lra.cc (lra_dump_insns): Dump all insns. (lra_dump_insns_if_possible): Dump all insns for lra_verbose >= 7. (lra_verbose): New global. (lra): Add new arg. Setup lra_verbose from its value. * lra-assigns.cc (lra_split_hard_reg_for): Dump insns if rtl was changed. * lra-remat.cc (lra_remat): Dump insns if rtl was changed. * lra-constraints.cc (lra_inheritance): Dump insns. (lra_constraints, lra_undo_inheritance): Dump insns if rtl was changed. (remove_inheritance_pseudos): Use restore reg if it is set up. * ira.cc: (lra): Pass internal_flag_ira_verbose. gcc/testsuite/ChangeLog: PR target/112445 * gcc.target/i386/pr112445.c: New test.
1 parent ff99671 commit 1390bf5

File tree

8 files changed

+65
-7
lines changed

8 files changed

+65
-7
lines changed

gcc/ira.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5970,7 +5970,7 @@ do_reload (void)
59705970

59715971
ira_destroy ();
59725972

5973-
lra (ira_dump_file);
5973+
lra (ira_dump_file, internal_flag_ira_verbose);
59745974
/* ???!!! Move it before lra () when we use ira_reg_equiv in
59755975
LRA. */
59765976
vec_free (reg_equivs);

gcc/lra-assigns.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1835,6 +1835,7 @@ lra_split_hard_reg_for (void)
18351835
if (spill_p)
18361836
{
18371837
bitmap_clear (&failed_reload_pseudos);
1838+
lra_dump_insns_if_possible ("changed func after splitting hard regs");
18381839
return true;
18391840
}
18401841
bitmap_clear (&non_reload_pseudos);

gcc/lra-constraints.cc

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5537,6 +5537,8 @@ lra_constraints (bool first_p)
55375537
lra_assert (df_regs_ever_live_p (hard_regno + j));
55385538
}
55395539
}
5540+
if (changed_p)
5541+
lra_dump_insns_if_possible ("changed func after local");
55405542
return changed_p;
55415543
}
55425544

@@ -7277,7 +7279,7 @@ lra_inheritance (void)
72777279
bitmap_release (&invalid_invariant_regs);
72787280
bitmap_release (&check_only_regs);
72797281
free (usage_insns);
7280-
7282+
lra_dump_insns_if_possible ("func after inheritance");
72817283
timevar_pop (TV_LRA_INHERITANCE);
72827284
}
72837285

@@ -7477,13 +7479,16 @@ remove_inheritance_pseudos (bitmap remove_pseudos)
74777479
== get_regno (lra_reg_info[prev_sregno].restore_rtx))))
74787480
&& ! bitmap_bit_p (remove_pseudos, prev_sregno))
74797481
{
7482+
int restore_regno = get_regno (lra_reg_info[sregno].restore_rtx);
7483+
if (restore_regno < 0)
7484+
restore_regno = prev_sregno;
74807485
lra_assert (GET_MODE (SET_SRC (prev_set))
7481-
== GET_MODE (regno_reg_rtx[sregno]));
7486+
== GET_MODE (regno_reg_rtx[restore_regno]));
74827487
/* Although we have a single set, the insn can
74837488
contain more one sregno register occurrence
74847489
as a source. Change all occurrences. */
74857490
lra_substitute_pseudo_within_insn (curr_insn, sregno,
7486-
SET_SRC (prev_set),
7491+
regno_reg_rtx[restore_regno],
74877492
false);
74887493
/* As we are finishing with processing the insn
74897494
here, check the destination too as it might
@@ -7745,5 +7750,7 @@ lra_undo_inheritance (void)
77457750
EXECUTE_IF_SET_IN_BITMAP (&lra_split_regs, 0, regno, bi)
77467751
lra_reg_info[regno].restore_rtx = NULL_RTX;
77477752
change_p = undo_optional_reloads () || change_p;
7753+
if (change_p)
7754+
lra_dump_insns_if_possible ("changed func after undoing inheritance");
77487755
return change_p;
77497756
}

gcc/lra-int.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,7 @@ typedef class lra_insn_recog_data *lra_insn_recog_data_t;
278278
/* lra.cc: */
279279

280280
extern FILE *lra_dump_file;
281+
extern int lra_verbose;
281282

282283
extern bool lra_hard_reg_split_p;
283284
extern bool lra_asm_error_p;
@@ -312,6 +313,9 @@ extern void lra_emit_move (rtx, rtx);
312313
extern void lra_update_dups (lra_insn_recog_data_t, signed char *);
313314
extern void lra_asm_insn_error (rtx_insn *insn);
314315

316+
extern void lra_dump_insns (FILE *f);
317+
extern void lra_dump_insns_if_possible (const char *title);
318+
315319
extern void lra_process_new_insns (rtx_insn *, rtx_insn *, rtx_insn *,
316320
const char *);
317321

gcc/lra-remat.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1331,6 +1331,8 @@ lra_remat (void)
13311331
calculate_global_remat_bb_data ();
13321332
dump_candidates_and_remat_bb_data ();
13331333
result = do_remat ();
1334+
if (result)
1335+
lra_dump_insns_if_possible ("changed func after rematerialization");
13341336
all_cands.release ();
13351337
bitmap_clear (&temp_bitmap);
13361338
bitmap_clear (&subreg_regs);

gcc/lra.cc

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1879,6 +1879,24 @@ setup_sp_offset (rtx_insn *from, rtx_insn *last)
18791879
return offset;
18801880
}
18811881

1882+
/* Dump all func insns in a slim form. */
1883+
void
1884+
lra_dump_insns (FILE *f)
1885+
{
1886+
dump_rtl_slim (f, get_insns (), NULL, -1, 0);
1887+
}
1888+
1889+
/* Dump all func insns in a slim form with TITLE when the dump file is open and
1890+
lra_verbose >=7. */
1891+
void
1892+
lra_dump_insns_if_possible (const char *title)
1893+
{
1894+
if (lra_dump_file == NULL || lra_verbose < 7)
1895+
return;
1896+
fprintf (lra_dump_file, "%s:", title);
1897+
lra_dump_insns (lra_dump_file);
1898+
}
1899+
18821900
/* Emit insns BEFORE before INSN and insns AFTER after INSN. Put the
18831901
insns onto the stack. Print about emitting the insns with
18841902
TITLE. */
@@ -2297,6 +2315,9 @@ bitmap_head lra_subreg_reload_pseudos;
22972315
/* File used for output of LRA debug information. */
22982316
FILE *lra_dump_file;
22992317

2318+
/* How verbose should be the debug information. */
2319+
int lra_verbose;
2320+
23002321
/* True if we split hard reg after the last constraint sub-pass. */
23012322
bool lra_hard_reg_split_p;
23022323

@@ -2332,14 +2353,15 @@ setup_reg_spill_flag (void)
23322353
bool lra_simple_p;
23332354

23342355
/* Major LRA entry function. F is a file should be used to dump LRA
2335-
debug info. */
2356+
debug info with given verbosity. */
23362357
void
2337-
lra (FILE *f)
2358+
lra (FILE *f, int verbose)
23382359
{
23392360
int i;
23402361
bool live_p, inserted_p;
23412362

23422363
lra_dump_file = f;
2364+
lra_verbose = verbose;
23432365
lra_asm_error_p = false;
23442366
lra_pmode_pseudo = gen_reg_rtx (Pmode);
23452367

gcc/lra.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ lra_get_allocno_class (int regno)
3535
}
3636

3737
extern rtx lra_eliminate_regs (rtx, machine_mode, rtx);
38-
extern void lra (FILE *);
38+
extern void lra (FILE *, int);
3939
extern void lra_init_once (void);
4040
extern void lra_finish_once (void);
4141

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/* { dg-do compile { target int128 } } */
2+
/* { dg-options "-O -march=cascadelake -fwrapv" } */
3+
4+
typedef _Decimal64 d64;
5+
int foo0_f128_0, foo0_ret, foo0_s64_0;
6+
_Complex float foo0_cf128_0;
7+
8+
void
9+
foo (char u8_0, char s8_0, _Complex unsigned cu8_0, int cs32_0,
10+
_Complex _Float16 cf16_0, _Complex int cf32_0, int d32_0,
11+
_Decimal64 d64_0)
12+
{
13+
cu8_0 *= (__int128) foo0_s64_0;
14+
int cf32_1 = __builtin_ccosf (cu8_0);
15+
__int128 u128_r =
16+
foo0_f128_0 + (__int128) foo0_cf128_0 + (__int128) __imag__ foo0_cf128_0;
17+
int u64_r = u128_r + foo0_s64_0 + d64_0;
18+
int u32_r = u64_r + cs32_0 + cf32_0 + __imag__ cf32_0 + cf32_1 + d32_0;
19+
short u16_r = u32_r + cf16_0 + __imag__ cf16_0;
20+
char u8_r = u16_r + u8_0 + s8_0 + cu8_0 + __imag__ cu8_0;
21+
foo0_ret = u8_r;
22+
}

0 commit comments

Comments
 (0)