Skip to content

Switch lookup gets turned into a branch to a wrong address #46

Closed
@gergoerdi

Description

@gergoerdi

I have the following Rust code:

#[inline(never)]
pub fn decode(n: u8) -> bool {
    match n {
        0x0 => Some(()),
        0x1 => Some(()),
        0x2 => Some(()),
        0x3 => Some(()),
        0x6 => Some(()),
        _ => None
    }.is_some()
}

It is turned into the following LLVM IR:

; ModuleID = 'external.cgu-0.rs'
source_filename = "external.cgu-0.rs"
target datalayout = "e-p:16:16:16-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-n8"
target triple = "avr-atmel-none"

; Function Attrs: noinline nounwind readnone uwtable
define zeroext i1 @_ZN8external6decode17hac8ff9e06698feb0E(i8) unnamed_addr #0 {
start:
  %1 = icmp ult i8 %0, 7
  br i1 %1, label %switch.lookup, label %bb7

switch.lookup:                                    ; preds = %start
  %2 = sext i8 %0 to i16
  %3 = and i16 %2, -2
  %.cmp = icmp ne i16 %3, 4
  br label %bb7

bb7:                                              ; preds = %start, %switch.lookup
  %.sink = phi i1 [ %.cmp, %switch.lookup ], [ false, %start ]
  ret i1 %.sink
}

attributes #0 = { noinline nounwind readnone uwtable }

Compiling that LLVM IR, the resulting object file is, I believe, wrong.

$ avr-objdump -dr external-4c5561d448dd0019.o 

external-4c5561d448dd0019.o:     file format elf32-avr


Disassembly of section .text:

00000000 <_ZN8external6decode17hac8ff9e06698feb0E>:
   0:	87 30       	cpi	r24, 0x07	; 7
   2:	90 e0       	ldi	r25, 0x00	; 0
   4:	00 f4       	brcc	.+0      	; 0x6 <_ZN8external6decode17hac8ff9e06698feb0E+0x6>
			4: R_AVR_7_PCREL	.text+0x1e
   6:	28 2f       	mov	r18, r24
   8:	38 2f       	mov	r19, r24
   a:	33 0f       	add	r19, r19
   c:	33 0b       	sbc	r19, r19
   e:	2e 7f       	andi	r18, 0xFE	; 254
  10:	44 e0       	ldi	r20, 0x04	; 4
  12:	50 e0       	ldi	r21, 0x00	; 0
  14:	91 e0       	ldi	r25, 0x01	; 1
  16:	24 17       	cp	r18, r20
  18:	35 07       	cpc	r19, r21
  1a:	01 f4       	brne	.+0      	; 0x1c <_ZN8external6decode17hac8ff9e06698feb0E+0x1c>
			1a: R_AVR_7_PCREL	.text+0x26
  1c:	90 e0       	ldi	r25, 0x00	; 0

0000001e <LBB0_4>:
  1e:	91 70       	andi	r25, 0x01	; 1
  20:	89 2f       	mov	r24, r25
  22:	99 27       	eor	r25, r25
  24:	08 95       	ret

Note that the relocation for 0x1a targets 0x26, which is after the end of the function. I believe the correct target would be 0x1e.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions