From: Eric Botcazou Date: Wed, 26 Sep 2018 07:36:45 +0000 (+0000) Subject: arm.c (arm_reorg): Skip Thumb reorg pass for thunks. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=f29cfc6b15aa015eb2ec0069633f6ed2a4cff195;p=gcc.git arm.c (arm_reorg): Skip Thumb reorg pass for thunks. * config/arm/arm.c (arm_reorg): Skip Thumb reorg pass for thunks. (arm32_output_mi_thunk): Deal with long calls. From-SVN: r264595 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d3f3de2cf84..4f606d35373 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2018-09-26 Eric Botcazou + + * config/arm/arm.c (arm_reorg): Skip Thumb reorg pass for thunks. + (arm32_output_mi_thunk): Deal with long calls. + 2018-09-26 Richard Biener PR debug/87428 diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 6332e68df05..c6e3f7954fb 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -17647,7 +17647,11 @@ arm_reorg (void) if (use_cmse) cmse_nonsecure_call_clear_caller_saved (); - if (TARGET_THUMB1) + + /* We cannot run the Thumb passes for thunks because there is no CFG. */ + if (cfun->is_thunk) + ; + else if (TARGET_THUMB1) thumb1_reorg (); else if (TARGET_THUMB2) thumb2_reorg (); @@ -26721,6 +26725,8 @@ static void arm32_output_mi_thunk (FILE *file, tree, HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset, tree function) { + const bool long_call_p = arm_is_long_call_p (function); + /* On ARM, this_regno is R0 or R1 depending on whether the function returns an aggregate or not. */ @@ -26758,9 +26764,22 @@ arm32_output_mi_thunk (FILE *file, tree, HOST_WIDE_INT delta, TREE_USED (function) = 1; } rtx funexp = XEXP (DECL_RTL (function), 0); + if (long_call_p) + { + emit_move_insn (temp, funexp); + funexp = temp; + } funexp = gen_rtx_MEM (FUNCTION_MODE, funexp); - rtx_insn * insn = emit_call_insn (gen_sibcall (funexp, const0_rtx, NULL_RTX)); + rtx_insn *insn = emit_call_insn (gen_sibcall (funexp, const0_rtx, NULL_RTX)); SIBLING_CALL_P (insn) = 1; + emit_barrier (); + + /* Indirect calls require a bit of fixup in PIC mode. */ + if (long_call_p) + { + split_all_insns_noflow (); + arm_reorg (); + } insn = get_insns (); shorten_branches (insn); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f690e62a445..60b23ba33d3 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2018-09-26 Eric Botcazou + + * g++.dg/other/vthunk1.C: Rename to... + * g++.dg/other/thunk1.C: ...this. + * g++.dg/other/thunk2a.C: New test. + * g++.dg/other/thunk2b.C: Likewise. + 2018-09-25 Jim Wilson * gcc.target/riscv/weak-1.c: New. diff --git a/gcc/testsuite/g++.dg/other/thunk1.C b/gcc/testsuite/g++.dg/other/thunk1.C new file mode 100644 index 00000000000..90165628b45 --- /dev/null +++ b/gcc/testsuite/g++.dg/other/thunk1.C @@ -0,0 +1,26 @@ +// PR c++/12007 Multiple inheritance float pass by value fails +// { dg-do run } + +extern "C" void abort (void); + +class gvImpl +{ +public: + virtual void PutVal(float value){} +}; + +class foo { public: virtual void Bar(){} }; + +class myGv: public foo, public gvImpl +{ + void PutVal(float value){ if (value != 3.14159f) abort (); } +}; + +myGv x; +gvImpl* object = &x; + +int main() +{ + object->PutVal(3.14159f); + return 0; +} diff --git a/gcc/testsuite/g++.dg/other/thunk2a.C b/gcc/testsuite/g++.dg/other/thunk2a.C new file mode 100644 index 00000000000..8e5ebd4960d --- /dev/null +++ b/gcc/testsuite/g++.dg/other/thunk2a.C @@ -0,0 +1,15 @@ +// { dg-do compile { target arm*-*-* } } +// { dg-options "-mlong-calls -ffunction-sections" } + +class a { +public: + virtual ~a(); +}; + +class b : virtual a {}; + +class c : b { + ~c(); +}; + +c::~c() {} diff --git a/gcc/testsuite/g++.dg/other/thunk2b.C b/gcc/testsuite/g++.dg/other/thunk2b.C new file mode 100644 index 00000000000..c8f4570923d --- /dev/null +++ b/gcc/testsuite/g++.dg/other/thunk2b.C @@ -0,0 +1,16 @@ +// { dg-do compile { target arm*-*-* } } +// { dg-options "-mlong-calls -ffunction-sections" } +// { dg-additional-options "-fPIC" { target fpic } } + +class a { +public: + virtual ~a(); +}; + +class b : virtual a {}; + +class c : b { + ~c(); +}; + +c::~c() {} diff --git a/gcc/testsuite/g++.dg/other/vthunk1.C b/gcc/testsuite/g++.dg/other/vthunk1.C deleted file mode 100644 index 90165628b45..00000000000 --- a/gcc/testsuite/g++.dg/other/vthunk1.C +++ /dev/null @@ -1,26 +0,0 @@ -// PR c++/12007 Multiple inheritance float pass by value fails -// { dg-do run } - -extern "C" void abort (void); - -class gvImpl -{ -public: - virtual void PutVal(float value){} -}; - -class foo { public: virtual void Bar(){} }; - -class myGv: public foo, public gvImpl -{ - void PutVal(float value){ if (value != 3.14159f) abort (); } -}; - -myGv x; -gvImpl* object = &x; - -int main() -{ - object->PutVal(3.14159f); - return 0; -}