Skip to content
This repository has been archived by the owner on Sep 2, 2018. It is now read-only.

mul instruction is generated on ATtiny, even though it is not supported #216

Open
cpldcpu opened this issue Jul 17, 2016 · 3 comments
Open

Comments

@cpldcpu
Copy link

cpldcpu commented Jul 17, 2016

Example code:

#include <avr/io.h>
void test(uint8_t *ptr, uint16_t index) {
    ptr[index+index+index]=7;
}

Interestingly LLVM infers a multiplication from the triple addition. This may be beneficial on some architectures, but certainly is not so on AVR.

To make things worse, very inefficient code with 8x single bit shift and multiplications is generated even on the ATtiny, where it is not supported.

The same code is generated for ATmega, ATtiny, and the tiny core:

    .text
    .file   "test2.c"
    .globl  test
    .p2align    1
    .type   test,@function
test:                                   ; @test
; BB#0:                                 ; %entry
    ldi r18, 3
    muls    r23, r18
    mov r19, r0
    eor r1, r1
    mul r22, r18
    mov r20, r1
    eor r1, r1
    add r20, r19
    lsl r20
    rol r21
    lsl r20
    rol r21
    lsl r20
    rol r21
    lsl r20
    rol r21
    lsl r20
    rol r21
    lsl r20
    rol r21
    lsl r20
    rol r21
    lsl r20
    rol r21
    mov r26, r0
    eor r27, r27
    or  r26, r20
    or  r27, r21
    add r26, r24
    adc r27, r25
    ldi r24, 7
    st  X, r24
    ret
.Lfunc_end0:
    .size   test, .Lfunc_end0-test

@shepmaster
Copy link

very inefficient code with 8x single bit shift

That's a side-effect of some 16-bit fakery that happens.

Multiplication should be able to be gated; there's a supportsMultiplication flag scattered about. Perhaps some variant of the -mattr=mul flag? Although I'd hope that specifying the Tiny would set all the right things.

How are you selecting which AVR variant you are using? Can you include the compiler command?

@cpldcpu
Copy link
Author

cpldcpu commented Jul 17, 2016

Sure. This is the compiler command I used:

TARGET=attiny85
DEVICE=__AVR_ATtiny85__

clang -O3 -c -S -I /usr/lib/avr/include -D $DEVICE --target=avr $1.c -o $1_llvm_t85.s -mmcu=$TARGET 

@cpldcpu
Copy link
Author

cpldcpu commented Jul 17, 2016

That's a side-effect of some 16-bit fakery that happens.

The shifts are effectively used to more one byte from one register to the other. Seems somewhat odd.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants