Skip to content

[AVR] Branch offset off by two in llvm-mc's output #60019

Closed
@gergoerdi

Description

@gergoerdi

Jump straight to #60019 (comment) to avoid red herrings and dead ends...

I started digging into #59962 and #47093 to figure out what exactly is broken, and it seems that as of 5fcdf76, branch offsets are in general mis-assembled. This can be demonstrated with very simple, very small inputs.

First, assembly with llvm-mc from hand-written code:

	.text
        cpi r24, 42
	brne .FOO
        ret
.FOO:
        rjmp .FOO

I have tried assembling this with llvm-mc thus:

$ llvm-mc --arch=avr --mcpu=atmega32u4 -filetype=obj foo.s -o foo.s.o
$ avr-objdump -d foo.s.o

foo.s.o:     file format elf32-avr


Disassembly of section .text:

00000000 <.FOO-0x6>:
   0:	8a 32       	cpi	r24, 0x2A	; 42
   2:	01 f4       	brne	.+0      	; 0x4 <.FOO-0x2>          <--- HERE
   4:	08 95       	ret

00000006 <.FOO>:
   6:	00 c0       	rjmp	.+0      	; 0x8 <.FOO+0x2>

At the marked line, we see that brne .+2 (pointing to .FOO) has been mis-assembled ito brne .+0 (a nop).

For the second test, we can write LLVM IR and try compiling that with llc:

target datalayout = "e-P1-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8-a:8"
target triple = "avr-unknown-unknown"

define internal fastcc i8 @foo(i8 %x) {
start:
  %b = icmp eq i8 %x, 42
  br i1 %b, label %bb1, label %bb2
bb1:
  ret i8 12
bb2:
  ret i8 34
}

If we ask llc to produce an assembly file, that one looks correct:

$ llc -march=avr -mcpu=atmega32u4 -filetype=asm bar.ll -o -
	.text
.set __tmp_reg__, 0
.set __zero_reg__, 1
.set __SREG__, 63
.set __SP_H__, 62
.set __SP_L__, 61
	.file	"bar.ll"
	.p2align	1                               ; -- Begin function foo
	.type	foo,@function
foo:                                    ; @foo
; %bb.0:                                ; %start
	cpi	r24, 42
	brne	.LBB0_2
; %bb.1:                                ; %bb1
	ldi	r24, 12
	ret
.LBB0_2:                                ; %bb2
	ldi	r24, 34
	ret
.Lfunc_end0:
	.size	foo, .Lfunc_end0-foo
                                        ; -- End function

However, if we go to object file, we have the same problem that the branch offset in %bb.0 becomes zero:

$ llc -march=avr -mcpu=atmega32u4 -filetype=obj bar.ll -o bar.ll.o
$ avr-objdump -d bar.ll.o

bar.ll.o:     file format elf32-avr


Disassembly of section .text:

00000000 <foo>:
   0:	8a 32       	cpi	r24, 0x2A	; 42
   2:	01 f4       	brne	.+0      	; 0x4 <foo+0x4>       <---- HERE
   4:	8c e0       	ldi	r24, 0x0C	; 12
   6:	08 95       	ret
   8:	82 e2       	ldi	r24, 0x22	; 34
   a:	08 95       	ret

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions