Created attachment 24025 [details] Example Program showing the unexpected behaviour While porting C source (https://github.com/cpldcpu/light_ws2812/blob/master/light_ws2812_AVR/Light_WS2812/light_ws2812.c) to Zig, which uses LLVM as a backend, I noticed that the "rjmp .+0" instructions that are used as 2-cycle NOPs under avr-gcc assembled to "rjmp .-2" (infinite loops) under Zig and LLVM/Clang. Here is some code to reproduce: /* $ clang -target avr-freestanding-eabi -mmcu=atmega32u2 demo_c.c -c -o demo_c.o $ avr-gcc -mmcu=atmega32u2 demo_c.o -o demo_c.elf $ avr-objdump --siassemble=main demo_c.elf demo_c.elf: file format elf32-avr Disassembly of section .text: 00000000 <main>: 0: fe cf rjmp .-4 ; 0xfffffffe <__eeprom_end+0xff7efffe> 2: ff cf rjmp .-2 ; 0x2 <main+0x2> 4: 00 c0 rjmp .+0 ; 0x6 <main+0x6> 6: 80 e0 ldi r24, 0x00 ; 0 8: 90 e0 ldi r25, 0x00 ; 0 a: 08 95 ret */ int main() { asm("rjmp .-2"); asm("rjmp .+0"); asm("rjmp .+2"); } (this file is also attached as demo_c.c) Note that just inspecting the object file created using clang will confusingly show "rjmp .+0" thrice since the actual offset is set using relocation fixups at that stage.