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

Reply via email to