public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] Disable sched1 in functions that call setjmp
@ 2022-12-22 17:16 Jose E. Marchesi
  0 siblings, 0 replies; only message in thread
From: Jose E. Marchesi @ 2022-12-22 17:16 UTC (permalink / raw)
  To: gcc-patches; +Cc: qing.zhao

When the following testcase is built with -fschedule-insns in either
x86_64 or aarch64:

----

jmp_buf ex_buf__;

int f(int x)
{
  int arr[] = {1,2,6,8,9,10};
  int lo=0;
  int hi=5;

  while(lo<=hi) {
        int mid=(lo+hi)/2;

        if(arr[mid]==x) {
          THROW;
        } else if(arr[mid]<x) {
          lo=mid+1;
        } else if(arr[mid]>x) {
          hi=mid-1;
        }
  }

  return -1;
}

int
main(int argc, char** argv)
{
  int a=2;
  bool b=false;

  TRY
  {
   a=f(a);
   b=true;
  }
  CATCH
  {
   printf("a : %d\n",a);
   printf("Got Exception!\n");
  }
  ETRY;

  if(b) {
        printf("b is true!\n");
  }
  return 0;
}
----

The first instruction scheduler pass reorders instructions in the TRY
block in a way `b=true' gets executed before the call to the function
`f'.  This optimization is wrong, because `main' calls setjmp and `f'
is known to call longjmp.

As discussed in BZ 57067, the root cause for this is the fact that
setjmp is not properly modeled in RTL, and therefore the backend
passes have no normalized way to handle this situation.

As Alexander Monakov noted in the BZ, many RTL passes refuse to touch
functions that call setjmp.  This includes for example gcse,
store_motion and cprop.  This patch adds the sched1 pass to that list.

Note that the other instruction scheduling passes are still allowed to
run on these functions, since they reorder instructions within basic
blocks, and therefore they cannot cross function calls.

This doesn't fix the fundamental issue, but at least assures that
sched1 wont perform invalid transformation in correct C programs.

regtested in aarch64-linux-gnu.

gcc/ChangeLog:

	PR rtl-optimization/57067
	* sched-rgn.cc (pass_sched::gate): Disable pass if current
	function calls setjmp.
---
 gcc/sched-rgn.cc | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/gcc/sched-rgn.cc b/gcc/sched-rgn.cc
index 420c45dffb4..c536d0b8dea 100644
--- a/gcc/sched-rgn.cc
+++ b/gcc/sched-rgn.cc
@@ -3847,7 +3847,8 @@ bool
 pass_sched::gate (function *)
 {
 #ifdef INSN_SCHEDULING
-  return optimize > 0 && flag_schedule_insns && dbg_cnt (sched_func);
+  return optimize > 0 && flag_schedule_insns
+    && !cfun->calls_setjmp && dbg_cnt (sched_func);
 #else
   return 0;
 #endif
-- 
2.30.2


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-12-22 17:12 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-12-22 17:16 [PATCH] Disable sched1 in functions that call setjmp Jose E. Marchesi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).