`llvm.add` is interpreted as `llvm.addrspacecast`

./std/primitive.mojo:71:64: error: 'llvm.addrspacecast' op requires a single operand
value: __mlir_op.`llvm.add`[_type: __mlir_type.i32](self.value, rhs.value)
./std/primitive.mojo:71:64: error: 'llvm.addrspacecast' op requires a single operand
value: __mlir_op.`llvm.add`[_type: __mlir_type.i32](self.value, rhs.value)
This feels like it's not working correctly, considering add is documented as something else.
62 Replies
jmky
jmky15mo ago
Can you share the actual docs on LLVM dialect for this Op? I also find that the translation between Mojo syntax to dialect is a black box to us For eg the index.casts index.castu syntax are different from Mojo's
TeamPuzel
TeamPuzelOP15mo ago
this is why they're different
No description
TeamPuzel
TeamPuzelOP15mo ago
both llvm and index dialects are off by one at least that's what it looks like :D well, sometimes
ModularBot
ModularBot15mo ago
Congrats @TeamPuzel, you just advanced to level 13!
TeamPuzel
TeamPuzelOP15mo ago
it seems like you have to use the one before what you actually want
TeamPuzel
TeamPuzelOP15mo ago
it's the second one
TeamPuzel
TeamPuzelOP15mo ago
whichever one I use mojo seems to take the next
No description
Stole
Stole15mo ago
This is quite funny. On my machine, I can't seem to use anything from the llvm dialect (and haven't tried to before), it can't find the llvm.add and other __mlir_ops, but the index dialect works fine and isn't one off as yours seems to be. For example, I can run the following, and it prints 64:
print(__mlir_op.`index.sizeof`[_type : __mlir_type.index]())
print(__mlir_op.`index.sizeof`[_type : __mlir_type.index]())
Okay, now I get the same one-off error with llvm dialect. Strange. (just in case, my mojo --version is mojo 0.2.1 (64d14e85))
TeamPuzel
TeamPuzelOP15mo ago
odd, I have the exact same version Not all of them are one off which makes it even more weird to me Though if I actually try to use llvm.ashr (which I assume must be add for me) it gives me an add error!
Stole
Stole15mo ago
First my LSP says that llvm.add is unregistered, then running it in console says llvm.addrspacecast wants a single operand.
TeamPuzel
TeamPuzelOP15mo ago
Yeah, I'm using ssh into a linux laptop with too little ram to handle the lsp so I don't even see those :D if you use ashr you will get add
Stole
Stole15mo ago
On my end it crashes if I replace add with ashr 🤷‍♂️
TeamPuzel
TeamPuzelOP15mo ago
unfortunately trying to add i32 in this way crashes llvm
mojo: /__w/modular/modular/third-party/llvm-project/llvm/include/llvm/Support/Casting.h:572: decltype(auto) llvm::cast(From &) [To = mlir::BytecodeOpInterface, From = mlir::Operation]: Assertion `isa<To>(Val) && "cast<Ty>() argument of incompatible type!"' failed.
Please submit a bug report to https://github.com/modularml/mojo/issues and include the crash backtrace along with all the relevant source codes.
Stack dump:
0. Program arguments: mojo run ./test.mojo
Stack dump without symbol names (ensure you have llvm-symbolizer in your PATH or set the environment var `LLVM_SYMBOLIZER_PATH` to point to it):
0 mojo 0x0000561a0e3f6957
1 mojo 0x0000561a0e3f452e
2 mojo 0x0000561a0e3f702f
3 libc.so.6 0x00007f5596442520
4 libc.so.6 0x00007f5596496a7c pthread_kill + 300
5 libc.so.6 0x00007f5596442476 raise + 22
6 libc.so.6 0x00007f55964287f3 abort + 211
7 libc.so.6 0x00007f559642871b
8 libc.so.6 0x00007f5596439e96
9 mojo 0x0000561a0fcffd35
10 mojo 0x0000561a0fd00ed8
11 mojo 0x0000561a0fcffe8f
12 mojo 0x0000561a0fcff0e0
13 mojo 0x0000561a0fcf2c70
14 mojo 0x0000561a0e849174
15 mojo 0x0000561a0e7b8fcc
16 mojo 0x0000561a0fd53913
17 mojo 0x0000561a0fd53b79
18 mojo 0x0000561a0fd198c4
19 mojo 0x0000561a0e7b7344
20 mojo 0x0000561a0e83e854
21 mojo 0x0000561a0e81caef
22 mojo 0x0000561a0e81d2ab
23 mojo 0x0000561a0e3c14ff
24 mojo 0x0000561a0e3a8a50
25 mojo 0x0000561a0e3c0460
26 mojo 0x0000561a0e3a2926
27 libc.so.6 0x00007f5596429d90
28 libc.so.6 0x00007f5596429e40 __libc_start_main + 128
29 mojo 0x0000561a0e3a212e
Aborted
mojo: /__w/modular/modular/third-party/llvm-project/llvm/include/llvm/Support/Casting.h:572: decltype(auto) llvm::cast(From &) [To = mlir::BytecodeOpInterface, From = mlir::Operation]: Assertion `isa<To>(Val) && "cast<Ty>() argument of incompatible type!"' failed.
Please submit a bug report to https://github.com/modularml/mojo/issues and include the crash backtrace along with all the relevant source codes.
Stack dump:
0. Program arguments: mojo run ./test.mojo
Stack dump without symbol names (ensure you have llvm-symbolizer in your PATH or set the environment var `LLVM_SYMBOLIZER_PATH` to point to it):
0 mojo 0x0000561a0e3f6957
1 mojo 0x0000561a0e3f452e
2 mojo 0x0000561a0e3f702f
3 libc.so.6 0x00007f5596442520
4 libc.so.6 0x00007f5596496a7c pthread_kill + 300
5 libc.so.6 0x00007f5596442476 raise + 22
6 libc.so.6 0x00007f55964287f3 abort + 211
7 libc.so.6 0x00007f559642871b
8 libc.so.6 0x00007f5596439e96
9 mojo 0x0000561a0fcffd35
10 mojo 0x0000561a0fd00ed8
11 mojo 0x0000561a0fcffe8f
12 mojo 0x0000561a0fcff0e0
13 mojo 0x0000561a0fcf2c70
14 mojo 0x0000561a0e849174
15 mojo 0x0000561a0e7b8fcc
16 mojo 0x0000561a0fd53913
17 mojo 0x0000561a0fd53b79
18 mojo 0x0000561a0fd198c4
19 mojo 0x0000561a0e7b7344
20 mojo 0x0000561a0e83e854
21 mojo 0x0000561a0e81caef
22 mojo 0x0000561a0e81d2ab
23 mojo 0x0000561a0e3c14ff
24 mojo 0x0000561a0e3a8a50
25 mojo 0x0000561a0e3c0460
26 mojo 0x0000561a0e3a2926
27 libc.so.6 0x00007f5596429d90
28 libc.so.6 0x00007f5596429e40 __libc_start_main + 128
29 mojo 0x0000561a0e3a212e
Aborted
Stole
Stole15mo ago
Yep lol
TeamPuzel
TeamPuzelOP15mo ago
(Yeah if you pass wrong arguments the error message says add) maybe just the error checking is off and it's actually still trying to use the correct operation
Stole
Stole15mo ago
For some reason, it seems to work fine in the REPL.
No description
TeamPuzel
TeamPuzelOP15mo ago
huh Well everything I was planning on writing is now impossible until this is fixed :( rebind doesn't want to work for me with the built in UInt8 alias which makes ffi with C very painful
Stole
Stole15mo ago
I think you should use the pop dialect for now. It looks like Mojo will lower the pop dialect down to llvm at least in some cases, and it has the add operation you want Wait, it doesn't seem to support i32 Darn it
TeamPuzel
TeamPuzelOP15mo ago
I think only index and llvm are supported right now and only llvm can handle differently sized numbers (and floats) I'm curious how floats are implemented by the standard library if this doesn't work
Stole
Stole15mo ago
pop, kgen, and lit are the internal dialects Mojo uses
TeamPuzel
TeamPuzelOP15mo ago
Do they show up in the lsp?
Stole
Stole15mo ago
The LSP doesn't annotate like the inside of `` for all __mlir_things, you just get a normal error
TeamPuzel
TeamPuzelOP15mo ago
I think I've seen those in some error messages before
Stole
Stole15mo ago
From what I've seen, pop is where a lot of this scalar stuff happens, along with more basic types. kgen is where more complex types reside, along with some language specific things. lit is for constructing and dealing with things that act like structs as mlir attrs There actually is one more dialect, hlcf, but it looks like it's for the language itself. Like there are hlcf.if and hlcf.for ops
TeamPuzel
TeamPuzelOP15mo ago
hm that's interesting, are they going to be documented at some point?
Stole
Stole15mo ago
No idea, I've just been going through a lot of trial and error
TeamPuzel
TeamPuzelOP15mo ago
Should I report the llvm dialect bug on github too?
Stole
Stole15mo ago
I guess so
TeamPuzel
TeamPuzelOP15mo ago
I opened an issue now
rd4com
rd4com15mo ago
do you get code completion on kgen ? could you share a snippet please @Stole @TeamPuzel i'd like to play too
TeamPuzel
TeamPuzelOP15mo ago
I do not get code completion for anything, the lsp is broken for me
JIMC
JIMC15mo ago
very interesting discussion here loving it very useful comment i cannot actually find the lit dialect probably not documented but its mojo's internal @TeamPuzel you have any lots of lit dialect etc?
TeamPuzel
TeamPuzelOP15mo ago
what do you mean?
Stole
Stole15mo ago
No, there is no code completion while you're typing inside any __mlir_thing
TeamPuzel
TeamPuzelOP15mo ago
I had to do this for now, seems to be adding correctly
from std.primitive import UInt8

fn main():
let x: UInt8 = 255
let y: UInt8 = 2
let z: UInt8 = x + y

print(z.to_int())
from std.primitive import UInt8

fn main():
let x: UInt8 = 255
let y: UInt8 = 2
let z: UInt8 = x + y

print(z.to_int())
It technically works but it looks really bad:
@register_passable("trivial")
struct UInt8:
alias Data = __mlir_type.ui8

var value: Self.Data

fn __init__(value: Int) -> Self:
return Self {
value: __mlir_op.`index.castu`[_type: Self.Data](value.__mlir_index__())
}

fn __add__(self, rhs: Self) -> Self:
let result = __mlir_op.`index.add`[_type: __mlir_type.index](
__mlir_op.`index.castu`[_type: __mlir_type.index](self.value),
__mlir_op.`index.castu`[_type: __mlir_type.index](rhs.value)
)
return Self(result)

fn to_int(self) -> Int:
return Int(__mlir_op.`index.castu`[_type: __mlir_type.index](self.value))
@register_passable("trivial")
struct UInt8:
alias Data = __mlir_type.ui8

var value: Self.Data

fn __init__(value: Int) -> Self:
return Self {
value: __mlir_op.`index.castu`[_type: Self.Data](value.__mlir_index__())
}

fn __add__(self, rhs: Self) -> Self:
let result = __mlir_op.`index.add`[_type: __mlir_type.index](
__mlir_op.`index.castu`[_type: __mlir_type.index](self.value),
__mlir_op.`index.castu`[_type: __mlir_type.index](rhs.value)
)
return Self(result)

fn to_int(self) -> Int:
return Int(__mlir_op.`index.castu`[_type: __mlir_type.index](self.value))
I'm not sure if this would get optimised, but either way it's going to be very hard to read once it has all of the methods. And then I need to copy and paste this for every type :/ at least the alias will help
Stole
Stole15mo ago
Yeah, just doing the adding through index isn't ideal
rd4com
rd4com15mo ago
hello for llvm it is var f = intrinsics.llvm_intrinsic"llvm.cos.f64",Float64
jmky
jmky15mo ago
intrinsics? can you show us the full codes so we can study it deeply? @rd4com did u try if it correctly rejects compile time values that are not UInt8 eg alias my_int = 256? it should reject as 256 > 255
rd4com
rd4com15mo ago
yes sorry you need import sys.intrinsics import sys.intrinsics var f = intrinsics.llvm_intrinsic["llvm.cos.f64",Float64](1.4)
jmky
jmky15mo ago
so this is doing cosine(1.4)?
rd4com
rd4com15mo ago
yes, i just try to figure out where are all the intrinsic we could use
TeamPuzel
TeamPuzelOP15mo ago
I didn’t add any checks I just let it wrap around Huh, is that intended? Aren’t those actual llvm intrinsics as opposed to mlir Or am I missing something But if that works I guess that’s cool 😄 I will have to write a constructor to convert between different numbers for every possible combination 😨
jmky
jmky15mo ago
yes u must check and also, there is no known way to raise compile time error
TeamPuzel
TeamPuzelOP15mo ago
If there's no way to compile error it will have to wrap :/
rd4com
rd4com15mo ago
you can use raise in @parameter if loop no
Stole
Stole15mo ago
Is this what you're looking for?
rd4com
rd4com15mo ago
🙂
JIMC
JIMC15mo ago
GitHub
[BUG]: Unable to convert a MLIR type to another MLIR type at compil...
Bug description I am attempting to create my own UInt8 following the tutorial on Mojo's documentation on the creation of a new boolean. Below is my implementation: @register_passable('trivi...
JIMC
JIMC15mo ago
i created an issue
rd4com
rd4com15mo ago
Stole
Stole15mo ago
I'm just wondering, did you try @parameter if as well?
JIMC
JIMC15mo ago
@register_passable('trivial')
struct UInt8:
var value: __mlir_type.ui8

fn __init__(value: Int) -> Self:
let value_as_index = value.__mlir_index__()
let _255 = __mlir_op.`index.castu`[_type : __mlir_type.ui8](__mlir_attr.`255:index`)
let _255_index = __mlir_op.`index.castu`[_type : __mlir_type.index](_255)
let greater_than_255 = __mlir_op.`index.cmp`[pred : __mlir_attr.`#index<cmp_predicate ugt>`](value_as_index, _255_index)
let _0 = __mlir_op.`index.castu`[_type : __mlir_type.index](__mlir_attr.`0`)
let lesser_than_0 = __mlir_op.`index.cmp`[pred : __mlir_attr.`#index<cmp_predicate ult>`](value_as_index, _0)
@parameter
if greater_than_255 or lesser_than_0:
constrained[False, "compile error"]()
return Self {
value: __mlir_op.`index.castu`[_type: __mlir_type.ui8](value_as_index)
}

fn into_int(self) -> Int:
return __mlir_op.`index.castu`[_type : __mlir_type.index](self.value)

fn main():
alias a: UInt8 = 4
print(a.into_int())
@register_passable('trivial')
struct UInt8:
var value: __mlir_type.ui8

fn __init__(value: Int) -> Self:
let value_as_index = value.__mlir_index__()
let _255 = __mlir_op.`index.castu`[_type : __mlir_type.ui8](__mlir_attr.`255:index`)
let _255_index = __mlir_op.`index.castu`[_type : __mlir_type.index](_255)
let greater_than_255 = __mlir_op.`index.cmp`[pred : __mlir_attr.`#index<cmp_predicate ugt>`](value_as_index, _255_index)
let _0 = __mlir_op.`index.castu`[_type : __mlir_type.index](__mlir_attr.`0`)
let lesser_than_0 = __mlir_op.`index.cmp`[pred : __mlir_attr.`#index<cmp_predicate ult>`](value_as_index, _0)
@parameter
if greater_than_255 or lesser_than_0:
constrained[False, "compile error"]()
return Self {
value: __mlir_op.`index.castu`[_type: __mlir_type.ui8](value_as_index)
}

fn into_int(self) -> Int:
return __mlir_op.`index.castu`[_type : __mlir_type.index](self.value)

fn main():
alias a: UInt8 = 4
print(a.into_int())
Error:
/marray# mojo array3.mojo
array3.mojo:13:10: error: cannot use a dynamic value in operator argument
if greater_than_255 or lesser_than_0:
^~~~~~~~~~~~~~~~
array3.mojo:13:10: error: cannot use a dynamic value in '@parameter if' condition
if greater_than_255 or lesser_than_0:
^~~~~~~~~~~~~~~~
array3.mojo:13:30: error: cannot use a dynamic value in boolean condition
if greater_than_255 or lesser_than_0:
^~~~~~~~~~~~~
mojo: error: failed to parse the provided Mojo
/marray# mojo array3.mojo
array3.mojo:13:10: error: cannot use a dynamic value in operator argument
if greater_than_255 or lesser_than_0:
^~~~~~~~~~~~~~~~
array3.mojo:13:10: error: cannot use a dynamic value in '@parameter if' condition
if greater_than_255 or lesser_than_0:
^~~~~~~~~~~~~~~~
array3.mojo:13:30: error: cannot use a dynamic value in boolean condition
if greater_than_255 or lesser_than_0:
^~~~~~~~~~~~~
mojo: error: failed to parse the provided Mojo
Stole
Stole15mo ago
Oh, I did forget that you're using a mlir op here, which isn't going to be done at compile time. I'll see if I can find a mlir attr that does the comparing work, but yeah this might not be possible There's a lot else here that isn't compile time as well I mean, @JIMC, do you really need to use MLIR here? Is that a requirement of yours? because things would be much simpler if you just didn't use MLIR here TBH I don't think there's a way to cast between integer types like i1, ui8, etc. at compile time through MLIR At least if there is, it's ultra obscure, and not documented at all if it's part of Mojo's dialects
jmky
jmky15mo ago
it is certainly very possible and a requirement to be able to cast an index to ui8. think about blockchain address that are exactly 20 bytes. many languages like rust, allows for dev to create types that are exactly 20 bytes and checks them at compile time
Stole
Stole15mo ago
You can cast values between ui8 and index fine, but they're mlir ops and that happens at runtime right now, not at compile time
JIMC
JIMC15mo ago
no MLIR ops are supposed and can happen at compile time have u read up on MLIR?
Stole
Stole15mo ago
How do you call that op at compile time in Mojo? It seems like every __mlir_op call is interpreted as dynamic
jmky
jmky15mo ago
no, it is not interpreted as dynamic, it is a bug at the mlir level that the foldr optimization is not working for index type you can check out the issue i raised and if you do alias A: U8 = 4; you will see #lit.value{4} being passed into the constructor
TeamPuzel
TeamPuzelOP15mo ago
Still broken after the new update 😔
jmky
jmky15mo ago
oh theres a new update?
Want results from more Discord servers?
Add your server