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

Vector2 gets incorrect type in LLVM IR for arm32 #4576

Open
Pingar5 opened this issue Dec 14, 2024 · 0 comments · May be fixed by #4579
Open

Vector2 gets incorrect type in LLVM IR for arm32 #4576

Pingar5 opened this issue Dec 14, 2024 · 0 comments · May be fixed by #4579

Comments

@Pingar5
Copy link
Contributor

Pingar5 commented Dec 14, 2024

Context

I am building for linux_arm32 (for a raspberry pi) so I am building to object files on my windows PC using this command:
odin build . -target:linux_arm32 -build-mode:obj -microarch:mpcore

Then on the pi, I am compiling those object files in with my c code (which in the real project is raylib) using this CMakeLists.txt:

cmake_minimum_required(VERSION 3.5)
set(CMAKE_C_STANDARD 99)

project(game)

add_executable(game
    game-main.o game-runtime.o game.o
    main.c
)
  • Operating System & Odin Version:
    Odin: dev-2024-10-nightly:af9ae48
    OS: Windows 10 Enterprise (version: 22H2), build 19045.5247
    CPU: 11th Gen Intel(R) Core(TM) i5-11600KF @ 3.90GHz
    RAM: 32645 MiB
    Backend: LLVM 18.1.8

Expected Behavior

LLVM IR should use [2 x float] for Vector 2 type

Current Behavior

LLVM IR is using [2 x i32] for Vector2 type, this causes the ARM machine code to use the wrong registers when calling the procedure (It uses r0-r6 but should use s0-s6).

Failure Information (for bugs)

Please help provide information about the failure if this is a bug. If it is not a bug, please remove the rest of this template.

Steps to Reproduce

  1. Build the following file to LLVM IR:
package repro

Vector2 :: [2]f32

foreign _ {
	draw_line :: proc "c" (start: Vector2, end: Vector2, thick: f32) ---
}

repro :: proc "c" () {
	start := Vector2{100, 200}
	end := Vector2{200, 300}

	draw_line(start, end, 60)
}
  1. This is what you get:
; ModuleID = 'odin_package-repro'
source_filename = "odin_package-repro"
target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
target triple = "armv6k-unknown-linux-gnueabihf"

declare void @draw_line([2 x i32], [2 x i32], float)

define void @repro.main(ptr noalias nocapture nonnull %__.context_ptr) {
decls:
  %start = alloca [2 x float], align 4
  %end = alloca [2 x float], align 4
  br label %entry

entry:                                            ; preds = %decls
  store [2 x float] [float 1.000000e+02, float 2.000000e+02], ptr %start, align 4
  store [2 x float] [float 2.000000e+02, float 3.000000e+02], ptr %end, align 4
  %0 = load [2 x i32], ptr %start, align 4
  %1 = load [2 x i32], ptr %end, align 4
  call void @draw_line([2 x i32] %0, [2 x i32] %1, float 6.000000e+01)
  ret void
}

When built to an object file you get this assembly:

        00010000 00 48 2d e9     stmdb      sp!,{r11,lr}
        00010004 0d b0 a0 e1     cpy        r11,sp
        00010008 10 d0 4d e2     sub        sp,sp,#0x10
        0001000c d2 07 a0 e3     mov        r0,#0x3480000
        00010010 01 01 80 e3     orr        r0,r0,#0x40000000
        00010014 0c 00 8d e5     str        r0,[sp,#local_c]
        00010018 b2 17 a0 e3     mov        r1,#0x2c80000
        0001001c 01 11 81 e3     orr        r1,r1,#0x40000000
        00010020 08 10 8d e5     str        r1,[sp,#local_10]
        00010024 96 18 a0 e3     mov        r1,#0x960000
        00010028 43 14 81 e3     orr        r1,r1,#0x43000000
        0001002c 04 10 8d e5     str        r1,[sp,#local_14]
        00010030 00 00 8d e5     str        r0,[sp,#0x0]=>local_18
        00010034 08 00 9d e5     ldr        r0,[sp,#local_10]
        00010038 0c 10 9d e5     ldr        r1,[sp,#local_c]
        0001003c 00 20 9d e5     ldr        r2,[sp,#0x0]=>local_18
        00010040 04 30 9d e5     ldr        r3,[sp,#local_14]
        00010044 02 0a 9f ed     vldr.32    s0,[pc,#0x8]=>DAT_00010054                       = 42700000h
        00010048 ec 03 00 eb     bl         <EXTERNAL>::draw_line                            undefined draw_line()
        0001004c 0b d0 a0 e1     cpy        sp,r11
        00010050 00 88 bd e8     ldmia      sp!,{r11,pc}

Notice that it is loading float values into r registers.

Here is the correct assembly generated by clang (for a functionally identical c file):

        00010000 00 48 2d e9     stmdb      sp!,{r11,lr}
        00010004 0d b0 a0 e1     cpy        r11,sp
        00010008 10 d0 4d e2     sub        sp,sp,#0x10
        0001000c 44 00 9f e5     ldr        r0,[DAT_00010058]                                = 00010068h
        00010010 00 10 90 e5     ldr        r1,[r0,#0x0]=>.L__const.repro.start              = 4348000042C80000h
        00010014 04 00 90 e5     ldr        r0,[r0,#0x4]=>.L__const.repro.start+4
        00010018 0c 00 8d e5     str        r0,[sp,#local_c]
        0001001c 08 10 8d e5     str        r1,[sp,#local_10]
        00010020 34 00 9f e5     ldr        r0,[DAT_0001005c]                                = 00010070h
        00010024 00 10 90 e5     ldr        r1,[r0,#0x0]=>.L__const.repro.end                = 4396000043480000h
        00010028 04 00 90 e5     ldr        r0,[r0,#0x4]=>.L__const.repro.end+4
        0001002c 04 00 8d e5     str        r0,[sp,#local_14]
        00010030 00 10 8d e5     str        r1,[sp,#0x0]=>local_18
        00010034 02 0a 9d ed     vldr.32    s0,[sp,#local_10]
        00010038 03 0a dd ed     vldr.32    s1,[sp,#local_c]
        0001003c 00 1a 9d ed     vldr.32    s2,[sp]=>local_18
        00010040 01 1a dd ed     vldr.32    s3,[sp,#local_14]
        00010044 02 2a 9f ed     vldr.32    s4,[pc,#0x8]=>DAT_00010054                       = 42700000h
        00010048 ec 03 00 eb     bl         <EXTERNAL>::draw_line                            undefined draw_line()
        0001004c 0b d0 a0 e1     cpy        sp,r11
        00010050 00 88 bd e8     ldmia      sp!,{r11,pc}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
1 participant