I can’t seem to figure out whats wrong with the following IR. I searched for similar issues here and still can’t figure out whats wrong with this IR.
The IR is generated from a custom language that I’m developing for learning purposes (code attached below).
Generated IR & Error:
Instruction does not dominate all uses!
%u2 = alloca i32, align 4
%1 = load i32, ptr %u2, align 4
Instruction does not dominate all uses!
%i3 = alloca i32, align 4
%2 = load i32, ptr %i3, align 4
; ModuleID = '/Users/dccarter/projects/cxy/tests/hello.cxy'
source_filename = "/Users/dccarter/projects/cxy/tests/hello.cxy"
target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-apple-darwin23.2.0"
%__Closure6 = type { i8 }
%tuple.116 = type { ptr, ptr }
define i32 @__Closure6_op__call(ptr %this, i32 %u, i32 %i) {
entry:
%res = alloca i32, align 4
%i3 = alloca i32, align 4
%u2 = alloca i32, align 4
%this1 = alloca ptr, align 8
store ptr %this, ptr %this1, align 8
store i32 %u, ptr %u2, align 4
store i32 %i, ptr %i3, align 4
%0 = load i32, ptr %u2, align 4
%1 = load i32, ptr %i3, align 4
%2 = add i32 %0, %1
%3 = load ptr, ptr %this1, align 8
%j = getelementptr inbounds %__Closure6, ptr %3, i32 0, i32 0
%4 = load i8, ptr %j, align 1
%5 = zext i8 %4 to i32
%6 = add i32 %2, %5
store i32 %6, ptr %res, align 4
br label %end
end: ; preds = %entry
%7 = load i32, ptr %res, align 4
ret i32 %7
}
define internal i32 @accumulate7(%tuple.116 %fun, i32 %acc) {
entry:
%i = alloca i64, align 8
%res = alloca i32, align 4
%acc2 = alloca i32, align 4
%fun1 = alloca %tuple.116, align 8
store %tuple.116 %fun, ptr %fun1, align 8
store i32 %acc, ptr %acc2, align 4
store i64 0, ptr %i, align 8
br label %while.cond
while.cond: ; preds = %while.update, %entry
%0 = load i64, ptr %i, align 8
%1 = icmp ne i64 %0, 10
br i1 %1, label %while.body, label %while.end
while.body: ; preds = %while.cond
%2 = getelementptr inbounds %tuple.116, ptr %fun1, i32 0, i32 1
%3 = load ptr, ptr %2, align 8
%4 = getelementptr inbounds %tuple.116, ptr %fun1, i32 0, i32 0
%5 = load ptr, ptr %4, align 8
%6 = load i32, ptr %acc2, align 4
%7 = load i64, ptr %i, align 8
%8 = trunc i64 %7 to i32
%9 = call i32 %3(ptr %5, i32 %6, i32 %8)
store i32 %9, ptr %acc2, align 4
br label %while.update
while.update: ; preds = %while.body
%10 = load i64, ptr %i, align 8
%11 = add i64 %10, 1
store i64 %11, ptr %i, align 8
br label %while.cond
while.end: ; preds = %while.cond
%12 = load i32, ptr %acc2, align 4
store i32 %12, ptr %res, align 4
br label %end
end: ; preds = %while.end
%13 = load i32, ptr %res, align 4
ret i32 %13
}
define internal i32 @__Closure6__fwd(ptr %ptr, i32 %u, i32 %i) {
entry:
%res = alloca i32, align 4
%i3 = alloca i32, align 4
%u2 = alloca i32, align 4
%ptr1 = alloca ptr, align 8
store ptr %ptr, ptr %ptr1, align 8
store i32 %u, ptr %u2, align 4
store i32 %i, ptr %i3, align 4
%0 = load ptr, ptr %ptr1, align 8
%1 = load i32, ptr %u2, align 4
%2 = load i32, ptr %i3, align 4
%3 = call i32 @__Closure6_op__call(ptr %0, i32 %1, i32 %2)
store i32 %3, ptr %res, align 4
br label %end
end: ; preds = %entry
%4 = load i32, ptr %res, align 4
ret i32 %4
}
define void @main(i32 %argc, ptr %argv) {
entry:
%0 = alloca %__Closure6, align 8
%j = alloca i8, align 1
%argv2 = alloca ptr, align 8
%argc1 = alloca i32, align 4
store i32 %argc, ptr %argc1, align 4
store ptr %argv, ptr %argv2, align 8
store i8 10, ptr %j, align 1
%1 = load i8, ptr %j, align 1
%2 = insertvalue %__Closure6 undef, i8 %1, 0
store %__Closure6 %2, ptr %0, align 1
%3 = insertvalue %tuple.116 undef, ptr %0, 0
%4 = insertvalue %tuple.116 %3, ptr @__Closure6__fwd, 1
%5 = call i32 @accumulate7(%tuple.116 %4, i32 0)
br label %end
end: ; preds = %entry
ret void
}
Original Source:
func accumulate[U](fun: func(acc: U, item: u32) -> U, acc: U) {
for (var i: 0..10) {
acc = fun(acc, <u32>i)
}
return acc
}
pub func main(argc: i32, argv: &string) {
var j = 10;
accumulate((u: u32, i: u32) => u + i + j, <u32>0)
}
Or Simplified:
struct __Closure0 {
- j: i8
}
pub func __Closure0_op__call(this: &__Closure0, u: u32, i: u32): u32 {
return u + i + this.j
}
func accumulate1(fun: (&void, func(_: &void, acc: u32, item: u32) -> u32), acc: u32): u32 {
{
var i = 0
while (i != 10)
{
acc = fun.1(fun.0, acc, <u32>i)
}
}
return acc
}
func __Closure0__fwd(ptr: &void, u: u32, i: u32): u32 => __Closure0_op__call(<&__Closure0>ptr, u, i)
pub func main(argc: i32, argv: &string) {
var j = 10
accumulate1((<&void>&__Closure0{j = j}, __Closure0__fwd), 0)
}