On Tue, Sep 15, 2020 at 7:44 AM Richard Sandiford <richard.sandif...@arm.com> wrote: > > Thanks for looking at this. > > "H.J. Lu" <hjl.to...@gmail.com> writes: > > commit 1bcb4c4faa4bd6b1c917c75b100d618faf9e628c > > Author: Richard Sandiford <richard.sandif...@arm.com> > > Date: Wed Oct 2 07:37:10 2019 +0000 > > > > [LRA] Don't make eliminable registers live (PR91957) > > > > didn't make eliminable registers live which breaks > > > > register void *cur_pro asm("reg"); > > > > where "reg" is an eliminable register. Make fixed eliminable registers > > live to fix it. > > I don't think fixedness itself is the issue here: it's usual for at > least some registers involved in eliminations to be fixed registers. > > I think what makes this case different is instead that cur_pro/ebp > is a global register. But IMO things have already gone wrong if we > think that a global register is eliminable. > > So I wonder if instead we should check global_regs at the beginning of: > > for (i = 0; i < fp_reg_count; i++) > if (!TEST_HARD_REG_BIT (crtl->asm_clobbers, > HARD_FRAME_POINTER_REGNUM + i)) > { > SET_HARD_REG_BIT (eliminable_regset, > HARD_FRAME_POINTER_REGNUM + i); > if (frame_pointer_needed) > SET_HARD_REG_BIT (ira_no_alloc_regs, > HARD_FRAME_POINTER_REGNUM + i); > } > else if (frame_pointer_needed) > error ("%s cannot be used in %<asm%> here", > reg_names[HARD_FRAME_POINTER_REGNUM + i]); > else > df_set_regs_ever_live (HARD_FRAME_POINTER_REGNUM + i, true); > > (ira_setup_eliminable_regset), and handle the global_regs[] case in > the same way as the else case, i.e. short-circuiting both of the ifs. >
Like this? Thanks. -- H.J.
From d1c852691d245d90666c1b977775fc7f8db2b241 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" <hjl.to...@gmail.com> Date: Tue, 15 Sep 2020 04:17:54 -0700 Subject: [PATCH] IRA: Don't make a global register eliminable commit 1bcb4c4faa4bd6b1c917c75b100d618faf9e628c Author: Richard Sandiford <richard.sandif...@arm.com> Date: Wed Oct 2 07:37:10 2019 +0000 [LRA] Don't make eliminable registers live (PR91957) didn't make eliminable registers live which breaks register void *cur_pro asm("reg"); where "reg" is an eliminable register. Update ira_setup_eliminable_regset to avoid making global registers eliminable. gcc/ PR middle-end/97054 * ira.c (ira_setup_eliminable_regset): Don't make a global register eliminable. gcc/testsuite/ PR middle-end/97054 * g++.target/i386/pr97054.C: New test. --- gcc/ira.c | 30 ++++---- gcc/testsuite/g++.target/i386/pr97054.C | 96 +++++++++++++++++++++++++ 2 files changed, 114 insertions(+), 12 deletions(-) create mode 100644 gcc/testsuite/g++.target/i386/pr97054.C diff --git a/gcc/ira.c b/gcc/ira.c index a759f3c2aa8..506c6e6783e 100644 --- a/gcc/ira.c +++ b/gcc/ira.c @@ -2309,21 +2309,27 @@ ira_setup_eliminable_regset (void) } if (!HARD_FRAME_POINTER_IS_FRAME_POINTER) { + /* NB: Don't make a global register eliminable. */ for (i = 0; i < fp_reg_count; i++) - if (!TEST_HARD_REG_BIT (crtl->asm_clobbers, - HARD_FRAME_POINTER_REGNUM + i)) + if (global_regs[HARD_FRAME_POINTER_REGNUM + i]) + df_set_regs_ever_live (HARD_FRAME_POINTER_REGNUM + i, true); + else { - SET_HARD_REG_BIT (eliminable_regset, - HARD_FRAME_POINTER_REGNUM + i); - if (frame_pointer_needed) - SET_HARD_REG_BIT (ira_no_alloc_regs, - HARD_FRAME_POINTER_REGNUM + i); + if (!TEST_HARD_REG_BIT (crtl->asm_clobbers, + HARD_FRAME_POINTER_REGNUM + i)) + { + SET_HARD_REG_BIT (eliminable_regset, + HARD_FRAME_POINTER_REGNUM + i); + if (frame_pointer_needed) + SET_HARD_REG_BIT (ira_no_alloc_regs, + HARD_FRAME_POINTER_REGNUM + i); + } + else if (frame_pointer_needed) + error ("%s cannot be used in %<asm%> here", + reg_names[HARD_FRAME_POINTER_REGNUM + i]); + else + df_set_regs_ever_live (HARD_FRAME_POINTER_REGNUM + i, true); } - else if (frame_pointer_needed) - error ("%s cannot be used in %<asm%> here", - reg_names[HARD_FRAME_POINTER_REGNUM + i]); - else - df_set_regs_ever_live (HARD_FRAME_POINTER_REGNUM + i, true); } } diff --git a/gcc/testsuite/g++.target/i386/pr97054.C b/gcc/testsuite/g++.target/i386/pr97054.C new file mode 100644 index 00000000000..d0693af2a42 --- /dev/null +++ b/gcc/testsuite/g++.target/i386/pr97054.C @@ -0,0 +1,96 @@ +// { dg-do run { target { ! ia32 } } } +// { dg-require-effective-target fstack_protector } +// { dg-options "-O2 -fno-strict-aliasing -msse4.2 -mfpmath=sse -fPIC -fstack-protector-strong -O2" } + +struct p2_icode *ipc; +register int pars asm("r13"); +register struct processor *cur_pro asm("rbp"); +register int a asm("rbx"); +register int c asm("r14"); +typedef long lina_t; +typedef long la_t; +typedef processor processor_t; +typedef p2_icode p2_icode_t; +typedef enum { + P2_Return_Action_Next, +} p2_return_action_t; +typedef struct p2_icode { + int ic_Parameters; +} icode_t; +extern "C" icode_t *x86_log_to_icode_exec(processor_t *, la_t); +typedef struct { + icode_t *ipc; +} b; +typedef struct { + char ma_thread_signal; + int event_counter; + b instrumentation; +} d; + +extern "C" lina_t int2linaddr(processor_t *cpu, const p2_icode_t *ic) +{ + return 0; +} + +typedef struct e { + long i64; + char LMA; +} f; + +struct processor { + d common; + e pc_RIP; + f pc_EFER; + p2_icode_t *saved_ipc; +}; +inline la_t code_lin_to_log(processor_t *, long) { return 0; } +void turbo_clear(processor_t *) {} + +p2_return_action_t p2_ep_REBIND_IPC(void) +{ + processor_t *cpu = cur_pro; + la_t vaddr = cpu->pc_RIP.i64; + cur_pro->saved_ipc = (p2_icode_t *) ipc; + cur_pro->common.instrumentation.ipc = ipc; + cur_pro->pc_RIP.i64 = code_lin_to_log(cur_pro, int2linaddr(cur_pro, ipc)); + turbo_clear(cur_pro); + + cpu->saved_ipc = x86_log_to_icode_exec(cur_pro, vaddr); + ipc++; + (cur_pro->common.event_counter -= (1)); + if (__builtin_expect((!((cur_pro->common.event_counter <= 0) + | cur_pro->common.ma_thread_signal)), 1)) + { + ((pars = ((ipc)->ic_Parameters))); + return P2_Return_Action_Next; + } else { + return (p2_return_action_t) 0; + } + return P2_Return_Action_Next; +} + +struct p2_icode fake_ipc = { 0 }; +struct processor fake_proc ={{ 0 } }; + +extern "C" icode_t * +x86_log_to_icode_exec(processor_t *cpu, la_t la) +{ + return 0; +} + +extern "C" void +turbo_threshold_reached(processor_t *c, p2_icode_t *i, int s) +{ +} + +int main() +{ + if (!__builtin_cpu_supports ("sse4.2")) + return 0; + fake_proc.pc_RIP.i64 = 0xbaadc0de; + fake_proc.pc_EFER.LMA = 0xf; + ipc = &fake_ipc; + cur_pro = &fake_proc; + p2_ep_REBIND_IPC(); + return 0; +} -- 2.26.2