odin-lang / Odin

Odin Programming Language
https://odin-lang.org
BSD 3-Clause "New" or "Revised" License
6.57k stars 572 forks source link

Cannot use global matrices with variables as index #3983

Open caiolaytynher opened 1 month ago

caiolaytynher commented 1 month ago

Context

When you define a vector as a compile time constant, you can only access it's fields with compile time constants. That's not the case with matrices, you can access the fields of a compile time constant matrix with variables just fine. However, trying to access a globally defined matrix inside of a procedure, if it is not a constant value it gives a llvm compile error that is unreadable. However, if you just define the matrix locally to the procedure or pass it by argument, the error stops.

I don't know if this is intended or not, but definitely seems like this shouldn't happen. If otherwise this is intended, then I suggest working on the compile error.

Odin and OS Info

Odin: dev-2024-07:fc5ce30 OS: Windows 10 Professional (version: 22H2), build 19045.4651 CPU: AMD Ryzen 5 5500U with Radeon Graphics RAM: 5989 MiB Backend: LLVM 18.1.8

Expected Behavior

I should be able to use matrices defined as variables in the global scope with other variables as indexes without having to pass the matrix as an argument.

Current Behavior

If you define a matrix in the global scope that is being used inside of a procedure, then trying to access it's fields using variables gives compile errors.

Steps to Reproduce

Please provide detailed steps for reproducing the issue.

Just run the following:

package main

m := matrix[3, 3]f32{
    1, 0, 0, 
    0, 1, 0, 
    0, 0, 1, 
}

main :: proc() {
    row, col := 1, 2
    _ = m[row, col]
}

Failure Logs

Error:

LLVM CODE GEN FAILED FOR PROCEDURE: main.entry_point
define void @main.entry_point(ptr noalias nocapture nonnull %__.context_ptr) {
decls:
  %row = alloca i64, align 8
  %col = alloca i64, align 8
  br label %entry

entry:                                            ; preds = %decls
  store i64 1, ptr %row, align 8
  store i64 2, ptr %col, align 8
  %0 = load i64, ptr %row, align 8
  %1 = load i64, ptr %col, align 8
  %2 = mul i64 %1, 3
  %3 = add i64 %0, %2
  call void @runtime.matrix_bounds_check_error(ptr @"ggv$0", i32 18, i32 8, i64 %0, i64 %1, i64 3, i64 3)
  %4 = load float, ptr getelementptr ([9 x float], ptr @main.m, i64 0, i64 %3), align 4
  ret void
}

Use of instruction is not an instruction!
  %3 = add i64 %0, %2
Hyrtwol commented 1 month ago

ditto, also bumped into this one (shader.varying_uv is a float2x3)

#unroll for vi in 0..<3 {
    shader.varying_uv[vi] = vertices[t[vi]].xy
}

fails with a dump, where this works

shader.varying_uv[0] = vertices[t[0]].xy
shader.varying_uv[1] = vertices[t[1]].xy
shader.varying_uv[2] = vertices[t[2]].xy

so constants works via indexing