Skip to content

Instantly share code, notes, and snippets.

@FreeMasen
Created September 30, 2023 00:30
Show Gist options
  • Save FreeMasen/b9b754d4ebb4cd174de89511b987eb4f to your computer and use it in GitHub Desktop.
Save FreeMasen/b9b754d4ebb4cd174de89511b987eb4f to your computer and use it in GitHub Desktop.
add test ir for luminary compiler
; ModuleID = 'std::tvalue'
source_filename = "std::tvalue"
%"std::tvalue::TValue" = type { i8, [23 x i8] }
%"std::tvalue::TValue::Bool" = type { [23 x i8], i8 }
%"std::tvalue::TValue::Number" = type { [12 x i8], float }
%"std::tvalue::TValue::String" = type { i8, i32, i32, i32, ptr }
@"tvalue::names::nil" = global [5 x i8] c"nil\0A\00"
@"tvalue::names::true" = global [6 x i8] c"true\0A\00"
@"tvalue::names::false" = global [7 x i8] c"false\0A\00"
@"tvalue::names::float_fmt" = global [4 x i8] c"%f\0A\00"
; Function Attrs: nounwind
declare ptr @malloc(i32) #0
define void @"std::tvalue::new_nil"(ptr %0) {
entry:
%tag_ptr = getelementptr inbounds %"std::tvalue::TValue", ptr %0, i32 0, i32 0
store i8 0, ptr %tag_ptr, align 1
%data_ptr = getelementptr inbounds %"std::tvalue::TValue", ptr %0, i32 0, i32 1
store [15 x i8] zeroinitializer, ptr %data_ptr, align 1
ret void
}
define void @"std::tvalue::new_bool"(ptr %0, i1 %1) {
entry:
%tag_ptr = getelementptr inbounds %"std::tvalue::TValue", ptr %0, i32 0, i32 0
store i8 1, ptr %tag_ptr, align 1
%data_ptr = getelementptr inbounds %"std::tvalue::TValue::Bool", ptr %0, i32 0, i32 1
store i1 %1, ptr %data_ptr, align 1
ret void
}
define void @"std::tvalue::new_num"(ptr %0, float %1) {
entry:
%tag_ptr = getelementptr inbounds %"std::tvalue::TValue", ptr %0, i32 0, i32 0
store i8 2, ptr %tag_ptr, align 1
%data_ptr = getelementptr inbounds %"std::tvalue::TValue::Number", ptr %0, i32 0, i32 1
store float %1, ptr %data_ptr, align 4
ret void
}
define void @"std::tvalue::new_str"(ptr %0, i32 %1) {
entry:
%tag_ptr = getelementptr inbounds %"std::tvalue::TValue", ptr %0, i32 0, i32 0
store i8 3, ptr %tag_ptr, align 1
%len_ptr = getelementptr inbounds %"std::tvalue::TValue::String", ptr %0, i32 0, i32 1
store i32 0, ptr %len_ptr, align 4
%cap_ptr = getelementptr inbounds %"std::tvalue::TValue::String", ptr %0, i32 0, i32 2
store i32 %1, ptr %cap_ptr, align 4
%ref_ct = getelementptr inbounds %"std::tvalue::TValue::String", ptr %0, i32 0, i32 3
store i32 0, ptr %ref_ct, align 4
%bytes_ptr = call ptr @malloc(i32 %1)
%storage = getelementptr inbounds %"std::tvalue::TValue::String", ptr %0, i32 0, i32 4
store ptr %bytes_ptr, ptr %storage, align 8
ret void
}
define i8 @"std::tvalue::get_tag"(ptr %tagged_value) {
entry:
%tag_ptr = getelementptr inbounds %"std::tvalue::TValue", ptr %tagged_value, i32 0, i32 0
%tag_val = load i8, ptr %tag_ptr, align 1
ret i8 %tag_val
}
define i1 @"std::tvalue::is_truthy"(ptr %tagged_value) {
entry:
%tag = call i8 @"std::tvalue::get_tag"(ptr %tagged_value)
%is_nil = icmp eq i8 %tag, 0
br i1 %is_nil, label %is_nil1, label %is_not_nil
is_nil1: ; preds = %entry
ret i1 false
is_not_nil: ; preds = %entry
%is_bool = icmp eq i8 %tag, 1
br i1 %is_bool, label %is_bool2, label %is_not_bool
is_bool2: ; preds = %is_not_nil
%raw_variant_pointer = getelementptr inbounds %"std::tvalue::TValue::Bool", ptr %tagged_value, i32 0, i32 1
%bool_t_int = load i8, ptr %raw_variant_pointer, align 1
%ret = icmp ugt i8 %bool_t_int, 0
ret i1 %ret
is_not_bool: ; preds = %is_not_nil
ret i1 true
}
define i1 @"std::tvalue::is_number"(ptr %0) {
entry:
%tag = call i8 @"std::tvalue::get_tag"(ptr %0)
%cmp = icmp eq i8 %tag, 2
ret i1 %cmp
}
define float @"std::tvalue::get_value_number"(ptr %0) {
entry:
%is_num = call i1 @"std::tvalue::is_number"(ptr %0)
br i1 %is_num, label %ian, label %nan
ian: ; preds = %entry
%value_ptr = getelementptr inbounds %"std::tvalue::TValue::Number", ptr %0, i32 0, i32 1
%value = load float, ptr %value_ptr, align 4
ret float %value
nan: ; preds = %entry
ret float 0x7FF8000000000000
}
declare i32 @printf(ptr, ...)
declare i32 @write(i32, ptr, i32)
define void @"std::tvalue::test::print_tvalue_string"(ptr %0) {
entry:
%len_ptr = getelementptr inbounds %"std::tvalue::TValue::String", ptr %0, i32 0, i32 1
%len = load i32, ptr %len_ptr, align 4
%bytes_ptr_ptr = getelementptr inbounds %"std::tvalue::TValue::String", ptr %0, i32 0, i32 4
%bytes_ptr = load ptr, ptr %bytes_ptr_ptr, align 8
%_ = call i32 @write(i32 1, ptr %bytes_ptr, i32 %len)
ret void
}
define void @"std::tvalue::test::print_tvalue_raw"(ptr %0) {
entry:
%ob = alloca [2 x i8], align 1
store [2 x i8] c"[\00", ptr %ob, align 1
%_ = call i32 (ptr, ...) @printf(ptr %ob)
br label %looptop
looptop: ; preds = %looptop, %entry
%idx = phi i32 [ %nextidx, %looptop ], [ 0, %entry ]
%nextidx = add i32 %idx, 1
%ch = getelementptr [16 x i8], ptr %0, i32 0, i32 %idx
%ch1 = load i8, ptr %ch, align 1
%ch_fmt = alloca [5 x i8], align 1
store [5 x i8] c"%*i,\00", ptr %ch_fmt, align 1
%_2 = call i32 (ptr, ...) @printf(ptr %ch_fmt, i8 3, i8 %ch1)
%done = icmp uge i32 %nextidx, ptrtoint (ptr getelementptr (%"std::tvalue::TValue", ptr null, i32 1) to i32)
br i1 %done, label %exit, label %looptop
exit: ; preds = %looptop
%cb = alloca [3 x i8], align 1
store [3 x i8] c"]\0A\00", ptr %cb, align 1
%_3 = call i32 (ptr, ...) @printf(ptr %cb)
ret void
}
define void @"std::tvalue::test::print_tvalue"(ptr %0) {
entry:
%tag = call i8 @"std::tvalue::get_tag"(ptr %0)
switch i8 %tag, label %unknown [
i8 0, label %nil
i8 1, label %boolean
i8 2, label %number
i8 3, label %string
]
unknown: ; preds = %entry
call void @"std::tvalue::test::print_tvalue_raw"(ptr %0)
ret void
nil: ; preds = %entry
%_ = call i32 (ptr, ...) @printf(ptr @"tvalue::names::nil")
ret void
boolean: ; preds = %entry
%truthy_ptr = getelementptr inbounds %"std::tvalue::TValue::Bool", ptr %0, i32 0, i32 1
%truthy = load i1, ptr %truthy_ptr, align 1
br i1 %truthy, label %bool_true, label %bool_false
number: ; preds = %entry
%num_ptr = getelementptr inbounds %"std::tvalue::TValue::Number", ptr %0, i32 0, i32 1
%num = load float, ptr %num_ptr, align 4
%dbl = fpext float %num to double
%_3 = call i32 (ptr, ...) @printf(ptr @"tvalue::names::float_fmt", double %dbl)
ret void
string: ; preds = %entry
call void @"std::tvalue::test::print_tvalue_string"(ptr %0)
ret void
bool_true: ; preds = %boolean
%_1 = call i32 (ptr, ...) @printf(ptr @"tvalue::names::true")
ret void
bool_false: ; preds = %boolean
%_2 = call i32 (ptr, ...) @printf(ptr @"tvalue::names::false")
ret void
}
define i1 @"std::tvalue::is_two_numbers"(ptr %lhs, ptr %rhs) {
entry:
%lhs_is_num = call i1 @"std::tvalue::is_number"(ptr %lhs)
br i1 %lhs_is_num, label %lhs_ian, label %nan
nan: ; preds = %lhs_ian, %entry
ret i1 false
lhs_ian: ; preds = %entry
%rhs_is_num = call i1 @"std::tvalue::is_number"(ptr %rhs)
br i1 %rhs_is_num, label %rhs_ian, label %nan
rhs_ian: ; preds = %lhs_ian
ret i1 true
}
define i1 @"std::tvalue::add"(ptr %lhs, ptr %rhs, ptr %out) {
entry:
%are_nums = call i1 @"std::tvalue::is_two_numbers"(ptr %lhs, ptr %rhs)
br i1 %are_nums, label %ian, label %nan
ian: ; preds = %entry
%lhs_value = call float @"std::tvalue::get_value_number"(ptr %lhs)
%rhs_value = call float @"std::tvalue::get_value_number"(ptr %rhs)
%out_value = fadd float %lhs_value, %rhs_value
call void @"std::tvalue::new_num"(ptr %out, float %out_value)
ret i1 true
nan: ; preds = %entry
ret i1 false
}
define i1 @"std::tvalue::sub"(ptr %lhs, ptr %rhs, ptr %out) {
entry:
%are_nums = call i1 @"std::tvalue::is_two_numbers"(ptr %lhs, ptr %rhs)
br i1 %are_nums, label %ian, label %nan
ian: ; preds = %entry
%lhs_value = call float @"std::tvalue::get_value_number"(ptr %lhs)
%rhs_value = call float @"std::tvalue::get_value_number"(ptr %rhs)
%out_value = fsub float %lhs_value, %rhs_value
call void @"std::tvalue::new_num"(ptr %out, float %out_value)
ret i1 true
nan: ; preds = %entry
ret i1 false
}
define i1 @"std::tvalue::mul"(ptr %lhs, ptr %rhs, ptr %out) {
entry:
%are_nums = call i1 @"std::tvalue::is_two_numbers"(ptr %lhs, ptr %rhs)
br i1 %are_nums, label %ian, label %nan
ian: ; preds = %entry
%lhs_value = call float @"std::tvalue::get_value_number"(ptr %lhs)
%rhs_value = call float @"std::tvalue::get_value_number"(ptr %rhs)
%out_value = fmul float %lhs_value, %rhs_value
call void @"std::tvalue::new_num"(ptr %out, float %out_value)
ret i1 true
nan: ; preds = %entry
ret i1 false
}
define i1 @"std::tvalue::div"(ptr %lhs, ptr %rhs, ptr %out) {
entry:
%are_nums = call i1 @"std::tvalue::is_two_numbers"(ptr %lhs, ptr %rhs)
br i1 %are_nums, label %ian, label %nan
ian: ; preds = %entry
%lhs_value = call float @"std::tvalue::get_value_number"(ptr %lhs)
%rhs_value = call float @"std::tvalue::get_value_number"(ptr %rhs)
%out_value = fdiv float %lhs_value, %rhs_value
call void @"std::tvalue::new_num"(ptr %out, float %out_value)
ret i1 true
nan: ; preds = %entry
ret i1 false
}
; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none)
declare float @llvm.floor.f32(float) #1
define i1 @"std::tvalue::floor_div"(ptr %lhs, ptr %rhs, ptr %out) {
entry:
%are_nums = call i1 @"std::tvalue::is_two_numbers"(ptr %lhs, ptr %rhs)
br i1 %are_nums, label %ian, label %nan
ian: ; preds = %entry
%lhs_value = call float @"std::tvalue::get_value_number"(ptr %lhs)
%rhs_value = call float @"std::tvalue::get_value_number"(ptr %rhs)
%out_value = fdiv float %lhs_value, %rhs_value
%ret = call float @llvm.floor.f32(float %out_value)
call void @"std::tvalue::new_num"(ptr %out, float %ret)
ret i1 true
nan: ; preds = %entry
ret i1 false
}
; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none)
declare float @llvm.pow.f32(float, float) #1
define i1 @"std::tvalue::pow"(ptr %lhs, ptr %rhs, ptr %out) {
entry:
%are_nums = call i1 @"std::tvalue::is_two_numbers"(ptr %lhs, ptr %rhs)
br i1 %are_nums, label %ian, label %nan
ian: ; preds = %entry
%lhs_value = call float @"std::tvalue::get_value_number"(ptr %lhs)
%rhs_value = call float @"std::tvalue::get_value_number"(ptr %rhs)
%out_value = call float @llvm.pow.f32(float %lhs_value, float %rhs_value)
call void @"std::tvalue::new_num"(ptr %out, float %out_value)
ret i1 true
nan: ; preds = %entry
ret i1 false
}
define i1 @"std::tvalue::mod"(ptr %lhs, ptr %rhs, ptr %out) {
entry:
%are_nums = call i1 @"std::tvalue::is_two_numbers"(ptr %lhs, ptr %rhs)
br i1 %are_nums, label %ian, label %nan
ian: ; preds = %entry
%lhs_value = call float @"std::tvalue::get_value_number"(ptr %lhs)
%rhs_value = call float @"std::tvalue::get_value_number"(ptr %rhs)
%out_value = frem float %lhs_value, %rhs_value
call void @"std::tvalue::new_num"(ptr %out, float %out_value)
ret i1 true
nan: ; preds = %entry
ret i1 false
}
define i1 @"std::tvalue::NEG"(ptr %0, ptr %1) {
entry:
%arg_ian = call i1 @"std::tvalue::is_number"(ptr %0)
br i1 %arg_ian, label %ian, label %nan
nan: ; preds = %entry
ret i1 false
ian: ; preds = %entry
%lhs_value = call float @"std::tvalue::get_value_number"(ptr %0)
%out_value = fneg float %lhs_value
call void @"std::tvalue::new_num"(ptr %1, float %out_value)
ret i1 true
}
define i1 @"std::tvalue::is_int"(float %0) {
entry:
%floored = call float @llvm.floor.f32(float %0)
%is_int = fcmp oeq float %0, %floored
br i1 %is_int, label %exit, label %nai
exit: ; preds = %entry
ret i1 true
nai: ; preds = %entry
ret i1 false
}
define i1 @"std::tvalue::is_two_ints"(float %lhs, float %rhs) {
entry:
%lhs_is = call i1 @"std::tvalue::is_int"(float %lhs)
br i1 %lhs_is, label %lhs_iai, label %nai
lhs_iai: ; preds = %entry
%rhs_is = call i1 @"std::tvalue::is_int"(float %rhs)
br i1 %rhs_is, label %rhs_iai, label %nai
rhs_iai: ; preds = %lhs_iai
ret i1 true
nai: ; preds = %lhs_iai, %entry
ret i1 false
}
define i1 @"std::tvalue::bin_and"(ptr %lhs, ptr %rhs, ptr %out) {
entry:
%are_nums = call i1 @"std::tvalue::is_two_numbers"(ptr %lhs, ptr %rhs)
br i1 %are_nums, label %ian, label %nan
ian: ; preds = %entry
%lhs_value = call float @"std::tvalue::get_value_number"(ptr %lhs)
%rhs_value = call float @"std::tvalue::get_value_number"(ptr %rhs)
%are_ints = call i1 @"std::tvalue::is_two_ints"(float %lhs_value, float %rhs_value)
br i1 %are_ints, label %two_ints, label %not_ints
nan: ; preds = %entry
ret i1 false
two_ints: ; preds = %ian
%lhs1 = fptosi float %lhs_value to i32
%rhs2 = fptosi float %rhs_value to i32
%anded = and i32 %lhs1, %rhs2
%out3 = sitofp i32 %anded to float
call void @"std::tvalue::new_num"(ptr %out, float %out3)
ret i1 true
not_ints: ; preds = %ian
ret i1 false
}
define i1 @"std::tvalue::bin_or"(ptr %lhs, ptr %rhs, ptr %out) {
entry:
%are_nums = call i1 @"std::tvalue::is_two_numbers"(ptr %lhs, ptr %rhs)
br i1 %are_nums, label %ian, label %nan
ian: ; preds = %entry
%lhs_value = call float @"std::tvalue::get_value_number"(ptr %lhs)
%rhs_value = call float @"std::tvalue::get_value_number"(ptr %rhs)
%are_ints = call i1 @"std::tvalue::is_two_ints"(float %lhs_value, float %rhs_value)
br i1 %are_ints, label %two_ints, label %not_ints
nan: ; preds = %entry
ret i1 false
two_ints: ; preds = %ian
%lhs1 = fptosi float %lhs_value to i32
%rhs2 = fptosi float %rhs_value to i32
%ored = or i32 %lhs1, %rhs2
%out3 = sitofp i32 %ored to float
call void @"std::tvalue::new_num"(ptr %out, float %out3)
ret i1 true
not_ints: ; preds = %ian
ret i1 false
}
define i1 @"std::tvalue::lsh"(ptr %lhs, ptr %rhs, ptr %out) {
entry:
%are_nums = call i1 @"std::tvalue::is_two_numbers"(ptr %lhs, ptr %rhs)
br i1 %are_nums, label %ian, label %nan
ian: ; preds = %entry
%lhs_value = call float @"std::tvalue::get_value_number"(ptr %lhs)
%rhs_value = call float @"std::tvalue::get_value_number"(ptr %rhs)
%are_ints = call i1 @"std::tvalue::is_two_ints"(float %lhs_value, float %rhs_value)
br i1 %are_ints, label %two_ints, label %not_ints
nan: ; preds = %entry
ret i1 false
two_ints: ; preds = %ian
%lhs1 = fptosi float %lhs_value to i32
%rhs2 = fptosi float %rhs_value to i32
%lshed = shl i32 %lhs1, %rhs2
%out3 = sitofp i32 %lshed to float
call void @"std::tvalue::new_num"(ptr %out, float %out3)
ret i1 true
not_ints: ; preds = %ian
ret i1 false
}
define i1 @"std::tvalue::rsh"(ptr %lhs, ptr %rhs, ptr %out) {
entry:
%are_nums = call i1 @"std::tvalue::is_two_numbers"(ptr %lhs, ptr %rhs)
br i1 %are_nums, label %ian, label %nan
ian: ; preds = %entry
%lhs_value = call float @"std::tvalue::get_value_number"(ptr %lhs)
%rhs_value = call float @"std::tvalue::get_value_number"(ptr %rhs)
%are_ints = call i1 @"std::tvalue::is_two_ints"(float %lhs_value, float %rhs_value)
br i1 %are_ints, label %two_ints, label %not_ints
nan: ; preds = %entry
ret i1 false
two_ints: ; preds = %ian
%lhs1 = fptosi float %lhs_value to i32
%rhs2 = fptosi float %rhs_value to i32
%rshed = lshr i32 %lhs1, %rhs2
%out3 = sitofp i32 %rshed to float
call void @"std::tvalue::new_num"(ptr %out, float %out3)
ret i1 true
not_ints: ; preds = %ian
ret i1 false
}
define i1 @"std::tvalue::bin_not"(ptr %value, ptr %out) {
entry:
%is_num = call i1 @"std::tvalue::is_number"(ptr %value)
br i1 %is_num, label %ian, label %no
ian: ; preds = %entry
%value_num = call float @"std::tvalue::get_value_number"(ptr %value)
%is_int = call i1 @"std::tvalue::is_int"(float %value_num)
br i1 %is_int, label %iai, label %no
no: ; preds = %ian, %entry
ret i1 false
iai: ; preds = %ian
%value_int = fptosi float %value_num to i32
%value_int1 = xor i32 %value_int, -1
%ret_float = sitofp i32 %value_int1 to float
call void @"std::tvalue::new_num"(ptr %out, float %ret_float)
ret i1 true
}
define float @test_num_add_happy(float %0, float %1) {
entry:
%lhs = alloca %"std::tvalue::TValue::Number", align 8
call void @"std::tvalue::new_num"(ptr %lhs, float %0)
%lhs1 = alloca %"std::tvalue::TValue::Number", align 8
call void @"std::tvalue::new_num"(ptr %lhs1, float %1)
%ret = alloca %"std::tvalue::TValue::Number", align 8
call void @"std::tvalue::new_num"(ptr %ret, float 0x7FF8000000000000)
%ret2 = call i1 @"std::tvalue::add"(ptr %lhs, ptr %lhs1, ptr %ret)
%ret3 = call float @"std::tvalue::get_value_number"(ptr %ret)
ret float %ret3
}
define float @add_num_bool() {
entry:
%lhs = alloca %"std::tvalue::TValue::Number", align 8
call void @"std::tvalue::new_num"(ptr %lhs, float 1.000000e+00)
%rhs = alloca %"std::tvalue::TValue::Bool", align 8
call void @"std::tvalue::new_bool"(ptr %rhs, float 1.000000e+00)
%ret = alloca %"std::tvalue::TValue::Number", align 8
call void @"std::tvalue::new_num"(ptr %ret, float 0x7FF8000000000000)
%ret1 = call i1 @"std::tvalue::add"(ptr %lhs, ptr %rhs, ptr %ret)
%ret2 = call float @"std::tvalue::get_value_number"(ptr %ret)
ret float %ret2
}
define float @add_num_nil() {
entry:
%lhs = alloca %"std::tvalue::TValue", align 8
call void @"std::tvalue::new_nil"(ptr %lhs)
%rhs = alloca %"std::tvalue::TValue::Bool", align 8
call void @"std::tvalue::new_bool"(ptr %rhs, float 1.000000e+00)
%ret = alloca %"std::tvalue::TValue::Number", align 8
call void @"std::tvalue::new_num"(ptr %ret, float 0x7FF8000000000000)
%ret1 = call i1 @"std::tvalue::add"(ptr %lhs, ptr %rhs, ptr %ret)
%ret2 = call float @"std::tvalue::get_value_number"(ptr %ret)
ret float %ret2
}
attributes #0 = { nounwind }
attributes #1 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
!llvm.dbg.cu = !{!0}
!0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "luminary", isOptimized: false, runtimeVersion: 1, emissionKind: FullDebug, splitDebugInlining: false)
!1 = !DIFile(filename: "std_tvalue.ll", directory: ".")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment