lib/os/heap: Compiler bug workaround on ARC
This is a workaround for a compiler bug on (at least) GCC 12.1.0 in Zephyr SDK 0.15.1. The optimizer generates this function with a last instruction that is an unconditional branch (a tail call into the chunk_set() handling). But that means that the NEXT instruction gets decoded as part of the branch delay slot, but that instruction isn't part of this function! Some instructions aren't legal in branch delay slots. One of those is ENTER_S, which is a very common entry instruction for whatever function the linker places after us. It seems like the compiler doesn't understand this problem. Stuff a NOP in to guarantee the code is legal. Comment above is duplicated in the code. The workaround is straightforward once the issue is understood, but the path to get here was hilariously weird. Fixes #54720 Signed-off-by: Andy Ross <andyross@google.com>
This commit is contained in:
parent
9c1076e7f7
commit
668bb3cb22
@ -128,6 +128,23 @@ static void merge_chunks(struct z_heap *h, chunkid_t lc, chunkid_t rc)
|
||||
|
||||
set_chunk_size(h, lc, newsz);
|
||||
set_left_chunk_size(h, right_chunk(h, rc), newsz);
|
||||
|
||||
#if defined(__arc__) && defined(__GNUC__)
|
||||
/* This is a workaround for a compiler bug on (at least) GCC
|
||||
* 12.1.0 in Zephyr SDK 0.15.1. The optimizer generates this
|
||||
* function with a last instruction that is an unconditional
|
||||
* branch (a tail call into the chunk_set() handling). But
|
||||
* that means that the NEXT instruction gets decoded as part
|
||||
* of the branch delay slot, but that instruction isn't part
|
||||
* of this function! Some instructions aren't legal in branch
|
||||
* delay slots. One of those is ENTER_S, which is a very
|
||||
* common entry instruction for whatever function the linker
|
||||
* places after us. It seems like the compiler doesn't
|
||||
* understand this problem. Stuff a NOP in to guarantee the
|
||||
* code is legal.
|
||||
*/
|
||||
__asm__ volatile("nop");
|
||||
#endif
|
||||
}
|
||||
|
||||
static void free_chunk(struct z_heap *h, chunkid_t c)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user