[Bug target/112413] Wrong switch jump table offset

2023-11-12 Thread vincent.riviere at freesbee dot fr via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112413

--- Comment #6 from Vincent Riviere  ---
(In reply to Mikael Pettersson from comment #4)
> Does the `.balignw` filler disappear if you drop `-malign-int`?

No, it stays, but its value becomes 2, so it doesn't cause trouble.

[Bug target/112413] Wrong switch jump table offset

2023-11-06 Thread vincent.riviere at freesbee dot fr via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112413

--- Comment #3 from Vincent Riviere  ---
(In reply to Andrew Pinski from comment #1)
> I don't see any issues with the output of gcc. Are you sure this is not a
> binutils gnu as issue where the offsets are done incorrectly there.

Yes, I'm sure it's a gcc bug.

With the testcase I initially provided, by chance it's the favourable case.
But if I artificially add a misalignment with a nop, for example, the wrong
result appears:

$ cat swi2.c
int g;

void f(int i)
{
asm("nop");
switch (i)
{
case 0: g = 6082; break;
case 1: g = 9332; break;
case 2: g = 5642; break;
case 3: g = 1423; break;
case 4: g = 2152; break;
case 5: g = 6779; break;
case 6: g = 7074; break;
case 7: g = 8280; break;
}
}

$ m68k-linux-gcc -Os -c swi2.c -mlong-jump-table-offsets -malign-int
$ m68k-linux-objdump -d swi2.o

swi2.o:file format elf32-m68k


Disassembly of section .text:

 :
   0:   202f 0004   movel %sp@(4),%d0
   4:   4e71nop
   6:   7207moveq #7,%d1
   8:   b280cmpl %d0,%d1
   a:   6536bcss 42 
   c:   e588lsll #2,%d0
   e:   203b 0808   movel %pc@(18 ,%d0:l),%d0  |right offset
  12:   4efb 0802   jmp %pc@(16 ,%d0:l)  |wrong offset
  16:   284cmoveal %a4,%a4   |harmful filler
  18:    0020   orib #32,%d0
  1c:    002c   orib #44,%d0
  20:    0038   orib #56,%d0

See that:
- actual jump table starts at offset 0x18
- at offset 0x16, a useless "moveal %a4,%a4" instruction is inserted as filler
- at offset 0xe, offset 0x18 is used appropriately for label .L4. So the right
jump table entry is properly read.
- but at offset 0x12, a *wrong* offset 0x16 is used for the jump. That's
actually the offset of the filler, while it should be 0x18 for label .L4.

This can't work:
- the jump table offsets are computed from the start of the jump table
- but jmp, with that "2" hardcoded as offset, expects offsets being relative to
the address right after itself.
So if a filler is inserted between jmp and actual table contents, as in the
example above, the jump occurs to a wrong address.

[Bug target/112413] Wrong switch jump table offset

2023-11-06 Thread vincent.riviere at freesbee dot fr via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112413

--- Comment #2 from Vincent Riviere  ---
Cause is in gcc/config/m68k/linux.h, macro ASM_RETURN_CASE_JUMP:

https://gcc.gnu.org/git/?p=gcc.git;a=blob;f=gcc/config/m68k/linux.h;h=2e1cb5498b86f053d1e9b7c530648dfa186ca4c4;hb=HEAD#l96

jmp %%pc@(2,%0:w)

Offset 2 is hardcoded in the macro. Ideally, it should be replaced with the
label of the first jump table entry. But I guess it isn't possible inside that
macro.

A solution is to force ADDR_VEC_ALIGN to 0, in order to completely disable the
jump table alignment. That's consistent with ASM_RETURN_CASE_JUMP expectations.

#define ADDR_VEC_ALIGN(ADDR_VEC) 0

This should be done for all m68k targets.

[Bug c/112413] New: Wrong switch jump table offset

2023-11-06 Thread vincent.riviere at freesbee dot fr via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112413

Bug ID: 112413
   Summary: Wrong switch jump table offset
   Product: gcc
   Version: 13.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: vincent.riviere at freesbee dot fr
  Target Milestone: ---

In some circumstances, gcc produces bad code for switch instruction.

Main goal of the testcase is to force gcc to produce a jump table.

$ cat swi.c
int g;

void f(int i)
{
switch (i)
{
case 0: g = 6082; break;
case 1: g = 9332; break;
case 2: g = 5642; break;
case 3: g = 1423; break;
case 4: g = 2152; break;
case 5: g = 6779; break;
case 6: g = 7074; break;
case 7: g = 8280; break;
}
}

$ m68k-linux-gcc -Os -S -o - swi.c -mlong-jump-table-offsets -malign-int
#NO_APP
.file   "swi.c"
.text
.align  2
.globl  f
.type   f, @function
f:
move.l 4(%sp),%d0
moveq #7,%d1
cmp.l %d0,%d1
jcs .L1
lsl.l #2,%d0
move.l .L4(%pc,%d0.l),%d0
jmp %pc@(2,%d0:l)
.balignw 4,0x284c   |Potential bug here
.L4:
.long .L11-.L4
.long .L10-.L4
.long .L9-.L4
.long .L8-.L4
.long .L7-.L4
.long .L6-.L4
.long .L5-.L4
.long .L3-.L4
.L11:
move.l #6082,g
.L1:
rts
.L10:
move.l #9332,g
jra .L1
...

As the jmp may not be aligned on a multiple of 4, the .balignw directive may
introduce a 2-byte filler, causing jmp to use a wrong offset.

Same happens with m68k-elf-gcc.

[Bug c++/111279] New: ICE: Segmentation fault with m68k,SJLJ and -malign-int

2023-09-03 Thread vincent.riviere at freesbee dot fr via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111279

Bug ID: 111279
   Summary: ICE: Segmentation fault with m68k,SJLJ and -malign-int
   Product: gcc
   Version: 14.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: vincent.riviere at freesbee dot fr
  Target Milestone: ---

m68k-elf-g++ causes "internal compiler error: Segmentation fault" when
configured for m68k-elf, SJLJ exceptions, and compiling a specific program with
-malign-int.

$ cat >bug.cc <
struct A
{
  A()
  { }

  char buf[4];
};

template
struct B : public A
{
  B()
  { }
};

template
struct C : public B
{
  C() throw()
  { }
};

void f()
{
  C tmp;
}
EOF

gcc was configured with:
~/sources/gcc/configure --target=m68k-elf --disable-nls --disable-multilib
--enable-languages="c,c++" --disable-libstdc++-pch --disable-lto
--enable-sjlj-exceptions

$ /home/vincent/compil/gccelfsjlj.obj/gcc/cc1plus bug.cc -malign-int
 A::A() B::B() C::C() void f() C B A C::C() [with
T = char] C::C() [with T = char] C::C() [with T = char] B::B() [with T
= char] B::B() [with T = char] B::B() [with T = char] A::A() [with T =
char] A::A() [with T = char] A::A() [with T = char]
Analyzing compilation unit
Performing interprocedural optimizations
 <*free_lang_data> {heap 1068k}  {heap 1068k} 
{heap 1068k}  {heap 1348k}  {heap 1348k}
 {heap 1348k}  {heap 1348k}Streaming LTO
  {heap 1348k}  {heap 1348k}  {heap 1348k}
 {heap 1348k}  {heap 1348k}  {heap 1348k}
 {heap 1348k}Assembling functions:
 void f() C::C() [with T = char]during RTL pass: expand

bug.cc: In constructor 'C::C() [with T = char]':
bug.cc:21:5: internal compiler error: Segmentation fault
   21 |   { }
  | ^
0x1174ec3 crash_signal
/home/vincent/sources/gcc/gcc/toplev.cc:314
0x7f7ca4a3c4af ???
./signal/../sysdeps/unix/sysv/linux/x86_64/libc_sigaction.c:0
0xe08653 assign_temp(tree_node*, int, int)
/home/vincent/sources/gcc/gcc/function.cc:976
0xdab01f emit_push_insn(rtx_def*, machine_mode, tree_node*, rtx_def*, unsigned
int, int, rtx_def*, poly_int<1u, long>, rtx_def*, rtx_def*, int, rtx_def*,
bool)
/home/vincent/sources/gcc/gcc/expr.cc:4920
0xc5f915 emit_library_call_value_1(int, rtx_def*, rtx_def*, libcall_type,
machine_mode, int, std::pair*)
/home/vincent/sources/gcc/gcc/calls.cc:4585
0xd765bf emit_library_call(rtx_def*, libcall_type, machine_mode, rtx_def*,
machine_mode)
/home/vincent/sources/gcc/gcc/rtl.h:4343
0xd765bf sjlj_emit_function_enter
/home/vincent/sources/gcc/gcc/except.cc:1212
0xd7b90d sjlj_build_landing_pads
/home/vincent/sources/gcc/gcc/except.cc:1491
0xd7b90d finish_eh_generation()
/home/vincent/sources/gcc/gcc/except.cc:1520
0xc7c1a6 execute
/home/vincent/sources/gcc/gcc/cfgexpand.cc:6940
Please submit a full bug report, with preprocessed source (by using
-freport-bug).
Please include the complete backtrace with any bug report.
See  for instructions.
$ /home/vincent/compil/gccelfsjlj.obj/gcc/cc1plus bug.cc -malign-int
 A::A() B::B() C::C() void f() C B A C::C() [with
T = char] C::C() [with T = char] C::C() [with T = char] B::B() [with T
= char] B::B() [with T = char] B::B() [with T = char] A::A() [with T =
char] A::A() [with T = char] A::A() [with T = char]
Analyzing compilation unit
Performing interprocedural optimizations
 <*free_lang_data> {heap 1068k}  {heap 1068k} 
{heap 1068k}  {heap 1348k}  {heap 1348k}
 {heap 1348k}  {heap 1348k}Streaming LTO
  {heap 1348k}  {heap 1348k}  {heap 1348k}
 {heap 1348k}  {heap 1348k}  {heap 1348k}
 {heap 1348k}Assembling functions:
 void f() C::C() [with T = char]during RTL pass: expand

bug.cc: In constructor 'C::C() [with T = char]':
bug.cc:21:5: internal compiler error: Segmentation fault
   21 |   { }
  | ^
0x1174ec3 crash_signal
/home/vincent/sources/gcc/gcc/toplev.cc:314
0x7f7ca4a3c4af ???
./signal/../sysdeps/unix/sysv/linux/x86_64/libc_sigaction.c:0
0xe08653 assign_temp(tree_node*, int, int)
/home/vincent/sources/gcc/gcc/function.cc:976
0xdab01f emit_push_insn(rtx_def*, machine_mode, tree_node*, rtx_def*, unsigned
int, int, rtx_def*, poly_int<1u, long>, rtx_def*, rtx_def*, int, rtx_def*,
bool)
/home/vincent/sources/gcc/gcc/expr.cc:4920
0xc5f915 emit_library_call_value_1(int, rtx_def*, rtx_def*, libcall_type,
machine_mode, int, std::pair*)
/home/vincent/sources/gcc/gcc/calls.cc:4585
0xd765bf emit_library_call(rtx_def*, libcall_type, machine_mode, rtx_def*,
machine_mode)
/home/vincent/sources/gcc/gcc/rtl.h:4343
0xd765bf sjlj_emit_function_enter
/home/vincent/sources/gcc/gcc/except.cc:1212
0xd7b90d sjlj_build_landing_pads
/home/vincent/sources/gcc/gcc/except.cc:1491
0xd7b90d finish_eh_generation()
/home/vincent/sources/gcc/gcc/except.cc:1520
0xc7c1a6 execute

[Bug target/88160] Error: register save offset not a multiple of 4 only with optimize

2023-07-26 Thread vincent.riviere at freesbee dot fr via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88160

--- Comment #4 from Vincent Riviere  ---
Created attachment 55647
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=55647=edit
Workaround for compiling libgcc with -mcpu=5475 -mshort

Here is a patch for GCC 13.1.0. It allows libgcc to be compiled with -mcpu=5475
-mshort. As a workaround, it uses -fno-combine-stack-adjustments on the
impacted functions.

__attribute__((optimize("-fno-combine-stack-adjustments")))

Of course, it would be much better to fix the root of the issue.

[Bug target/88160] Error: register save offset not a multiple of 4 only with optimize

2023-07-26 Thread vincent.riviere at freesbee dot fr via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88160

--- Comment #3 from Vincent Riviere  ---
There are 2 lightweight workarounds for the OP testcase:
-fno-combine-stack-adjustments
-fno-omit-frame-pointer

$ m68k-elf-gcc -mshort -mcpu=5475 -g -O2 -c test.c
/tmp/ccW6hc6h.s: Assembler messages:
/tmp/ccW6hc6h.s:20: Error: register save offset not a multiple of 4
/tmp/ccW6hc6h.s:21: Error: register save offset not a multiple of 4
/tmp/ccW6hc6h.s:22: Error: register save offset not a multiple of 4

$ m68k-elf-gcc -mshort -mcpu=5475 -g -O2 -c test.c
-fno-combine-stack-adjustments
# OK

$ m68k-elf-gcc -mshort -mcpu=5475 -g -O2 -c test.c -fno-omit-frame-pointer
# OK

[Bug target/88160] Error: register save offset not a multiple of 4 only with optimize

2023-07-25 Thread vincent.riviere at freesbee dot fr via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88160

Vincent Riviere  changed:

   What|Removed |Added

 CC||vincent.riviere at freesbee 
dot fr

--- Comment #2 from Vincent Riviere  ---
I reproduce this bug with GCC 13.1.0 for m68k. It happens when compiling libgcc
with -mcpu=5475 -mshort -O2.

Affected files are:
unwind-dw2.c
unwind-dw2-fde.c
libgcov-driver.c

Workaround: compile with -O1.

[Bug c/110567] New: GCC fails using a register to initialize multiple variables with a constant

2023-07-05 Thread vincent.riviere at freesbee dot fr via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110567

Bug ID: 110567
   Summary: GCC fails using a register to initialize multiple
variables with a constant
   Product: gcc
   Version: 13.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: vincent.riviere at freesbee dot fr
  Target Milestone: ---
Target: m68k-elf

This is about a missed optimization for an obvious case.
GCC fails to use a register to initialize several global variables with the
same constant value.

$ cat foo.c
extern long init;
extern long g1, g2, g3, g4, g5;

void f(void)
{
long val = 12345678;

g1 = val;
g2 = val;
g3 = val;
g4 = val;
g5 = val;
}

$ m68k-elf-gcc -S foo.c -o - -Os
#NO_APP
.file   "foo.c"
.text
.align  2
.globl  f
.type   f, @function
f:
move.l #12345678,g1
move.l #12345678,g2
move.l #12345678,g3
move.l #12345678,g4
move.l #12345678,g5
rts
.size   f, .-f
.ident  "GCC: (GNU) 13.1.0"

We can see that 12345678 is used many times. This is a waste of space and time.

On the other hand, if I replace 12345678 by "init" (an external global
variable) then GCC produces the expected optimized output:

$ m68k-elf-gcc -S foo.c -o - -Os
#NO_APP
.file   "foo.c"
.text
.align  2
.globl  f
.type   f, @function
f:
move.l init,%d0
move.l %d0,g1
move.l %d0,g2
move.l %d0,g3
move.l %d0,g4
move.l %d0,g5
rts
.size   f, .-f
.ident  "GCC: (GNU) 13.1.0"

GCC should be able to optimize a constant initializer, just as it does with a
variable initializer.

I can reproduce the same wrong behaviour with GCC 11.4.0 for x86_64-pc-cygwin
host with -m32:

$ gcc -m32 -S foo.c -o - -Os
.file   "foo.c"
.text
.globl  _f
.def_f; .scl2;  .type   32; .endef
_f:
movl$12345678, _g1
movl$12345678, _g2
movl$12345678, _g3
movl$12345678, _g4
movl$12345678, _g5
ret
.ident  "GCC: (GNU) 11.4.0"

[Bug tree-optimization/102725] -fno-builtin leads to call of strlen since r12-4283-g6f966f06146be768

2023-06-02 Thread vincent.riviere at freesbee dot fr via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102725

--- Comment #8 from Vincent Riviere  ---
This still happens with m68k-elf-gcc 13.1.0.

[Bug c/106349] New: strlen reimplementation produces infinite loop with -Os

2022-07-18 Thread vincent.riviere at freesbee dot fr via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106349

Bug ID: 106349
   Summary: strlen reimplementation produces infinite loop with
-Os
   Product: gcc
   Version: 12.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: vincent.riviere at freesbee dot fr
  Target Milestone: ---
Target: m68k-elf

Compiling a function named strlen with strlen-like body generates an infinite
loop.

$ cat bug.c
#include 

size_t strlen(const char *str)
{
size_t n;

for (n = 0; *str++; n++);

return n;
}

$ m68k-elf-gcc -S bug.c -o - -Os
#NO_APP
.file   "bug.c"
.text
.align  2
.globl  strlen
.type   strlen, @function
strlen:
jra strlen
.size   strlen, .-strlen
.ident  "GCC: (GNU) 12.1.0"

The only generated code is the infinite loop. That's a nonsense.
This issue doesn't occur with -O2.