Bug 93808 - [11/12/13/14/15 Regression] [SH] Ruby crashes with 'Illegal Instruction' with -fcrossjumping
Summary: [11/12/13/14/15 Regression] [SH] Ruby crashes with 'Illegal Instruction' with...
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 9.2.1
: P4 normal
Target Milestone: 11.5
Assignee: Not yet assigned to anyone
URL:
Keywords: wrong-code
Depends on:
Blocks:
 
Reported: 2020-02-18 16:56 UTC by John Paul Adrian Glaubitz
Modified: 2024-04-26 10:37 UTC (History)
2 users (show)

See Also:
Host:
Target: sh*-*-*
Build:
Known to work: 8.3.0
Known to fail: 10.2.1, 9.2.0
Last reconfirmed: 2020-02-20 00:00:00


Attachments
Source and compiler output for string.c (984.79 KB, application/x-compressed-tar)
2020-02-18 18:18 UTC, John Paul Adrian Glaubitz
Details
Source and compiler output for string.c with stack-protector disabled (982.60 KB, application/x-compressed-tar)
2020-02-20 08:16 UTC, John Paul Adrian Glaubitz
Details
reduced case (1.27 KB, text/plain)
2020-02-20 15:28 UTC, Oleg Endo
Details
Build log for ruby 2.5 with Oleg's patch applied (60.37 KB, application/gzip)
2021-04-30 10:27 UTC, John Paul Adrian Glaubitz
Details

Note You need to log in before you can comment on or make changes to this bug.
Description John Paul Adrian Glaubitz 2020-02-18 16:56:33 UTC
When compiling the ruby2.5 package on Debian/sh4 with gcc-9 instead of gcc-8, the Ruby interpretor crashes with 'Illegal Instruction'.

root@tirpitz:..ruby2.5-ixXW4Q/ruby2.5-2.5.5> ./miniruby 
Illegal instruction
root@tirpitz:..ruby2.5-ixXW4Q/ruby2.5-2.5.5>

Printing the assembly with GDB shows that the IP seems to be pointing at data instead of code(?):

(gdb) x/5i $pc
=> 0x5380c0 <coderange_scan+720>:       .word 0x0000
   0x5380c2 <coderange_scan+722>:       .word 0x0010
   0x5380c4 <coderange_scan+724>:       mov     r14,r2
   0x5380c6 <coderange_scan+726>:       bra     0x538094 <coderange_scan+676>
   0x5380c8 <coderange_scan+728>:       add     #-16,r2
(gdb)

I have not tested gcc-10 yet. Will do that now.
Comment 2 Oleg Endo 2020-02-18 17:11:13 UTC
(In reply to John Paul Adrian Glaubitz from comment #0)
> 
> Printing the assembly with GDB shows that the IP seems to be pointing at
> data instead of code(?):
> 
> (gdb) x/5i $pc
> => 0x5380c0 <coderange_scan+720>:       .word 0x0000
>    0x5380c2 <coderange_scan+722>:       .word 0x0010

Yeah, that looks like data.  Something makes it jump to a wrong address.  No idea why.  Can you try to get a bit bigger code snippet at that point?  What's the code/data before and after?
Comment 3 John Paul Adrian Glaubitz 2020-02-18 17:18:23 UTC
(In reply to Oleg Endo from comment #2)
> Yeah, that looks like data.  Something makes it jump to a wrong address.  No
> idea why.  Can you try to get a bit bigger code snippet at that point? 
> What's the code/data before and after?

I have put the compiled source into a tarball so you can have a look yourself:

> https://people.debian.org/~glaubitz/ruby2.5-G7ZWPI.tgz
Comment 4 Oleg Endo 2020-02-18 17:21:51 UTC
(In reply to John Paul Adrian Glaubitz from comment #3)
> 
> I have put the compiled source into a tarball so you can have a look
> yourself:
> 
> > https://people.debian.org/~glaubitz/ruby2.5-G7ZWPI.tgz

Sorry, I will not wade through the whole thing.  If you have it crashing in the debugger already, please try to provide a bit more context of the crash.  Like file name, function name ... something like that would be helpful.
Comment 5 John Paul Adrian Glaubitz 2020-02-18 17:32:38 UTC
(In reply to Oleg Endo from comment #4)
> (In reply to John Paul Adrian Glaubitz from comment #3)
> > 
> > I have put the compiled source into a tarball so you can have a look
> > yourself:
> > 
> > > https://people.debian.org/~glaubitz/ruby2.5-G7ZWPI.tgz
> 
> Sorry, I will not wade through the whole thing.  If you have it crashing in
> the debugger already, please try to provide a bit more context of the crash.
> Like file name, function name ... something like that would be helpful.

Okay, so the backtrace looks like this:

483         switch (e - p) {
(gdb) bt
#0  0x005380c0 in search_nonascii (e=<optimized out>, p=<optimized out>) at string.c:483
#1  coderange_scan (p=<optimized out>, len=<optimized out>, enc=0x63d698) at string.c:505
#2  0x00538866 in rb_enc_str_coderange (str=6750060) at string.c:634
#3  0x00538920 in rb_str_hash (str=6750060) at string.c:3112
#4  0x0052fb94 in do_hash (tab=0x63fe20, key=<optimized out>) at st.c:1479
#5  st_update (tab=0x63fe20, key=<optimized out>, func=0x539fb8 <fstr_update_callback>, arg=2080371772) at st.c:1479
#6  0x00534c46 in register_fstring (str=6750060) at string.c:341
#7  0x0054e06a in register_static_symid_str (id=33, str=<optimized out>) at symbol.c:417
#8  0x0054e458 in register_static_symid (enc=0x63d698, len=1, name=0x7bfff47f "!\\\bI", id=33) at symbol.c:407
#9  Init_op_tbl () at symbol.c:46
#10 Init_sym () at symbol.c:86
#11 0x0049085c in rb_call_inits () at inits.c:21
#12 0x00472c86 in ruby_setup () at eval.c:61
#13 0x0047444c in ruby_init () at eval.c:78
#14 0x00418e76 in main (argc=<optimized out>, argv=<optimized out>) at ./main.c:41
(gdb)

I will probably have to rebuild with debug symbols disabled so we can see more.
Comment 6 Oleg Endo 2020-02-18 17:43:27 UTC
Thanks, that's good.  I can look at the disassembly of string.o and found the spot.

I suspect the switch statements in the code are turned into jump tables, and for some reason the jump offset is wrong in some case.

Can you re-compile with -save-temps option and attach the resulting string.s intermediate file?
Comment 7 John Paul Adrian Glaubitz 2020-02-18 18:18:00 UTC
Created attachment 47871 [details]
Source and compiler output for string.c

I have created a tarball which contains both the C source, the assembly, the preprocessed source and the object file for string.
Comment 8 Richard Biener 2020-02-19 08:00:52 UTC
One may want to see whether GCC 10 is affected or not.
Comment 9 John Paul Adrian Glaubitz 2020-02-19 09:23:18 UTC
(In reply to Richard Biener from comment #8)
> One may want to see whether GCC 10 is affected or not.

Yes, I can confirm it affects GCC-10 as well.
Comment 10 Oleg Endo 2020-02-19 14:11:51 UTC
I've just tried to compile the preprocessed string.i with the current gcc 9 branch sh-elf cross compiler with the following options:

sh-elf-gcc -c -mieee -g -O2  -fstack-protector-strong -Wformat -Werror=format-security -fPIC -D_FORTIFY_SOURCE=2 -fstack-protector -fno-strict-overflow -fvisibility=hidden -fexcess-precision=standard -DRUBY_EXPORT -Wdate-time -D_FORTIFY_SOURCE=2 -save-temps 

but the resulting string.s is quite different from the one in #comment 7.

It's difficult to see what's going on there.  Can you try building this without the stackprotector options and see if still crashes in the same way?
Comment 11 John Paul Adrian Glaubitz 2020-02-20 08:16:55 UTC
Created attachment 47878 [details]
Source and compiler output for string.c with stack-protector disabled

(In reply to Oleg Endo from comment #10)
> It's difficult to see what's going on there.  Can you try building this
> without the stackprotector options and see if still crashes in the same way?

I have stripped "-fstack-protector" and "-fstack-protector-strong" from the CFLAGS, still crashes. Attaching the corresponding tarball of the string.* files.

I can try removing more flags from CFLAGS and see if that helps.
Comment 12 John Paul Adrian Glaubitz 2020-02-20 08:45:03 UTC
Building with -O1 fixes the problem for me. Now I need to compare the flags for -O1 and -O2 and check which one breaks the build.
Comment 13 John Paul Adrian Glaubitz 2020-02-20 13:59:01 UTC
(In reply to John Paul Adrian Glaubitz from comment #12)
> Building with -O1 fixes the problem for me. Now I need to compare the flags
> for -O1 and -O2 and check which one breaks the build.

It's -fcrossjumping which causes the crash. Passing -fno-crossjumping fixes the build.
Comment 14 Oleg Endo 2020-02-20 15:28:04 UTC
Created attachment 47879 [details]
reduced case

I've reduced the preprocessed file string.c down to the problematic function 'coderange_scan'
Comment 15 Oleg Endo 2020-02-20 15:40:58 UTC
Compiling attachment 47879 [details] with regular sh-elf cross compiler:

sh-elf-gcc -c -O2 -save-temps -dp string_coderange_scan.c 

and looking at the generated assembly, clearly shows the bug right before the 2nd casesi_worker_1 insn:


.L48:
	mov.l	.L120,r0	! 11	[c=10 l=2]  movsi_i/0
	add	#8,r15		! 1214	[c=4 l=2]  *addsi3/0
	lds.l	@r15+,pr	! 1216	[c=1 l=2]  movsi_i/14
	mov.l	@r15+,r14	! 1217	[c=1 l=2]  movsi_i/5
	mov.l	@r15+,r13	! 1218	[c=1 l=2]  movsi_i/5
	mov.l	@r15+,r12	! 1219	[c=1 l=2]  movsi_i/5
	mov.l	@r15+,r11	! 1220	[c=1 l=2]  movsi_i/5
	mov.l	@r15+,r10	! 1221	[c=1 l=2]  movsi_i/5
	mov.l	@r15+,r9	! 1222	[c=1 l=2]  movsi_i/5
	rts			! 1225	[c=0 l=2]  *return_i
	mov.l	@r15+,r8	! 1223	[c=1 l=2]  movsi_i/5
	.align 1
.L96:
	sub	r2,r10		! 278	[c=4 l=2]  *subsi3_internal
	mov	#3,r2		! 282	[c=4 l=2]  movsi_i/2


.L11:				! <<<< jump target BEFORE the constant pool
.L121:
	.align 2
.L120:
	.long	1048576		! <<<< this is a constant in the constant pool
	.align 1
.L58:
	mov	r13,r3		! 1119	[c=4 l=2]  movsi_i/1
	bra	.L15		! 1261	[c=5 l=2]  jump_compact
	add	#-16,r3		! 1120	[c=4 l=2]  *addsi3/0
	.align 1
.L29:
	mov.b	@(14,r3),r0	! 316	[c=2 l=2]  *extendqisi2_compact_mem_disp/0
	cmp/pz	r0		! 317	[c=4 l=2]  cmpgesi_t/0
	bf	.L107		! 318	[c=17 l=2]  *cbranch_t
.L30:
	mov.b	@(15,r3),r0	! 330	[c=2 l=2]  *extendqisi2_compact_mem_disp/0
	cmp/pz	r0		! 331	[c=4 l=2]  cmpgesi_t/0
	bt	.L48		! 332	[c=17 l=2]  *cbranch_t
	mov	r13,r8		! 1068	[c=4 l=2]  movsi_i/1
	bra	.L23		! 1265	[c=5 l=2]  jump_compact
	add	#-1,r8		! 334	[c=4 l=2]  *addsi3/0
	.align 1
.L101:
	sub	r3,r1		! 465	[c=4 l=2]  *subsi3_internal
	mov	r1,r3		! 1083	[c=4 l=2]  movsi_i/1
.L33:
	mov	#3,r7		! 469	[c=4 l=2]  movsi_i/2
	cmp/hi	r7,r3		! 474	[c=4 l=2]  cmpgtusi_t
.L153:
	bt	.L11		! 475	[c=17 l=2]  *cbranch_t <<< bad jump
	mova	.L42,r0		! 1085	[c=9 l=2]  mova
	add	r3,r3		! 1086	[c=9 l=4]  casesi_worker_1/0
	mov.w	@(r0,r3),r3
	add	r0,r3		! 1087	[c=4 l=2]  *addsi3/0
	jmp	@r3
	nop			! 477	[c=4 l=4]  casesi_jump_1
	.align 2
Comment 16 Oleg Endo 2020-02-20 15:52:29 UTC
This seems to be actually valid code?!

  switch (e - p)
  {
    default: __builtin_unreachable();
    case 3: if (e[-3]&0x80) return e-3;
    case 2: if (e[-2]&0x80) return e-2;
    case 1: if (e[-1]&0x80) return e-1;
    case 0: return ((void *)0);
  }

gets compiled to

.L101:
	sub	r3,r1		! 465	[c=4 l=2]  *subsi3_internal
	mov	r1,r3		! 1083	[c=4 l=2]  movsi_i/1
.L33:
	mov	#3,r7		! 469	[c=4 l=2]  movsi_i/2
	cmp/hi	r7,r3		! 474	[c=4 l=2]  cmpgtusi_t

		! when here: T bit = r3 > #3
		! this is the 'default' case
.L153:
		! always branch into nowhere
	bt	.L11		! 475	[c=17 l=2]  *cbranch_t <<< bad jump


So somehow it hits the case that is supposed to be unreachable.
Comment 17 Andrew Pinski 2020-02-20 19:25:06 UTC
In the original code we have:
 if ((uintptr_t)p % 4) {
     int l = 4 - (uintptr_t)p % 4;
     p += l;
     switch (l) {

l range should be 0...3
Comment 18 Oleg Endo 2020-02-20 23:53:37 UTC
(In reply to Andrew Pinski from comment #17)
> In the original code we have:
>  if ((uintptr_t)p % 4) {
>      int l = 4 - (uintptr_t)p % 4;
>      p += l;
>      switch (l) {
> 
> l range should be 0...3


Ha!  This code is an autostereogram.  You gotta stare at it until something comes out of it (or falls in) ...

  if (0 || e - p >= 4)
  {
    if ((uintptr_t)p % 4)
    {
      // when here, p % 4 is never zero.

      // thus, l = 4 - {3|2|1}
      int l = 4 - (uintptr_t)p % 4;

However, that's not where it crashes.  It's in the second switch statement.  I assume that's because it's never supposed to get there, but it does.

What the code does is trying to walk an array of bytes in 4-byte steps.  For that it potentially steps 0...3 bytes to get a 4-byte aligned pointer 'p', then does the 4-byte steps in the for loop, then does  the remaining 0...3 bytes after the loop.

Perhaps this line

    p = (const char *)s;

somehow results in wrong code with p not being updated correctly, and then (e - p) is not in the range {3|2|1|0} as the code expects.
Comment 19 Andrew Pinski 2020-02-21 00:32:04 UTC
    t = (const uintptr_t *)(e - (4 -1));

is problemantic though.  e is not known to be aligned to uintptr_t.
Comment 20 Oleg Endo 2020-02-21 07:33:52 UTC
(In reply to Andrew Pinski from comment #19)
>     t = (const uintptr_t *)(e - (4 -1));
> 
> is problemantic though.  e is not known to be aligned to uintptr_t.

That's right.  But it makes me wonder, why this has been discovered only on SH with, seemingly caused by fcross-jumping optimization option.  There are other more popular strict-alignment targets like ARM ... something is smelly, I think.
Comment 21 Andrew Pinski 2020-02-21 07:38:25 UTC
(In reply to Oleg Endo from comment #20)
> (In reply to Andrew Pinski from comment #19)
> >     t = (const uintptr_t *)(e - (4 -1));
> > 
> > is problemantic though.  e is not known to be aligned to uintptr_t.
> 
> That's right.  But it makes me wonder, why this has been discovered only on
> SH with, seemingly caused by fcross-jumping optimization option.  There are
> other more popular strict-alignment targets like ARM ... something is
> smelly, I think.

I think it is more by accident.    strict-alginment here should not make a difference really as it is undefined even on non-strict targets.  fcross-jumping in this case causes the BB that contains __builtin_unreachable to go to an invalid basic-block which is valid optimization which just happens on sh and for some reason not arm or other targets.  I have not looked into the code or even the RTL to double check this theory though.
Comment 22 Oleg Endo 2020-02-22 09:34:57 UTC
(In reply to Andrew Pinski from comment #21)
> 
> I think it is more by accident.    strict-alginment here should not make a
> difference really as it is undefined even on non-strict targets. 
> fcross-jumping in this case causes the BB that contains
> __builtin_unreachable to go to an invalid basic-block which is valid
> optimization which just happens on sh and for some reason not arm or other
> targets.  I have not looked into the code or even the RTL to double check
> this theory though.


But then that would mean, the code is just generally undefined and might reach the "unreachable" cases in any case.

The function 'search_nonascii' is used in the crashing function 'coderange_scan' 3 times.  It's a bit difficult to see what's going on in the resulting code.  Prohibiting the inlining with...

--- "orig ng/string.c.orig"	2019-10-01 20:02:30.000000000 +0900
+++ "orig ng/string.c"	2020-02-22 17:12:02.624621304 +0900
@@ -436,7 +436,7 @@
 
 VALUE rb_fs;
 
-static inline const char *
+static const char * __attribute__((noinline))
 search_nonascii(const char *p, const char *e)
 {
     const uintptr_t *s, *t;

...results in a more straight forward code of course.  In that case the unreachable case just falls through into one of the other cases, so the code will not crash, but it will also not work correctly.  The latter switch is also not translated into a jump table but a series of simple comparisons.

One thing I've noticed ...

    if (0 || e - p >= 4)

this line uses a signed comparison for e-p >= 4 in the final code.
If 'p' is greater than 'e', then this code will do nonsense.  It might then go into the unreachable case in the latter switch.

'p' is modified in the calling function 'coderange_scan' like so

   p += (ret);

if 'ret' is >= 0, where ret is the return value of function 'rb_enc_precise_mbclen', which in turn calls

   (enc)->precise_mbc_enc_len(p,e,enc)

through the macro ONIGENC_PRECISE_MBC_ENC_LEN

I see at least one encoder function that 



Adrian, could please apply the following patch to the original string.c file and try building & running the whole thing again with the original compiler flags, with -fno-cross-jumping and with -O1.  Does one of the added traps go off?


--- "orig ng/string.c.orig"	2019-10-01 20:02:30.000000000 +0900
+++ "orig ng/string.c"	2020-02-22 18:29:54.904783490 +0900
@@ -446,13 +446,15 @@
 # define NONASCII_MASK 0x80808080UL
 #endif
 
+if ( (intptr_t)(e-p) < 0) __builtin_trap ();
+
     if (UNALIGNED_WORD_ACCESS || e - p >= SIZEOF_VOIDP) {
 #if !UNALIGNED_WORD_ACCESS
 	if ((uintptr_t)p % SIZEOF_VOIDP) {
 	    int l = SIZEOF_VOIDP - (uintptr_t)p % SIZEOF_VOIDP;
 	    p += l;
 	    switch (l) {
-	      default: UNREACHABLE;
+	      default: __builtin_trap ();
 #if SIZEOF_VOIDP > 4
 	      case 7: if (p[-7]&0x80) return p-7;
 	      case 6: if (p[-6]&0x80) return p-6;
@@ -481,7 +483,7 @@
     }
 
     switch (e - p) {
-      default: UNREACHABLE;
+      default: __builtin_trap ();
 #if SIZEOF_VOIDP > 4
       case 7: if (e[-7]&0x80) return e-7;
       case 6: if (e[-6]&0x80) return e-6;
Comment 23 Oleg Endo 2020-02-22 09:36:37 UTC
(In reply to Oleg Endo from comment #22)
> 
> I see at least one encoder function that 

... does not check that p is >= e and blindly starts reading data at p. ... so I'd like to try to narrow it down a bit.
Comment 24 Oleg Endo 2020-02-26 14:29:04 UTC
Adrian, have you had a chance to apply the test patch in comment #22 and re-run it?
Comment 25 John Paul Adrian Glaubitz 2020-02-26 14:32:50 UTC
(In reply to Oleg Endo from comment #24)
> Adrian, have you had a chance to apply the test patch in comment #22 and
> re-run it?

I hadn't seen this patch, sorry. I will try that tonight.
Comment 26 Jakub Jelinek 2020-03-12 11:58:41 UTC
GCC 9.3.0 has been released, adjusting target milestone.
Comment 27 Richard Biener 2021-04-30 08:02:13 UTC
Adrian, any results?  (I just assume GCC 11 and trunk are affected now)
Comment 28 John Paul Adrian Glaubitz 2021-04-30 08:37:48 UTC
(In reply to Richard Biener from comment #27)
> Adrian, any results?  (I just assume GCC 11 and trunk are affected now)

Not yet. I'll try to remember it this weekend.
Comment 29 John Paul Adrian Glaubitz 2021-04-30 10:23:33 UTC
(In reply to John Paul Adrian Glaubitz from comment #28)
> Adrian, could please apply the following patch to the original string.c file
> and try building & running the whole thing again with the original compiler
> flags, with -fno-cross-jumping and with -O1.  Does one of the added traps go
> off?
> 
> 
> --- "orig ng/string.c.orig"	2019-10-01 20:02:30.000000000 +0900
> +++ "orig ng/string.c"	2020-02-22 18:29:54.904783490 +0900
> @@ -446,13 +446,15 @@
>  # define NONASCII_MASK 0x80808080UL
>  #endif
>  
> +if ( (intptr_t)(e-p) < 0) __builtin_trap ();
> +
>      if (UNALIGNED_WORD_ACCESS || e - p >= SIZEOF_VOIDP) {
>  #if !UNALIGNED_WORD_ACCESS
>  	if ((uintptr_t)p % SIZEOF_VOIDP) {
>  	    int l = SIZEOF_VOIDP - (uintptr_t)p % SIZEOF_VOIDP;
>  	    p += l;
>  	    switch (l) {
> -	      default: UNREACHABLE;
> +	      default: __builtin_trap ();
>  #if SIZEOF_VOIDP > 4
>  	      case 7: if (p[-7]&0x80) return p-7;
>  	      case 6: if (p[-6]&0x80) return p-6;
> @@ -481,7 +483,7 @@
>      }
>  
>      switch (e - p) {
> -      default: UNREACHABLE;
> +      default: __builtin_trap ();
>  #if SIZEOF_VOIDP > 4
>        case 7: if (e[-7]&0x80) return e-7;
>        case 6: if (e[-6]&0x80) return e-6;

I did not see any of the traps fire. With the patch applied, it builds fine and the Ruby interpreter doesn't crash. I'll attach the full build log.

Without the patch, Ruby crashes, even with the latest gcc-10 version (didn't test gcc-11 yet as gcc-10 is currently the default for Debian unstable).
Comment 30 John Paul Adrian Glaubitz 2021-04-30 10:27:34 UTC
Created attachment 50717 [details]
Build log for ruby 2.5 with Oleg's patch applied
Comment 31 John Paul Adrian Glaubitz 2021-05-02 09:22:17 UTC
(In reply to John Paul Adrian Glaubitz from comment #30)
> Created attachment 50717 [details]
> Build log for ruby 2.5 with Oleg's patch applied

Ah, I forgot to add -O1 and -fno-cross-jumping to CFLAGS.

Are the builtin_traps() optimized out for -O2?

I'm building with the correct flags now.
Comment 32 John Paul Adrian Glaubitz 2021-05-02 09:44:23 UTC
(In reply to John Paul Adrian Glaubitz from comment #31)
> Ah, I forgot to add -O1 and -fno-cross-jumping to CFLAGS.
> 
> Are the builtin_traps() optimized out for -O2?
> 
> I'm building with the correct flags now.

Traps also didn't trigger with -O1 and -fno-cross-jumping.
Comment 33 Richard Biener 2021-06-01 08:16:33 UTC
GCC 9.4 is being released, retargeting bugs to GCC 9.5.
Comment 34 Richard Biener 2022-05-27 09:42:12 UTC
GCC 9 branch is being closed
Comment 35 Jakub Jelinek 2022-06-28 10:39:49 UTC
GCC 10.4 is being released, retargeting bugs to GCC 10.5.
Comment 36 Richard Biener 2023-07-07 10:36:51 UTC
GCC 10 branch is being closed.
Comment 37 Oleg Endo 2023-10-30 07:37:52 UTC
(In reply to John Paul Adrian Glaubitz from comment #32)
> (In reply to John Paul Adrian Glaubitz from comment #31)
> > Ah, I forgot to add -O1 and -fno-cross-jumping to CFLAGS.
> > 
> > Are the builtin_traps() optimized out for -O2?
> > 
> > I'm building with the correct flags now.
> 
> Traps also didn't trigger with -O1 and -fno-cross-jumping.

Adrian, what happened to this issue in the end?  Do you remember?
Comment 38 John Paul Adrian Glaubitz 2023-10-30 07:49:41 UTC
(In reply to Oleg Endo from comment #37)
> (In reply to John Paul Adrian Glaubitz from comment #32)
> > (In reply to John Paul Adrian Glaubitz from comment #31)
> > > Ah, I forgot to add -O1 and -fno-cross-jumping to CFLAGS.
> > > 
> > > Are the builtin_traps() optimized out for -O2?
> > > 
> > > I'm building with the correct flags now.
> > 
> > Traps also didn't trigger with -O1 and -fno-cross-jumping.
> 
> Adrian, what happened to this issue in the end?  Do you remember?

Ruby is still being built with -fno-crossjumping on sh4. Let me check, whether we can drop the flag nowadays with Ruby 3.1 and gcc-13.