LLVM IR
MIR staging text for external LLVM tools. Also the route CUDA device programs take, via NVVM → PTX.
Part of the MIR lane. Every panel below is compiler output.
How to read it#
The widest ratio on the site, and the least surprising one: SSA form names every intermediate. Read it for what the compiler knows about your program, not as something to maintain.
Measured support#
| Capable | Analyzable | Coverage |
|---|---|---|
| 334 | 373 | 90% |
From the target matrix: how many corpus exempla lower to this target. Coverage is not a quality score — an emitter can lower a term and still erase a distinction.
Not fully supported#
Terms the matrix records as partial, planned, or unsupported for this target. A term here is a measured gap, not an omission.
| Category | Terms |
|---|---|
| Keywords — systems lane | <a id="atomic"></a>atomic, <a id="clausura"></a>lambda, <a id="ex"></a>from, <a id="genus"></a>class, <a id="itera"></a>for, <a id="lista"></a>list, <a id="matrix"></a>matrix, <a id="numerus"></a>int, <a id="tensor"></a>tensor, <a id="vector"></a>vector |
| Operators — systems lane | ·, ⊗, ⊙, ![, !., !(, ↦, ?[, ?., ?( |
Typed tensors#
Builds two shaped matrices, multiplies them, and reduces the product to a scalar. Exercises shape-bearing types and a reduction.
Faber source
faber convert --to en — English reader surfacemain {
const list<f32> flat_a ← [1.0, 2.0, 3.0, 4.0, 5.0, 6.0]
const list<f32> flat_b ← [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0]
const tf32[] seed ← empty
const tf32[2, 3] a ← seed.from_flat(flat_a, [2, 3])
const tf32[3, 4] b ← seed.from_flat(flat_b, [3, 4])
const tf32[2, 4] product ← a.matmul(b)
const f32 mean ← product.mean()
print mean
}faber convert --to la — canonical Faberincipit {
fixum lista<f32> flat_a ← [1.0, 2.0, 3.0, 4.0, 5.0, 6.0]
fixum lista<f32> flat_b ← [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0]
fixum tf32[] seed ← vacua
fixum tf32[2, 3] a ← seed.strue(flat_a, [2, 3])
fixum tf32[3, 4] b ← seed.strue(flat_b, [3, 4])
fixum tf32[2, 4] product ← a.matmul(b)
fixum f32 mean ← product.media()
nota mean
}faber convert --to th-TH — Thaiเริ่ม {
คงที่ รายการ<f32> flat_a ← [1.0, 2.0, 3.0, 4.0, 5.0, 6.0]
คงที่ รายการ<f32> flat_b ← [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0]
คงที่ tf32[] seed ← เซตว่าง
คงที่ tf32[2, 3] a ← seed.สร้างจากข้อมูลแบน(flat_a, [2, 3])
คงที่ tf32[3, 4] b ← seed.สร้างจากข้อมูลแบน(flat_b, [3, 4])
คงที่ tf32[2, 4] product ← a.คูณเมทริกซ์(b)
คงที่ f32 mean ← product.ค่าเฉลี่ย()
บันทึก mean
}faber convert --to zh-Hans — Simplified Chinese入口 {
常量 列表<f32> flat_a ← [1.0, 2.0, 3.0, 4.0, 5.0, 6.0]
常量 列表<f32> flat_b ← [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0]
常量 tf32[] seed ← 空集
常量 tf32[2, 3] a ← seed.由扁平构造(flat_a, [2, 3])
常量 tf32[3, 4] b ← seed.由扁平构造(flat_b, [3, 4])
常量 tf32[2, 4] product ← a.矩阵乘法(b)
常量 f32 mean ← product.均值()
显示 mean
}faber convert --to zh-Hant — Traditional Chinese入口 {
定值 列表<f32> flat_a ← [1.0, 2.0, 3.0, 4.0, 5.0, 6.0]
定值 列表<f32> flat_b ← [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0]
定值 tf32[] seed ← 空集
定值 tf32[2, 3] a ← seed.由扁平建構(flat_a, [2, 3])
定值 tf32[3, 4] b ← seed.由扁平建構(flat_b, [3, 4])
定值 tf32[2, 4] product ← a.矩陣乘法(b)
定值 f32 mean ← product.平均值()
註記 mean
}faber convert --to vi — Vietnamesebắt_đầu {
hằng danh_sách<f32> flat_a ← [1.0, 2.0, 3.0, 4.0, 5.0, 6.0]
hằng danh_sách<f32> flat_b ← [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0]
hằng tf32[] seed ← tập_rỗng
hằng tf32[2, 3] a ← seed.dựng_từ_phẳng(flat_a, [2, 3])
hằng tf32[3, 4] b ← seed.dựng_từ_phẳng(flat_b, [3, 4])
hằng tf32[2, 4] product ← a.nhân_ma_trận(b)
hằng f32 mean ← product.trung_bình()
ghi_chú mean
}faber convert --to ar — Arabicبداية {
ثابت قائمة<f32> flat_a ← [1.0, 2.0, 3.0, 4.0, 5.0, 6.0]
ثابت قائمة<f32> flat_b ← [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0]
ثابت tf32[] seed ← فارغ
ثابت tf32[2, 3] a ← seed.ابن_من_مسطح(flat_a, [2, 3])
ثابت tf32[3, 4] b ← seed.ابن_من_مسطح(flat_b, [3, 4])
ثابت tf32[2, 4] product ← a.ضرب_المصفوفات(b)
ثابت f32 mean ← product.المتوسط()
اعرض mean
}faber convert --to hi — Hindiआरंभ {
स्थिर सूची<f32> flat_a ← [1.0, 2.0, 3.0, 4.0, 5.0, 6.0]
स्थिर सूची<f32> flat_b ← [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0]
स्थिर tf32[] seed ← खाली
स्थिर tf32[2, 3] a ← seed.समतल_से_बनाओ(flat_a, [2, 3])
स्थिर tf32[3, 4] b ← seed.समतल_से_बनाओ(flat_b, [3, 4])
स्थिर tf32[2, 4] product ← a.आव्यूह_गुणन(b)
स्थिर f32 mean ← product.माध्य()
दिखाओ mean
}LLVM IR — 10 lines in, 356 out (35.6×)
; Generated by radix MIR LLVM IR probe - experimental artifact.
%FaberRtSliceV1 = type { ptr, i64 }
%FaberRtExitV1 = type i64
%FaberRtPtrResultV1 = type { i32, ptr }
%FaberRtStatusV1 = type { i32 }
@__faber_rt_v1_context = linkonce_odr global ptr null
@__faber_rt_v1_status = linkonce_odr global i32 0
declare void @__faber_rt_v1_fatal(ptr, %FaberRtSliceV1) noreturn
declare void @__faber_rt_v1_numerus_overflow(ptr) noreturn
declare ptr @__faber_aggregate_array_2_i64_i64(i64, i64)
; @runtime __faber_rt_v1_array_new category=core-semantics
declare %FaberRtPtrResultV1 @__faber_rt_v1_array_new(ptr, i32)
; @runtime __faber_rt_v1_array_push category=core-semantics
declare i32 @__faber_rt_v1_array_push(ptr, ptr, i32, ptr)
; @runtime __faber_rt_v1_diagnostic_nota_f32 category=host-integration
declare i32 @__faber_rt_v1_diagnostic_nota_f32(ptr, float)
; @runtime __faber_rt_v1_tensor_from_flat category=core-semantics
declare %FaberRtPtrResultV1 @__faber_rt_v1_tensor_from_flat(ptr, i32, ptr, ptr)
; @runtime __faber_rt_v1_tensor_matmul category=core-semantics
declare %FaberRtPtrResultV1 @__faber_rt_v1_tensor_matmul(ptr, ptr, ptr)
; @runtime __faber_rt_v1_tensor_mean category=core-semantics
declare i32 @__faber_rt_v1_tensor_mean(ptr, ptr, i32, ptr)
; @runtime __faber_rt_v1_tensor_new category=core-semantics
declare %FaberRtPtrResultV1 @__faber_rt_v1_tensor_new(ptr, i32)
define void @main() {
entry:
%l0.addr = alloca ptr
%l1.addr = alloca ptr
%l2.addr = alloca ptr
%l3.addr = alloca ptr
%l4.addr = alloca ptr
%l5.addr = alloca ptr
%l6.addr = alloca float
%t0.addr = alloca float
%t1.addr = alloca float
%t2.addr = alloca float
%t3.addr = alloca float
%t4.addr = alloca float
%t5.addr = alloca float
%t6.addr = alloca ptr
%t7.addr = alloca float
%t8.addr = alloca float
%t9.addr = alloca float
%t10.addr = alloca float
%t11.addr = alloca float
%t12.addr = alloca float
%t13.addr = alloca float
%t14.addr = alloca float
%t15.addr = alloca float
%t16.addr = alloca float
%t17.addr = alloca float
%t18.addr = alloca float
%t19.addr = alloca ptr
%t20.addr = alloca ptr
%t21.addr = alloca ptr
%t22.addr = alloca ptr
%t23.addr = alloca ptr
%t24.addr = alloca ptr
%t25.addr = alloca ptr
%t26.addr = alloca float
br label %b0
b0:
%cast0 = fptrunc double 1.0 to float
store float %cast0, ptr %t0.addr
%cast1 = fptrunc double 2.0 to float
store float %cast1, ptr %t1.addr
%cast2 = fptrunc double 3.0 to float
store float %cast2, ptr %t2.addr
%cast3 = fptrunc double 4.0 to float
store float %cast3, ptr %t3.addr
%cast4 = fptrunc double 5.0 to float
store float %cast4, ptr %t4.addr
%cast5 = fptrunc double 6.0 to float
store float %cast5, ptr %t5.addr
%faber.context6 = load ptr, ptr @__faber_rt_v1_context
%faber.array.result6 = call %FaberRtPtrResultV1 @__faber_rt_v1_array_new(ptr %faber.context6, i32 5)
%faber.array.status6 = extractvalue %FaberRtPtrResultV1 %faber.array.result6, 0
%faber.array.handle6 = extractvalue %FaberRtPtrResultV1 %faber.array.result6, 1
%faber.old.status6 = load i32, ptr @__faber_rt_v1_status
%faber.has.error6 = icmp ne i32 %faber.old.status6, 0
%faber.latched.status6 = select i1 %faber.has.error6, i32 %faber.old.status6, i32 %faber.array.status6
store i32 %faber.latched.status6, ptr @__faber_rt_v1_status
%load8 = load float, ptr %t0.addr
%faber.array.value7 = alloca float
store float %load8, ptr %faber.array.value7
%faber.array.status7 = call i32 @__faber_rt_v1_array_push(ptr %faber.context6, ptr %faber.array.handle6, i32 5, ptr %faber.array.value7)
%faber.old.status7 = load i32, ptr @__faber_rt_v1_status
%faber.has.error7 = icmp ne i32 %faber.old.status7, 0
%faber.latched.status7 = select i1 %faber.has.error7, i32 %faber.old.status7, i32 %faber.array.status7
store i32 %faber.latched.status7, ptr @__faber_rt_v1_status
%load10 = load float, ptr %t1.addr
%faber.array.value9 = alloca float
store float %load10, ptr %faber.array.value9
%faber.array.status9 = call i32 @__faber_rt_v1_array_push(ptr %faber.context6, ptr %faber.array.handle6, i32 5, ptr %faber.array.value9)
%faber.old.status9 = load i32, ptr @__faber_rt_v1_status
%faber.has.error9 = icmp ne i32 %faber.old.status9, 0
%faber.latched.status9 = select i1 %faber.has.error9, i32 %faber.old.status9, i32 %faber.array.status9
store i32 %faber.latched.status9, ptr @__faber_rt_v1_status
%load12 = load float, ptr %t2.addr
%faber.array.value11 = alloca float
store float %load12, ptr %faber.array.value11
%faber.array.status11 = call i32 @__faber_rt_v1_array_push(ptr %faber.context6, ptr %faber.array.handle6, i32 5, ptr %faber.array.value11)
%faber.old.status11 = load i32, ptr @__faber_rt_v1_status
%faber.has.error11 = icmp ne i32 %faber.old.status11, 0
%faber.latched.status11 = select i1 %faber.has.error11, i32 %faber.old.status11, i32 %faber.array.status11
store i32 %faber.latched.status11, ptr @__faber_rt_v1_status
%load14 = load float, ptr %t3.addr
%faber.array.value13 = alloca float
store float %load14, ptr %faber.array.value13
%faber.array.status13 = call i32 @__faber_rt_v1_array_push(ptr %faber.context6, ptr %faber.array.handle6, i32 5, ptr %faber.array.value13)
%faber.old.status13 = load i32, ptr @__faber_rt_v1_status
%faber.has.error13 = icmp ne i32 %faber.old.status13, 0
%faber.latched.status13 = select i1 %faber.has.error13, i32 %faber.old.status13, i32 %faber.array.status13
store i32 %faber.latched.status13, ptr @__faber_rt_v1_status
%load16 = load float, ptr %t4.addr
%faber.array.value15 = alloca float
store float %load16, ptr %faber.array.value15
%faber.array.status15 = call i32 @__faber_rt_v1_array_push(ptr %faber.context6, ptr %faber.array.handle6, i32 5, ptr %faber.array.value15)
%faber.old.status15 = load i32, ptr @__faber_rt_v1_status
%faber.has.error15 = icmp ne i32 %faber.old.status15, 0
%faber.latched.status15 = select i1 %faber.has.error15, i32 %faber.old.status15, i32 %faber.array.status15
store i32 %faber.latched.status15, ptr @__faber_rt_v1_status
%load18 = load float, ptr %t5.addr
%faber.array.value17 = alloca float
store float %load18, ptr %faber.array.value17
%faber.array.status17 = call i32 @__faber_rt_v1_array_push(ptr %faber.context6, ptr %faber.array.handle6, i32 5, ptr %faber.array.value17)
%faber.old.status17 = load i32, ptr @__faber_rt_v1_status
%faber.has.error17 = icmp ne i32 %faber.old.status17, 0
%faber.latched.status17 = select i1 %faber.has.error17, i32 %faber.old.status17, i32 %faber.array.status17
store i32 %faber.latched.status17, ptr @__faber_rt_v1_status
store ptr %faber.array.handle6, ptr %t6.addr
%load19 = load ptr, ptr %t6.addr
store ptr %load19, ptr %l0.addr
%cast20 = fptrunc double 1.0 to float
store float %cast20, ptr %t7.addr
%cast21 = fptrunc double 2.0 to float
store float %cast21, ptr %t8.addr
%cast22 = fptrunc double 3.0 to float
store float %cast22, ptr %t9.addr
%cast23 = fptrunc double 4.0 to float
store float %cast23, ptr %t10.addr
%cast24 = fptrunc double 5.0 to float
store float %cast24, ptr %t11.addr
%cast25 = fptrunc double 6.0 to float
store float %cast25, ptr %t12.addr
%cast26 = fptrunc double 7.0 to float
store float %cast26, ptr %t13.addr
%cast27 = fptrunc double 8.0 to float
store float %cast27, ptr %t14.addr
%cast28 = fptrunc double 9.0 to float
store float %cast28, ptr %t15.addr
%cast29 = fptrunc double 10.0 to float
store float %cast29, ptr %t16.addr
%cast30 = fptrunc double 11.0 to float
store float %cast30, ptr %t17.addr
%cast31 = fptrunc double 12.0 to float
store float %cast31, ptr %t18.addr
%faber.context32 = load ptr, ptr @__faber_rt_v1_context
%faber.array.result32 = call %FaberRtPtrResultV1 @__faber_rt_v1_array_new(ptr %faber.context32, i32 5)
%faber.array.status32 = extractvalue %FaberRtPtrResultV1 %faber.array.result32, 0
%faber.array.handle32 = extractvalue %FaberRtPtrResultV1 %faber.array.result32, 1
%faber.old.status32 = load i32, ptr @__faber_rt_v1_status
%faber.has.error32 = icmp ne i32 %faber.old.status32, 0
%faber.latched.status32 = select i1 %faber.has.error32, i32 %faber.old.status32, i32 %faber.array.status32
store i32 %faber.latched.status32, ptr @__faber_rt_v1_status
%load34 = load float, ptr %t7.addr
%faber.array.value33 = alloca float
store float %load34, ptr %faber.array.value33
%faber.array.status33 = call i32 @__faber_rt_v1_array_push(ptr %faber.context32, ptr %faber.array.handle32, i32 5, ptr %faber.array.value33)
%faber.old.status33 = load i32, ptr @__faber_rt_v1_status
%faber.has.error33 = icmp ne i32 %faber.old.status33, 0
%faber.latched.status33 = select i1 %faber.has.error33, i32 %faber.old.status33, i32 %faber.array.status33
store i32 %faber.latched.status33, ptr @__faber_rt_v1_status
%load36 = load float, ptr %t8.addr
%faber.array.value35 = alloca float
store float %load36, ptr %faber.array.value35
%faber.array.status35 = call i32 @__faber_rt_v1_array_push(ptr %faber.context32, ptr %faber.array.handle32, i32 5, ptr %faber.array.value35)
%faber.old.status35 = load i32, ptr @__faber_rt_v1_status
%faber.has.error35 = icmp ne i32 %faber.old.status35, 0
%faber.latched.status35 = select i1 %faber.has.error35, i32 %faber.old.status35, i32 %faber.array.status35
store i32 %faber.latched.status35, ptr @__faber_rt_v1_status
%load38 = load float, ptr %t9.addr
%faber.array.value37 = alloca float
store float %load38, ptr %faber.array.value37
%faber.array.status37 = call i32 @__faber_rt_v1_array_push(ptr %faber.context32, ptr %faber.array.handle32, i32 5, ptr %faber.array.value37)
%faber.old.status37 = load i32, ptr @__faber_rt_v1_status
%faber.has.error37 = icmp ne i32 %faber.old.status37, 0
%faber.latched.status37 = select i1 %faber.has.error37, i32 %faber.old.status37, i32 %faber.array.status37
store i32 %faber.latched.status37, ptr @__faber_rt_v1_status
%load40 = load float, ptr %t10.addr
%faber.array.value39 = alloca float
store float %load40, ptr %faber.array.value39
%faber.array.status39 = call i32 @__faber_rt_v1_array_push(ptr %faber.context32, ptr %faber.array.handle32, i32 5, ptr %faber.array.value39)
%faber.old.status39 = load i32, ptr @__faber_rt_v1_status
%faber.has.error39 = icmp ne i32 %faber.old.status39, 0
%faber.latched.status39 = select i1 %faber.has.error39, i32 %faber.old.status39, i32 %faber.array.status39
store i32 %faber.latched.status39, ptr @__faber_rt_v1_status
%load42 = load float, ptr %t11.addr
%faber.array.value41 = alloca float
store float %load42, ptr %faber.array.value41
%faber.array.status41 = call i32 @__faber_rt_v1_array_push(ptr %faber.context32, ptr %faber.array.handle32, i32 5, ptr %faber.array.value41)
%faber.old.status41 = load i32, ptr @__faber_rt_v1_status
%faber.has.error41 = icmp ne i32 %faber.old.status41, 0
%faber.latched.status41 = select i1 %faber.has.error41, i32 %faber.old.status41, i32 %faber.array.status41
store i32 %faber.latched.status41, ptr @__faber_rt_v1_status
%load44 = load float, ptr %t12.addr
%faber.array.value43 = alloca float
store float %load44, ptr %faber.array.value43
%faber.array.status43 = call i32 @__faber_rt_v1_array_push(ptr %faber.context32, ptr %faber.array.handle32, i32 5, ptr %faber.array.value43)
%faber.old.status43 = load i32, ptr @__faber_rt_v1_status
%faber.has.error43 = icmp ne i32 %faber.old.status43, 0
%faber.latched.status43 = select i1 %faber.has.error43, i32 %faber.old.status43, i32 %faber.array.status43
store i32 %faber.latched.status43, ptr @__faber_rt_v1_status
%load46 = load float, ptr %t13.addr
%faber.array.value45 = alloca float
store float %load46, ptr %faber.array.value45
%faber.array.status45 = call i32 @__faber_rt_v1_array_push(ptr %faber.context32, ptr %faber.array.handle32, i32 5, ptr %faber.array.value45)
%faber.old.status45 = load i32, ptr @__faber_rt_v1_status
%faber.has.error45 = icmp ne i32 %faber.old.status45, 0
%faber.latched.status45 = select i1 %faber.has.error45, i32 %faber.old.status45, i32 %faber.array.status45
store i32 %faber.latched.status45, ptr @__faber_rt_v1_status
%load48 = load float, ptr %t14.addr
%faber.array.value47 = alloca float
store float %load48, ptr %faber.array.value47
%faber.array.status47 = call i32 @__faber_rt_v1_array_push(ptr %faber.context32, ptr %faber.array.handle32, i32 5, ptr %faber.array.value47)
%faber.old.status47 = load i32, ptr @__faber_rt_v1_status
%faber.has.error47 = icmp ne i32 %faber.old.status47, 0
%faber.latched.status47 = select i1 %faber.has.error47, i32 %faber.old.status47, i32 %faber.array.status47
store i32 %faber.latched.status47, ptr @__faber_rt_v1_status
%load50 = load float, ptr %t15.addr
%faber.array.value49 = alloca float
store float %load50, ptr %faber.array.value49
%faber.array.status49 = call i32 @__faber_rt_v1_array_push(ptr %faber.context32, ptr %faber.array.handle32, i32 5, ptr %faber.array.value49)
%faber.old.status49 = load i32, ptr @__faber_rt_v1_status
%faber.has.error49 = icmp ne i32 %faber.old.status49, 0
%faber.latched.status49 = select i1 %faber.has.error49, i32 %faber.old.status49, i32 %faber.array.status49
store i32 %faber.latched.status49, ptr @__faber_rt_v1_status
%load52 = load float, ptr %t16.addr
%faber.array.value51 = alloca float
store float %load52, ptr %faber.array.value51
%faber.array.status51 = call i32 @__faber_rt_v1_array_push(ptr %faber.context32, ptr %faber.array.handle32, i32 5, ptr %faber.array.value51)
%faber.old.status51 = load i32, ptr @__faber_rt_v1_status
%faber.has.error51 = icmp ne i32 %faber.old.status51, 0
%faber.latched.status51 = select i1 %faber.has.error51, i32 %faber.old.status51, i32 %faber.array.status51
store i32 %faber.latched.status51, ptr @__faber_rt_v1_status
%load54 = load float, ptr %t17.addr
%faber.array.value53 = alloca float
store float %load54, ptr %faber.array.value53
%faber.array.status53 = call i32 @__faber_rt_v1_array_push(ptr %faber.context32, ptr %faber.array.handle32, i32 5, ptr %faber.array.value53)
%faber.old.status53 = load i32, ptr @__faber_rt_v1_status
%faber.has.error53 = icmp ne i32 %faber.old.status53, 0
%faber.latched.status53 = select i1 %faber.has.error53, i32 %faber.old.status53, i32 %faber.array.status53
store i32 %faber.latched.status53, ptr @__faber_rt_v1_status
%load56 = load float, ptr %t18.addr
%faber.array.value55 = alloca float
store float %load56, ptr %faber.array.value55
%faber.array.status55 = call i32 @__faber_rt_v1_array_push(ptr %faber.context32, ptr %faber.array.handle32, i32 5, ptr %faber.array.value55)
%faber.old.status55 = load i32, ptr @__faber_rt_v1_status
%faber.has.error55 = icmp ne i32 %faber.old.status55, 0
%faber.latched.status55 = select i1 %faber.has.error55, i32 %faber.old.status55, i32 %faber.array.status55
store i32 %faber.latched.status55, ptr @__faber_rt_v1_status
store ptr %faber.array.handle32, ptr %t19.addr
%load57 = load ptr, ptr %t19.addr
store ptr %load57, ptr %l1.addr
%faber.context58 = load ptr, ptr @__faber_rt_v1_context
%faber.tensor.result58 = call %FaberRtPtrResultV1 @__faber_rt_v1_tensor_new(ptr %faber.context58, i32 5)
%faber.tensor.status58 = extractvalue %FaberRtPtrResultV1 %faber.tensor.result58, 0
%faber.tensor.value58 = extractvalue %FaberRtPtrResultV1 %faber.tensor.result58, 1
%faber.old.status58 = load i32, ptr @__faber_rt_v1_status
%faber.has.error58 = icmp ne i32 %faber.old.status58, 0
%faber.latched.status58 = select i1 %faber.has.error58, i32 %faber.old.status58, i32 %faber.tensor.status58
store i32 %faber.latched.status58, ptr @__faber_rt_v1_status
store ptr %faber.tensor.value58, ptr %t20.addr
%load59 = load ptr, ptr %t20.addr
store ptr %load59, ptr %l2.addr
%agg60 = call ptr @__faber_aggregate_array_2_i64_i64(i64 2, i64 3)
store ptr %agg60, ptr %t21.addr
%load62 = load ptr, ptr %l2.addr
%faber.context61 = load ptr, ptr @__faber_rt_v1_context
%load63 = load ptr, ptr %l0.addr
%load64 = load ptr, ptr %t21.addr
%faber.tensor.result61 = call %FaberRtPtrResultV1 @__faber_rt_v1_tensor_from_flat(ptr %faber.context61, i32 5, ptr %load63, ptr %load64)
%faber.tensor.status61 = extractvalue %FaberRtPtrResultV1 %faber.tensor.result61, 0
%faber.tensor.value61 = extractvalue %FaberRtPtrResultV1 %faber.tensor.result61, 1
%faber.old.status61 = load i32, ptr @__faber_rt_v1_status
%faber.has.error61 = icmp ne i32 %faber.old.status61, 0
%faber.latched.status61 = select i1 %faber.has.error61, i32 %faber.old.status61, i32 %faber.tensor.status61
store i32 %faber.latched.status61, ptr @__faber_rt_v1_status
store ptr %faber.tensor.value61, ptr %t22.addr
%load65 = load ptr, ptr %t22.addr
store ptr %load65, ptr %l3.addr
%agg66 = call ptr @__faber_aggregate_array_2_i64_i64(i64 3, i64 4)
store ptr %agg66, ptr %t23.addr
%load68 = load ptr, ptr %l2.addr
%faber.context67 = load ptr, ptr @__faber_rt_v1_context
%load69 = load ptr, ptr %l1.addr
%load70 = load ptr, ptr %t23.addr
%faber.tensor.result67 = call %FaberRtPtrResultV1 @__faber_rt_v1_tensor_from_flat(ptr %faber.context67, i32 5, ptr %load69, ptr %load70)
%faber.tensor.status67 = extractvalue %FaberRtPtrResultV1 %faber.tensor.result67, 0
%faber.tensor.value67 = extractvalue %FaberRtPtrResultV1 %faber.tensor.result67, 1
%faber.old.status67 = load i32, ptr @__faber_rt_v1_status
%faber.has.error67 = icmp ne i32 %faber.old.status67, 0
%faber.latched.status67 = select i1 %faber.has.error67, i32 %faber.old.status67, i32 %faber.tensor.status67
store i32 %faber.latched.status67, ptr @__faber_rt_v1_status
store ptr %faber.tensor.value67, ptr %t24.addr
%load71 = load ptr, ptr %t24.addr
store ptr %load71, ptr %l4.addr
%load73 = load ptr, ptr %l3.addr
%faber.context72 = load ptr, ptr @__faber_rt_v1_context
%load74 = load ptr, ptr %l4.addr
%faber.tensor.result72 = call %FaberRtPtrResultV1 @__faber_rt_v1_tensor_matmul(ptr %faber.context72, ptr %load73, ptr %load74)
%faber.tensor.status72 = extractvalue %FaberRtPtrResultV1 %faber.tensor.result72, 0
%faber.tensor.value72 = extractvalue %FaberRtPtrResultV1 %faber.tensor.result72, 1
%faber.old.status72 = load i32, ptr @__faber_rt_v1_status
%faber.has.error72 = icmp ne i32 %faber.old.status72, 0
%faber.latched.status72 = select i1 %faber.has.error72, i32 %faber.old.status72, i32 %faber.tensor.status72
store i32 %faber.latched.status72, ptr @__faber_rt_v1_status
store ptr %faber.tensor.value72, ptr %t25.addr
%load75 = load ptr, ptr %t25.addr
store ptr %load75, ptr %l5.addr
%load77 = load ptr, ptr %l5.addr
%faber.context76 = load ptr, ptr @__faber_rt_v1_context
%faber.tensor.reduce.out76 = alloca float
store float 0.0, ptr %faber.tensor.reduce.out76
%faber.tensor.status76 = call i32 @__faber_rt_v1_tensor_mean(ptr %faber.context76, ptr %load77, i32 5, ptr %faber.tensor.reduce.out76)
%faber.tensor.reduce76 = load float, ptr %faber.tensor.reduce.out76
%faber.old.status76 = load i32, ptr @__faber_rt_v1_status
%faber.has.error76 = icmp ne i32 %faber.old.status76, 0
%faber.latched.status76 = select i1 %faber.has.error76, i32 %faber.old.status76, i32 %faber.tensor.status76
store i32 %faber.latched.status76, ptr @__faber_rt_v1_status
store float %faber.tensor.reduce76, ptr %t26.addr
%load78 = load float, ptr %t26.addr
store float %load78, ptr %l6.addr
%load79 = load float, ptr %l6.addr
%faber.context80 = load ptr, ptr @__faber_rt_v1_context
%faber.diag.status80 = call i32 @__faber_rt_v1_diagnostic_nota_f32(ptr %faber.context80, float %load79)
%faber.old.status80 = load i32, ptr @__faber_rt_v1_status
%faber.has.error80 = icmp ne i32 %faber.old.status80, 0
%faber.latched.status80 = select i1 %faber.has.error80, i32 %faber.old.status80, i32 %faber.diag.status80
store i32 %faber.latched.status80, ptr @__faber_rt_v1_status
ret void
}
define %FaberRtExitV1 @__faber_program_entry_v1(ptr %context) {
entry:
store ptr %context, ptr @__faber_rt_v1_context
call void @main()
%faber.entry.status = load i32, ptr @__faber_rt_v1_status
%faber.entry.status.ext = zext i32 %faber.entry.status to i64
%faber.entry.shifted = shl i64 %faber.entry.status.ext, 32
%faber.entry.packed = or i64 0, %faber.entry.shifted
ret %FaberRtExitV1 %faber.entry.packed
}The error channel#
A function that may fail, and a caller that catches. Shows how the ⇥ channel becomes each target's own error idiom.
Faber source
faber convert --to en — English reader surfacefn divide(int a, int b) → int ⇥ string {
if b ≡ 0 {
throw "division by zero"
}
return a / b
}
main {
do {
print divide(10, 2)
}
catch err {
warn err
}
}faber convert --to la — canonical Faberfunctio divide(numerus a, numerus b) → numerus ⇥ textus {
si b ≡ 0 {
iace "division by zero"
}
redde a / b
}
incipit {
fac {
nota divide(10, 2)
}
cape err {
mone err
}
}faber convert --to th-TH — Thaiฟังก์ชัน divide(จำนวน a, จำนวน b) → จำนวน ⇥ ข้อความ {
ถ้า b ≡ 0 {
โยน "division by zero"
}
คืน a / b
}
เริ่ม {
ทำ {
บันทึก divide(10, 2)
}
จับ err {
เตือน err
}
}faber convert --to zh-Hans — Simplified Chinese函数 divide(整数 a, 整数 b) → 整数 ⇥ 文本 {
如果 b ≡ 0 {
抛错 "division by zero"
}
返回 a / b
}
入口 {
执行 {
显示 divide(10, 2)
}
捕获 err {
警告 err
}
}faber convert --to zh-Hant — Traditional Chinese函式 divide(整數 a, 整數 b) → 整數 ⇥ 文字 {
若 b ≡ 0 {
拋出 "division by zero"
}
傳回 a / b
}
入口 {
執行 {
註記 divide(10, 2)
}
捕捉 err {
警告 err
}
}faber convert --to vi — Vietnamesehàm divide(số a, số b) → số ⇥ văn_bản {
nếu b ≡ 0 {
ném "division by zero"
}
trả a / b
}
bắt_đầu {
làm {
ghi_chú divide(10, 2)
}
bắt err {
cảnh_báo err
}
}faber convert --to ar — Arabicدالة divide(عدد a, عدد b) → عدد ⇥ نص {
إذا b ≡ 0 {
ارم "division by zero"
}
أعد a / b
}
بداية {
افعل {
اعرض divide(10, 2)
}
التقط err {
نبه err
}
}faber convert --to hi — Hindiफलन divide(संख्या a, संख्या b) → संख्या ⇥ पाठ {
यदि b ≡ 0 {
इधरफेंको "division by zero"
}
लौटाओ a / b
}
आरंभ {
करो {
दिखाओ divide(10, 2)
}
पकड़ो err {
चेताओ err
}
}LLVM IR — 13 lines in, 198 out (15.2×)
; Generated by radix MIR LLVM IR probe - experimental artifact.
%FaberRtSliceV1 = type { ptr, i64 }
%FaberRtExitV1 = type i64
%FaberRtPtrResultV1 = type { i32, ptr }
%FaberRtStatusV1 = type { i32 }
@__faber_rt_v1_context = linkonce_odr global ptr null
@__faber_rt_v1_status = linkonce_odr global i32 0
declare void @__faber_rt_v1_fatal(ptr, %FaberRtSliceV1) noreturn
declare void @__faber_rt_v1_numerus_overflow(ptr) noreturn
; @literal-data __faber_text_literal_text_16_64_69_76_69_73_69_6f_6e_20_62_79_20_7a_65_72_6f family=text family_index=0 family_index_count=1 family_count=1 representation=static-byte-data representation_index=0 representation_index_count=1 representation_count=1 byte_data_schema_version=1 encoding=utf8 byte_data_schema_version_index=0 byte_data_schema_version_index_count=1 encoding_index=0 encoding_index_count=1 byte_data_schema_version_count=1 encoding_count=1 layout="[17 x i8]" bytes=17 payload_bytes=16 layout_index=0 layout_index_count=1 payload_byte_index=0 payload_byte_index_count=1 payload_byte_count=1 layout_count=1 byte_length_count=1 terminator_bytes=1 terminator_byte_index=0 terminator_byte_index_count=1 terminator_byte_count=1 terminator_policy_index=0 terminator_policy_index_count=1 terminator_policy_count=1 null_terminated_index=0 null_terminated_index_count=1 null_terminated=true null_terminated_count=1 mutability_index=0 mutability_index_count=1 mutability="constant" mutability_count=1 pointer_policy_index=0 pointer_policy_index_count=1 pointer_policy="gep-nonempty-direct-empty" pointer_policy_count=1 linkage_index=0 linkage_index_count=1 linkage="linkonce_odr unnamed_addr constant" linkage_count=1 alignment_index=0 alignment_index_count=1 alignment="align 1" alignment_count=1
@__faber_text_literal_text_16_64_69_76_69_73_69_6f_6e_20_62_79_20_7a_65_72_6f = linkonce_odr unnamed_addr constant [17 x i8] c"division by zero\00", align 1
; @literal-object __faber_text_literal_text_16_64_69_76_69_73_69_6f_6e_20_62_79_20_7a_65_72_6f_object family=text family_index=0 family_index_count=1 family_count=1 representation=static-descriptor representation_count=1 descriptor_schema_version=1 descriptor_schema_version_count=1 layout="{ ptr, i64 }" layout_count=1 byte_len=16 byte_len_count=1 abi_align=8 abi_align_count=1 field_types=ptr,i64 field_type_count=2 field_sizes=8,8 field_size_count=2 field_alignments=8,8 field_alignment_count=2 field_offsets=0,8 field_offset_count=2 field_end_offsets=8,16 field_end_offset_count=2 pointer_fields=data pointer_field_indexes=data:0 pointer_field_index_count=1 pointer_field_count=1 pointer_address_spaces=data:0 pointer_address_space_count=1 pointer_target_families=data:unknown pointer_target_family_indexes=data:0:unknown pointer_target_family_index_count=1 pointer_target_family_count=1 pointer_target_terminators=none pointer_target_terminator_indexes=none pointer_target_terminator_index_count=0 pointer_target_terminator_count=0 pointer_target_byte_lens=none pointer_target_byte_len_indexes=none pointer_target_byte_len_index_count=0 pointer_target_byte_len_count=0 length_fields=none length_field_indexes=none length_field_index_count=0 length_field_count=0 pointer_length_fields=none pointer_length_field_indexes=none pointer_length_field_index_count=0 pointer_length_field_count=0 fields=data,len field_indexes=data:0,len:1 field_index_count=2 field_count=2 nullable_fields=none nullable_field_indexes=none nullable_field_index_count=0 nullable_field_count=0 null_sentinels=none null_sentinel_indexes=none null_sentinel_index_count=0 null_sentinel_count=0 pointer_policy="direct-global-symbol" pointer_policy_count=1 storage_policy="static-descriptor-global" storage_policy_count=1 mutability="constant" mutability_count=1 linkage="linkonce_odr unnamed_addr constant" linkage_count=1 alignment="align 8" alignment_count=1
@__faber_text_literal_text_16_64_69_76_69_73_69_6f_6e_20_62_79_20_7a_65_72_6f_object = linkonce_odr unnamed_addr constant { ptr, i64 } { ptr getelementptr inbounds ([17 x i8], ptr @__faber_text_literal_text_16_64_69_76_69_73_69_6f_6e_20_62_79_20_7a_65_72_6f, i64 0, i64 0), i64 16 }, align 8
; @runtime __faber_rt_v1_diagnostic_mone_text category=host-integration
declare i32 @__faber_rt_v1_diagnostic_mone_text(ptr, ptr)
; @runtime __faber_rt_v1_diagnostic_nota_i64 category=host-integration
declare i32 @__faber_rt_v1_diagnostic_nota_i64(ptr, i64)
define { i1, i64, ptr } @divide(i64 %l0, i64 %l1) {
entry:
%l0.addr = alloca i64
%l1.addr = alloca i64
%t0.addr = alloca i1
%t1.addr = alloca ptr
%t2.addr = alloca i128
%t3.addr = alloca i64
store i64 %l0, ptr %l0.addr
store i64 %l1, ptr %l1.addr
br label %b0
b0:
%load0 = load i64, ptr %l1.addr
%v0 = icmp eq i64 %load0, 0
store i1 %v0, ptr %t0.addr
%load1 = load i1, ptr %t0.addr
br i1 %load1, label %b1, label %b2
b1:
store ptr @__faber_text_literal_text_16_64_69_76_69_73_69_6f_6e_20_62_79_20_7a_65_72_6f_object, ptr %t1.addr
%load2 = load ptr, ptr %t1.addr
%ret3 = insertvalue { i1, i64, ptr } undef, i1 false, 0
%ret4 = insertvalue { i1, i64, ptr } %ret3, i64 0, 1
%ret5 = insertvalue { i1, i64, ptr } %ret4, ptr %load2, 2
ret { i1, i64, ptr } %ret5
b2:
%load6 = load i64, ptr %l0.addr
%ex.w7 = sext i64 %load6 to i128
%load8 = load i64, ptr %l1.addr
%ex.w9 = sext i64 %load8 to i128
%ex.zero10 = icmp eq i128 %ex.w9, 0
br i1 %ex.zero10, label %ex.trap11, label %ex.ok11
ex.trap11:
%ex.ctx11 = load ptr, ptr @__faber_rt_v1_context
call void @__faber_rt_v1_fatal(ptr %ex.ctx11, %FaberRtSliceV1 { ptr getelementptr inbounds ([23 x i8], ptr @__faber_trap_msg_6e756d65727573206469766973696f6e206661696c6564, i64 0, i64 0), i64 23 })
unreachable
ex.ok11:
%ex.neg12 = icmp slt i128 %ex.w7, 0
%ex.flip13 = sub i128 0, %ex.w7
%ex.mag14 = select i1 %ex.neg12, i128 %ex.flip13, i128 %ex.w7
%ex.neg15 = icmp slt i128 %ex.w9, 0
%ex.flip16 = sub i128 0, %ex.w9
%ex.mag17 = select i1 %ex.neg15, i128 %ex.flip16, i128 %ex.w9
%ex.at18 = trunc i128 %ex.mag14 to i64
%ex.bt19 = trunc i128 %ex.mag17 to i64
%ex.q20 = udiv i64 %ex.at18, %ex.bt19
%ex.r21 = urem i64 %ex.at18, %ex.bt19
%ex.qz22 = zext i64 %ex.q20 to i128
%ex.sgn23 = xor i1 %ex.neg12, %ex.neg15
%ex.rem24 = icmp ne i64 %ex.r21, 0
%ex.adj25 = and i1 %ex.sgn23, %ex.rem24
%ex.bump26 = add i128 %ex.qz22, 1
%ex.qmag27 = select i1 %ex.adj25, i128 %ex.bump26, i128 %ex.qz22
%ex.qneg28 = sub i128 0, %ex.qmag27
%ex.floor29 = select i1 %ex.sgn23, i128 %ex.qneg28, i128 %ex.qmag27
%ex.cb30 = add i128 %ex.floor29, 9223372036854775808
%ex.cbad31 = icmp ugt i128 %ex.cb30, 27670116110564327423
br i1 %ex.cbad31, label %ex.trap32, label %ex.ok32
ex.trap32:
%ex.ctx32 = load ptr, ptr @__faber_rt_v1_context
call void @__faber_rt_v1_numerus_overflow(ptr %ex.ctx32)
unreachable
ex.ok32:
store i128 %ex.floor29, ptr %t2.addr
%ex.wl33 = load i128, ptr %t2.addr
%ex.store34 = trunc i128 %ex.wl33 to i64
%ex.back35 = sext i64 %ex.store34 to i128
%ex.bad36 = icmp ne i128 %ex.back35, %ex.wl33
br i1 %ex.bad36, label %ex.trap37, label %ex.ok37
ex.trap37:
call void @__faber_trap_store(i128 %ex.wl33, ptr getelementptr inbounds ([31 x i8], ptr @__faber_trap_msg_20646f6573206e6f742066697420696e206069363460202872657475726e29, i64 0, i64 0), i64 31)
unreachable
ex.ok37:
store i64 %ex.store34, ptr %t3.addr
%ret38 = insertvalue { i1, i64, ptr } undef, i1 true, 0
%load39 = load i64, ptr %t3.addr
%ret40 = insertvalue { i1, i64, ptr } %ret38, i64 %load39, 1
%ret41 = insertvalue { i1, i64, ptr } %ret40, ptr null, 2
ret { i1, i64, ptr } %ret41
}
define void @main() {
entry:
%l0.addr = alloca ptr
%t0.addr = alloca i64
br label %b0
b0:
%try0 = call { i1, i64, ptr } @divide(i64 10, i64 2)
%try_tag1 = extractvalue { i1, i64, ptr } %try0, 0
br i1 %try_tag1, label %try_ok2, label %try_error3
try_ok2:
%try_success4 = extractvalue { i1, i64, ptr } %try0, 1
store i64 %try_success4, ptr %t0.addr
br label %b4
try_error3:
%try_error_value5 = extractvalue { i1, i64, ptr } %try0, 2
store ptr %try_error_value5, ptr %l0.addr
br label %b1
b1:
%load6 = load ptr, ptr %l0.addr
%faber.context7 = load ptr, ptr @__faber_rt_v1_context
%faber.diag.status7 = call i32 @__faber_rt_v1_diagnostic_mone_text(ptr %faber.context7, ptr %load6)
%faber.old.status7 = load i32, ptr @__faber_rt_v1_status
%faber.has.error7 = icmp ne i32 %faber.old.status7, 0
%faber.latched.status7 = select i1 %faber.has.error7, i32 %faber.old.status7, i32 %faber.diag.status7
store i32 %faber.latched.status7, ptr @__faber_rt_v1_status
br label %b2
b2:
ret void
b3:
br label %b2
b4:
%load8 = load i64, ptr %t0.addr
%faber.context9 = load ptr, ptr @__faber_rt_v1_context
%faber.diag.status9 = call i32 @__faber_rt_v1_diagnostic_nota_i64(ptr %faber.context9, i64 %load8)
%faber.old.status9 = load i32, ptr @__faber_rt_v1_status
%faber.has.error9 = icmp ne i32 %faber.old.status9, 0
%faber.latched.status9 = select i1 %faber.has.error9, i32 %faber.old.status9, i32 %faber.diag.status9
store i32 %faber.latched.status9, ptr @__faber_rt_v1_status
br label %b3
}
define %FaberRtExitV1 @__faber_program_entry_v1(ptr %context) {
entry:
store ptr %context, ptr @__faber_rt_v1_context
call void @main()
%faber.entry.status = load i32, ptr @__faber_rt_v1_status
%faber.entry.status.ext = zext i32 %faber.entry.status to i64
%faber.entry.shifted = shl i64 %faber.entry.status.ext, 32
%faber.entry.packed = or i64 0, %faber.entry.shifted
ret %FaberRtExitV1 %faber.entry.packed
}
@__faber_trap_msg_20646f6573206e6f742066697420696e206069363460202872657475726e29 = linkonce_odr unnamed_addr constant [31 x i8] c" does not fit in \60i64\60 \28return\29", align 1
@__faber_trap_msg_6e756d65727573206469766973696f6e206661696c6564 = linkonce_odr unnamed_addr constant [23 x i8] c"numerus division failed", align 1
declare void @llvm.memcpy.p0.p0.i64(ptr, ptr, i64, i1)
define linkonce_odr void @__faber_trap_store(i128 %v, ptr %sfx, i64 %n) noreturn {
entry:
%ctx = load ptr, ptr @__faber_rt_v1_context
%cap = add i64 %n, 24
%buf = alloca i8, i64 %cap
%digits = alloca [24 x i8]
%neg = icmp slt i128 %v, 0
%negv = sub i128 0, %v
%mag128 = select i1 %neg, i128 %negv, i128 %v
%mag = trunc i128 %mag128 to i64
br label %loop
loop:
%i = phi i64 [ 24, %entry ], [ %i2, %loop ]
%m = phi i64 [ %mag, %entry ], [ %q, %loop ]
%r = urem i64 %m, 10
%q = udiv i64 %m, 10
%c = add i64 %r, 48
%c8 = trunc i64 %c to i8
%i2 = sub i64 %i, 1
%p = getelementptr i8, ptr %digits, i64 %i2
store i8 %c8, ptr %p
%done = icmp eq i64 %q, 0
br i1 %done, label %copy, label %loop
copy:
%len = sub i64 24, %i2
%signlen = zext i1 %neg to i64
br i1 %neg, label %sign, label %body
sign:
store i8 45, ptr %buf
br label %body
body:
%dst = getelementptr i8, ptr %buf, i64 %signlen
%src = getelementptr i8, ptr %digits, i64 %i2
call void @llvm.memcpy.p0.p0.i64(ptr %dst, ptr %src, i64 %len, i1 false)
%off = add i64 %signlen, %len
%dst2 = getelementptr i8, ptr %buf, i64 %off
call void @llvm.memcpy.p0.p0.i64(ptr %dst2, ptr %sfx, i64 %n, i1 false)
%total = add i64 %off, %n
%s0 = insertvalue %FaberRtSliceV1 undef, ptr %buf, 0
%s1 = insertvalue %FaberRtSliceV1 %s0, i64 %total, 1
call void @__faber_rt_v1_fatal(ptr %ctx, %FaberRtSliceV1 %s1)
unreachable
}Collections and iteration#
A list folded to a total with for from. The plainest possible read on how loops lower.
Faber source
fn sum(list<int> numeri) → int {
var int total ← 0
for from numeri const n {
total ← total + n
}
return total
}
main {
const list<int> valores ← [1, 2, 3, 4, 5]
print sum(valores)
}LLVM IR — 12 lines in, 250 out (20.8×)
; Generated by radix MIR LLVM IR probe - experimental artifact.
%FaberRtSliceV1 = type { ptr, i64 }
%FaberRtExitV1 = type i64
%FaberRtPtrResultV1 = type { i32, ptr }
%FaberRtStatusV1 = type { i32 }
@__faber_rt_v1_context = linkonce_odr global ptr null
@__faber_rt_v1_status = linkonce_odr global i32 0
declare void @__faber_rt_v1_fatal(ptr, %FaberRtSliceV1) noreturn
declare void @__faber_rt_v1_numerus_overflow(ptr) noreturn
; @runtime __faber_rt_v1_array_get category=core-semantics
declare i32 @__faber_rt_v1_array_get(ptr, ptr, i64, i32, ptr)
; @runtime __faber_rt_v1_array_length category=core-semantics
declare i32 @__faber_rt_v1_array_length(ptr, ptr, ptr)
; @runtime __faber_rt_v1_array_new category=core-semantics
declare %FaberRtPtrResultV1 @__faber_rt_v1_array_new(ptr, i32)
; @runtime __faber_rt_v1_array_push category=core-semantics
declare i32 @__faber_rt_v1_array_push(ptr, ptr, i32, ptr)
; @runtime __faber_rt_v1_diagnostic_nota_i64 category=host-integration
declare i32 @__faber_rt_v1_diagnostic_nota_i64(ptr, i64)
define i64 @sum(ptr %l0) {
entry:
%l0.addr = alloca ptr
%l1.addr = alloca i64
%l2.addr = alloca i64
%l3.addr = alloca i64
%t0.addr = alloca i64
%t1.addr = alloca i1
%t2.addr = alloca i128
%t3.addr = alloca i64
%t4.addr = alloca i128
store ptr %l0, ptr %l0.addr
br label %b0
b0:
store i64 0, ptr %l1.addr
store i64 0, ptr %l2.addr
%load0 = load ptr, ptr %l0.addr
%faber.array.length.out1 = alloca i64
store i64 0, ptr %faber.array.length.out1
%faber.context1 = load ptr, ptr @__faber_rt_v1_context
%faber.array.length.status1 = call i32 @__faber_rt_v1_array_length(ptr %faber.context1, ptr %load0, ptr %faber.array.length.out1)
%faber.array.length1 = load i64, ptr %faber.array.length.out1
%faber.old.status1 = load i32, ptr @__faber_rt_v1_status
%faber.has.error1 = icmp ne i32 %faber.old.status1, 0
%faber.latched.status1 = select i1 %faber.has.error1, i32 %faber.old.status1, i32 %faber.array.length.status1
store i32 %faber.latched.status1, ptr @__faber_rt_v1_status
store i64 %faber.array.length1, ptr %t0.addr
br label %b1
b1:
%load2 = load i64, ptr %l2.addr
%load3 = load i64, ptr %t0.addr
%v2 = icmp slt i64 %load2, %load3
store i1 %v2, ptr %t1.addr
%load4 = load i1, ptr %t1.addr
br i1 %load4, label %b2, label %b4
b2:
%load5 = load ptr, ptr %l0.addr
%load6 = load i64, ptr %l2.addr
%faber.array.get.out7 = alloca i64
store i64 0, ptr %faber.array.get.out7
%faber.context7 = load ptr, ptr @__faber_rt_v1_context
%faber.array.get.status7 = call i32 @__faber_rt_v1_array_get(ptr %faber.context7, ptr %load5, i64 %load6, i32 4, ptr %faber.array.get.out7)
%faber.array.get.value7 = load i64, ptr %faber.array.get.out7
%faber.old.status7 = load i32, ptr @__faber_rt_v1_status
%faber.has.error7 = icmp ne i32 %faber.old.status7, 0
%faber.latched.status7 = select i1 %faber.has.error7, i32 %faber.old.status7, i32 %faber.array.get.status7
store i32 %faber.latched.status7, ptr @__faber_rt_v1_status
store i64 %faber.array.get.value7, ptr %l3.addr
%load8 = load i64, ptr %l1.addr
%ex.w9 = sext i64 %load8 to i128
%load10 = load i64, ptr %l3.addr
%ex.w11 = sext i64 %load10 to i128
%ex.add12 = add i128 %ex.w9, %ex.w11
%ex.cb13 = add i128 %ex.add12, 9223372036854775808
%ex.cbad14 = icmp ugt i128 %ex.cb13, 27670116110564327423
br i1 %ex.cbad14, label %ex.trap15, label %ex.ok15
ex.trap15:
%ex.ctx15 = load ptr, ptr @__faber_rt_v1_context
call void @__faber_rt_v1_numerus_overflow(ptr %ex.ctx15)
unreachable
ex.ok15:
store i128 %ex.add12, ptr %t2.addr
%ex.wl16 = load i128, ptr %t2.addr
%ex.store17 = trunc i128 %ex.wl16 to i64
%ex.back18 = sext i64 %ex.store17 to i128
%ex.bad19 = icmp ne i128 %ex.back18, %ex.wl16
br i1 %ex.bad19, label %ex.trap20, label %ex.ok20
ex.trap20:
call void @__faber_trap_store(i128 %ex.wl16, ptr getelementptr inbounds ([46 x i8], ptr @__faber_trap_msg_20646f6573206e6f742066697420696e206069363460202861737369676e6d656e7420746f2060746f74616c6029, i64 0, i64 0), i64 46)
unreachable
ex.ok20:
store i64 %ex.store17, ptr %t3.addr
%load21 = load i64, ptr %t3.addr
store i64 %load21, ptr %l1.addr
br label %b3
b3:
%load22 = load i64, ptr %l2.addr
%ex.w23 = sext i64 %load22 to i128
%ex.w24 = sext i64 1 to i128
%ex.add25 = add i128 %ex.w23, %ex.w24
%ex.cb26 = add i128 %ex.add25, 9223372036854775808
%ex.cbad27 = icmp ugt i128 %ex.cb26, 27670116110564327423
br i1 %ex.cbad27, label %ex.trap28, label %ex.ok28
ex.trap28:
%ex.ctx28 = load ptr, ptr @__faber_rt_v1_context
call void @__faber_rt_v1_numerus_overflow(ptr %ex.ctx28)
unreachable
ex.ok28:
store i128 %ex.add25, ptr %t4.addr
%ex.wl29 = load i128, ptr %t4.addr
%ex.nr30 = trunc i128 %ex.wl29 to i64
%ex.back31 = sext i64 %ex.nr30 to i128
%ex.bad32 = icmp ne i128 %ex.back31, %ex.wl29
br i1 %ex.bad32, label %ex.trap33, label %ex.ok33
ex.trap33:
%ex.ctx33 = load ptr, ptr @__faber_rt_v1_context
call void @__faber_rt_v1_numerus_overflow(ptr %ex.ctx33)
unreachable
ex.ok33:
store i64 %ex.nr30, ptr %l2.addr
br label %b1
b4:
%load34 = load i64, ptr %l1.addr
ret i64 %load34
}
define void @main() {
entry:
%l0.addr = alloca ptr
%t0.addr = alloca ptr
%t1.addr = alloca i64
br label %b0
b0:
%faber.context0 = load ptr, ptr @__faber_rt_v1_context
%faber.array.result0 = call %FaberRtPtrResultV1 @__faber_rt_v1_array_new(ptr %faber.context0, i32 4)
%faber.array.status0 = extractvalue %FaberRtPtrResultV1 %faber.array.result0, 0
%faber.array.handle0 = extractvalue %FaberRtPtrResultV1 %faber.array.result0, 1
%faber.old.status0 = load i32, ptr @__faber_rt_v1_status
%faber.has.error0 = icmp ne i32 %faber.old.status0, 0
%faber.latched.status0 = select i1 %faber.has.error0, i32 %faber.old.status0, i32 %faber.array.status0
store i32 %faber.latched.status0, ptr @__faber_rt_v1_status
%faber.array.value1 = alloca i64
store i64 1, ptr %faber.array.value1
%faber.array.status1 = call i32 @__faber_rt_v1_array_push(ptr %faber.context0, ptr %faber.array.handle0, i32 4, ptr %faber.array.value1)
%faber.old.status1 = load i32, ptr @__faber_rt_v1_status
%faber.has.error1 = icmp ne i32 %faber.old.status1, 0
%faber.latched.status1 = select i1 %faber.has.error1, i32 %faber.old.status1, i32 %faber.array.status1
store i32 %faber.latched.status1, ptr @__faber_rt_v1_status
%faber.array.value2 = alloca i64
store i64 2, ptr %faber.array.value2
%faber.array.status2 = call i32 @__faber_rt_v1_array_push(ptr %faber.context0, ptr %faber.array.handle0, i32 4, ptr %faber.array.value2)
%faber.old.status2 = load i32, ptr @__faber_rt_v1_status
%faber.has.error2 = icmp ne i32 %faber.old.status2, 0
%faber.latched.status2 = select i1 %faber.has.error2, i32 %faber.old.status2, i32 %faber.array.status2
store i32 %faber.latched.status2, ptr @__faber_rt_v1_status
%faber.array.value3 = alloca i64
store i64 3, ptr %faber.array.value3
%faber.array.status3 = call i32 @__faber_rt_v1_array_push(ptr %faber.context0, ptr %faber.array.handle0, i32 4, ptr %faber.array.value3)
%faber.old.status3 = load i32, ptr @__faber_rt_v1_status
%faber.has.error3 = icmp ne i32 %faber.old.status3, 0
%faber.latched.status3 = select i1 %faber.has.error3, i32 %faber.old.status3, i32 %faber.array.status3
store i32 %faber.latched.status3, ptr @__faber_rt_v1_status
%faber.array.value4 = alloca i64
store i64 4, ptr %faber.array.value4
%faber.array.status4 = call i32 @__faber_rt_v1_array_push(ptr %faber.context0, ptr %faber.array.handle0, i32 4, ptr %faber.array.value4)
%faber.old.status4 = load i32, ptr @__faber_rt_v1_status
%faber.has.error4 = icmp ne i32 %faber.old.status4, 0
%faber.latched.status4 = select i1 %faber.has.error4, i32 %faber.old.status4, i32 %faber.array.status4
store i32 %faber.latched.status4, ptr @__faber_rt_v1_status
%faber.array.value5 = alloca i64
store i64 5, ptr %faber.array.value5
%faber.array.status5 = call i32 @__faber_rt_v1_array_push(ptr %faber.context0, ptr %faber.array.handle0, i32 4, ptr %faber.array.value5)
%faber.old.status5 = load i32, ptr @__faber_rt_v1_status
%faber.has.error5 = icmp ne i32 %faber.old.status5, 0
%faber.latched.status5 = select i1 %faber.has.error5, i32 %faber.old.status5, i32 %faber.array.status5
store i32 %faber.latched.status5, ptr @__faber_rt_v1_status
store ptr %faber.array.handle0, ptr %t0.addr
%load6 = load ptr, ptr %t0.addr
store ptr %load6, ptr %l0.addr
%load7 = load ptr, ptr %l0.addr
%call8 = call i64 @sum(ptr %load7)
store i64 %call8, ptr %t1.addr
%load9 = load i64, ptr %t1.addr
%faber.context10 = load ptr, ptr @__faber_rt_v1_context
%faber.diag.status10 = call i32 @__faber_rt_v1_diagnostic_nota_i64(ptr %faber.context10, i64 %load9)
%faber.old.status10 = load i32, ptr @__faber_rt_v1_status
%faber.has.error10 = icmp ne i32 %faber.old.status10, 0
%faber.latched.status10 = select i1 %faber.has.error10, i32 %faber.old.status10, i32 %faber.diag.status10
store i32 %faber.latched.status10, ptr @__faber_rt_v1_status
ret void
}
define %FaberRtExitV1 @__faber_program_entry_v1(ptr %context) {
entry:
store ptr %context, ptr @__faber_rt_v1_context
call void @main()
%faber.entry.status = load i32, ptr @__faber_rt_v1_status
%faber.entry.status.ext = zext i32 %faber.entry.status to i64
%faber.entry.shifted = shl i64 %faber.entry.status.ext, 32
%faber.entry.packed = or i64 0, %faber.entry.shifted
ret %FaberRtExitV1 %faber.entry.packed
}
@__faber_trap_msg_20646f6573206e6f742066697420696e206069363460202861737369676e6d656e7420746f2060746f74616c6029 = linkonce_odr unnamed_addr constant [46 x i8] c" does not fit in \60i64\60 \28assignment to \60total\60\29", align 1
declare void @llvm.memcpy.p0.p0.i64(ptr, ptr, i64, i1)
define linkonce_odr void @__faber_trap_store(i128 %v, ptr %sfx, i64 %n) noreturn {
entry:
%ctx = load ptr, ptr @__faber_rt_v1_context
%cap = add i64 %n, 24
%buf = alloca i8, i64 %cap
%digits = alloca [24 x i8]
%neg = icmp slt i128 %v, 0
%negv = sub i128 0, %v
%mag128 = select i1 %neg, i128 %negv, i128 %v
%mag = trunc i128 %mag128 to i64
br label %loop
loop:
%i = phi i64 [ 24, %entry ], [ %i2, %loop ]
%m = phi i64 [ %mag, %entry ], [ %q, %loop ]
%r = urem i64 %m, 10
%q = udiv i64 %m, 10
%c = add i64 %r, 48
%c8 = trunc i64 %c to i8
%i2 = sub i64 %i, 1
%p = getelementptr i8, ptr %digits, i64 %i2
store i8 %c8, ptr %p
%done = icmp eq i64 %q, 0
br i1 %done, label %copy, label %loop
copy:
%len = sub i64 24, %i2
%signlen = zext i1 %neg to i64
br i1 %neg, label %sign, label %body
sign:
store i8 45, ptr %buf
br label %body
body:
%dst = getelementptr i8, ptr %buf, i64 %signlen
%src = getelementptr i8, ptr %digits, i64 %i2
call void @llvm.memcpy.p0.p0.i64(ptr %dst, ptr %src, i64 %len, i1 false)
%off = add i64 %signlen, %len
%dst2 = getelementptr i8, ptr %buf, i64 %off
call void @llvm.memcpy.p0.p0.i64(ptr %dst2, ptr %sfx, i64 %n, i1 false)
%total = add i64 %off, %n
%s0 = insertvalue %FaberRtSliceV1 undef, ptr %buf, 0
%s1 = insertvalue %FaberRtSliceV1 %s0, i64 %total, 1
call void @__faber_rt_v1_fatal(ptr %ctx, %FaberRtSliceV1 %s1)
unreachable
}---