aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@arm.com>2020-09-18 16:55:45 +0100
committerRichard Sandiford <richard.sandiford@arm.com>2020-09-18 16:55:45 +0100
commit3c7c5f1d4a4b8328fb4c07483cdbfe4ea7762155 (patch)
tree0f8006892f070e8f42d6c46084958d9cf64b5320
parentf89e9bfac36d45dcf82c462ce51163b0b196cc45 (diff)
downloadgcc-3c7c5f1d4a4b8328fb4c07483cdbfe4ea7762155.zip
gcc-3c7c5f1d4a4b8328fb4c07483cdbfe4ea7762155.tar.gz
gcc-3c7c5f1d4a4b8328fb4c07483cdbfe4ea7762155.tar.bz2
ira: Fix elimination for global hard FPs [PR91957]
If the hard frame pointer is being used as a global register, we should skip the usual handling for eliminations. As the comment says, the register cannot in that case be eliminated (or eliminated to) and is already marked live where appropriate. Doing this removes the duplicate error for gcc.target/i386/pr82673.c. The “cannot be used in 'asm' here” message is meant to be for asm statements rather than register asms, and the function that the error is reported against doesn't use asm. gcc/ 2020-09-18 Richard Sandiford <richard.sandiford@arm.com> PR middle-end/91957 * ira.c (ira_setup_eliminable_regset): Skip the special elimination handling of the hard frame pointer if the hard frame pointer is fixed. gcc/testsuite/ 2020-09-18 H.J. Lu <hjl.tools@gmail.com> Richard Sandiford <richard.sandiford@arm.com> PR middle-end/91957 * g++.target/i386/pr97054.C: New test. * gcc.target/i386/pr82673.c: Remove redundant extra message.
-rw-r--r--gcc/ira.c8
-rw-r--r--gcc/testsuite/g++.target/i386/pr97054.C96
-rw-r--r--gcc/testsuite/gcc.target/i386/pr82673.c2
3 files changed, 103 insertions, 3 deletions
diff --git a/gcc/ira.c b/gcc/ira.c
index a759f3c..27d1b3c 100644
--- a/gcc/ira.c
+++ b/gcc/ira.c
@@ -2310,8 +2310,12 @@ ira_setup_eliminable_regset (void)
if (!HARD_FRAME_POINTER_IS_FRAME_POINTER)
{
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])
+ /* Nothing to do: the register is already treated as live
+ where appropriate, and cannot be eliminated. */
+ ;
+ else if (!TEST_HARD_REG_BIT (crtl->asm_clobbers,
+ HARD_FRAME_POINTER_REGNUM + i))
{
SET_HARD_REG_BIT (eliminable_regset,
HARD_FRAME_POINTER_REGNUM + i);
diff --git a/gcc/testsuite/g++.target/i386/pr97054.C b/gcc/testsuite/g++.target/i386/pr97054.C
new file mode 100644
index 0000000..d0693af
--- /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;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr82673.c b/gcc/testsuite/gcc.target/i386/pr82673.c
index 161ec88..2248295 100644
--- a/gcc/testsuite/gcc.target/i386/pr82673.c
+++ b/gcc/testsuite/gcc.target/i386/pr82673.c
@@ -9,4 +9,4 @@ void
bar (void) /* { dg-error "frame pointer required, but reserved" } */
{
B = &y;
-} /* { dg-error "bp cannot be used in 'asm' here" } */
+}