Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiplication instructions generated for target that does not support them #124

Closed
Rahix opened this issue Jan 12, 2019 · 4 comments
Closed

Comments

@Rahix
Copy link

Rahix commented Jan 12, 2019

When compiling the following code:

#![no_std]
#![no_main]
#![feature(lang_items, panic_handler)]

#[no_mangle]
pub extern fn main() {
    unsafe {
        let x: u8 = core::ptr::read_volatile(42 as *mut u8);
        let y = x * 13;
        core::ptr::write_volatile(42 as *mut u8, y);
    }
}

pub mod std {
    #[lang = "eh_personality"]
    pub unsafe extern "C" fn rust_eh_personality(
        _state: (),
        _exception_object: *mut (),
        _context: *mut (),
    ) -> () {
    }

    #[panic_handler]
    fn panic(_info: &::core::panic::PanicInfo) -> ! {
        loop { }
    }
}

using rustc --target=avr-attiny85 main.rs --emit=asm and the following target:

{
  "llvm-target": "avr-unknown-unknown",
  "cpu": "attiny85",
  "target-endian": "little",
  "target-pointer-width": "16",
  "target-c-int-width": "16",
  "os": "unknown",
  "target-env": "",
  "target-vendor": "unknown",
  "arch": "avr",
  "data-layout": "e-P1-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8-a:8",

  "executables": true,

  "linker": "avr-gcc",
  "linker-flavor": "gcc",
  "pre-link-args": {
    "gcc": ["-Os", "-mmcu=attiny85"]
  },
  "exe-suffix": ".elf",
  "post-link-args": {
    "gcc": ["-Wl,--gc-sections"]
  },

  "singlethread": true,
  "no-builtins": false,

  "no-default-libraries": false
}

LLVM emits a mul instruction, even though they are not supported on attiny85.

Unfortunately I don't have llvm tools available right now, to reduce the IR. I guess this is the responsible line:

  %1 = call addrspace(1) { i8, i1 } @llvm.umul.with.overflow.i8(i8 %0, i8 13)
@dylanmckay
Copy link
Member

Here's a reproduction

declare {i8, i1 } @llvm.umul.with.overflow.i8(i8, i8) 

define {i8, i1} @test(i8 %a) {
  %1 = call addrspace(1) { i8, i1 } @llvm.umul.with.overflow.i8(i8 %a, i8 13) 
  ret {i8, i1} %1
}

Compile with

./bin/llc -march=avr -mcpu=attiny85 test.ll -o -  

Outputs

test:                                   ; @test
; %bb.0:
        movw    r26, r24
        ldi     r24, 13
        mul     r22, r24 ; HERE'S THE MUL
        mov     r25, r1
        clr     r1
        st      X+, r0
        ldi     r24, 1
        cpi     r25, 0
        brne    LBB0_2
; %bb.1:
        ldi     r24, 0
LBB0_2:
        andi    r24, 1
        st      X, r24
        ret
.Lfunc_end0:
        .size   test, .Lfunc_end0-test
                                        ; -- End function

@aykevl
Copy link

aykevl commented Jan 17, 2019

I think I've seen a mul without the llvm.umul.with.overflow.i8 intrinsic, but I'm not sure. I should make a repro out of that. Noting it here in case it is relevant.

bogner pushed a commit to bogner/llvm-zipper-prototype that referenced this issue Jan 18, 2019
…ave hardware MUL

This change modifies the LLVM ISel lowering settings so that
8-bit/16-bit multiplication is expanded to calls into the compiler
runtime library if the MCU being targeted does not support
multiplication in hardware.

Before this, MUL instructions would be generated on CPUs like the
ATtiny85, triggering a CPU reset due to an illegal instruction at
runtime.

First raised in avr-rust/rust-legacy-fork#124.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@351523 91177308-0d34-0410-b5e6-96231b3b80d8
llvm-git-migration pushed a commit to llvm/llvm-project that referenced this issue Jan 18, 2019
…ave hardware MUL

This change modifies the LLVM ISel lowering settings so that
8-bit/16-bit multiplication is expanded to calls into the compiler
runtime library if the MCU being targeted does not support
multiplication in hardware.

Before this, MUL instructions would be generated on CPUs like the
ATtiny85, triggering a CPU reset due to an illegal instruction at
runtime.

First raised in avr-rust/rust-legacy-fork#124.

llvm-svn: 351523
@dylanmckay
Copy link
Member

Fixed in upstream LLVM at llvm-project/llvm-project-20170507@a684637f8b667527882ac4f50ea9ecb482e248aa.

dylanmckay pushed a commit to avr-rust/llvm that referenced this issue Jan 18, 2019
…ave hardware MUL

This change modifies the LLVM ISel lowering settings so that
8-bit/16-bit multiplication is expanded to calls into the compiler
runtime library if the MCU being targeted does not support
multiplication in hardware.

Before this, MUL instructions would be generated on CPUs like the
ATtiny85, triggering a CPU reset due to an illegal instruction at
runtime.

First raised in avr-rust/rust-legacy-fork#124.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@351523 91177308-0d34-0410-b5e6-96231b3b80d8
earl pushed a commit to earl/llvm-mirror that referenced this issue Jan 18, 2019
…ave hardware MUL

This change modifies the LLVM ISel lowering settings so that
8-bit/16-bit multiplication is expanded to calls into the compiler
runtime library if the MCU being targeted does not support
multiplication in hardware.

Before this, MUL instructions would be generated on CPUs like the
ATtiny85, triggering a CPU reset due to an illegal instruction at
runtime.

First raised in avr-rust/rust-legacy-fork#124.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@351523 91177308-0d34-0410-b5e6-96231b3b80d8
@dylanmckay
Copy link
Member

Cherry-picked in a3b0834

dylanmckay pushed a commit to dylanmckay/llvm that referenced this issue Jan 20, 2019
…ave hardware MUL

This change modifies the LLVM ISel lowering settings so that
8-bit/16-bit multiplication is expanded to calls into the compiler
runtime library if the MCU being targeted does not support
multiplication in hardware.

Before this, MUL instructions would be generated on CPUs like the
ATtiny85, triggering a CPU reset due to an illegal instruction at
runtime.

First raised in avr-rust/rust-legacy-fork#124.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@351523 91177308-0d34-0410-b5e6-96231b3b80d8
dylanmckay added a commit to dylanmckay/llvm that referenced this issue Jan 20, 2019
…ave hardware MUL

This change modifies the LLVM ISel lowering settings so that
8-bit/16-bit multiplication is expanded to calls into the compiler
runtime library if the MCU being targeted does not support
multiplication in hardware.

Before this, MUL instructions would be generated on CPUs like the
ATtiny85, triggering a CPU reset due to an illegal instruction at
runtime.

First raised in avr-rust/rust-legacy-fork#124.
llvm-git-migration pushed a commit to llvm/llvm-project that referenced this issue May 23, 2019
------------------------------------------------------------------------
r351523 | dylanmckay | 2019-01-17 22:10:41 -0800 (Thu, 17 Jan 2019) | 12 lines

[AVR] Expand 8/16-bit multiplication to libcalls on MCUs that don't have hardware MUL

This change modifies the LLVM ISel lowering settings so that
8-bit/16-bit multiplication is expanded to calls into the compiler
runtime library if the MCU being targeted does not support
multiplication in hardware.

Before this, MUL instructions would be generated on CPUs like the
ATtiny85, triggering a CPU reset due to an illegal instruction at
runtime.

First raised in avr-rust/rust-legacy-fork#124.
------------------------------------------------------------------------

llvm-svn: 361551
dtzWill pushed a commit to llvm-mirror/llvm that referenced this issue May 23, 2019
------------------------------------------------------------------------
r351523 | dylanmckay | 2019-01-17 22:10:41 -0800 (Thu, 17 Jan 2019) | 12 lines

[AVR] Expand 8/16-bit multiplication to libcalls on MCUs that don't have hardware MUL

This change modifies the LLVM ISel lowering settings so that
8-bit/16-bit multiplication is expanded to calls into the compiler
runtime library if the MCU being targeted does not support
multiplication in hardware.

Before this, MUL instructions would be generated on CPUs like the
ATtiny85, triggering a CPU reset due to an illegal instruction at
runtime.

First raised in avr-rust/rust-legacy-fork#124.
------------------------------------------------------------------------

git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_80@361551 91177308-0d34-0410-b5e6-96231b3b80d8
ajohnson-uoregon pushed a commit to ajohnson-uoregon/clang-rewrite-only that referenced this issue Jul 17, 2022
------------------------------------------------------------------------
r351523 | dylanmckay | 2019-01-17 22:10:41 -0800 (Thu, 17 Jan 2019) | 12 lines

[AVR] Expand 8/16-bit multiplication to libcalls on MCUs that don't have hardware MUL

This change modifies the LLVM ISel lowering settings so that
8-bit/16-bit multiplication is expanded to calls into the compiler
runtime library if the MCU being targeted does not support
multiplication in hardware.

Before this, MUL instructions would be generated on CPUs like the
ATtiny85, triggering a CPU reset due to an illegal instruction at
runtime.

First raised in avr-rust/rust-legacy-fork#124.
------------------------------------------------------------------------

llvm-svn: 361551
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants