Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Int128: fix how LLVM::Type.const_int emit 128 literals #7135

Merged
merged 1 commit into from Dec 2, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
16 changes: 16 additions & 0 deletions spec/std/llvm/type_spec.cr
@@ -0,0 +1,16 @@
require "spec"
require "llvm"

describe LLVM::Type do
describe ".const_int" do
it "support Int64" do
ctx = LLVM::Context.new
ctx.int(64).const_int(Int64::MAX).to_s.should eq("i64 9223372036854775807")
end

it "support Int128" do
ctx = LLVM::Context.new
ctx.int(128).const_int(Int128::MAX).to_s.should eq("i128 170141183460469231731687303715884105727")
end
end
end
1 change: 1 addition & 0 deletions src/llvm/lib_llvm.cr
Expand Up @@ -137,6 +137,7 @@ lib LibLLVM
fun build_zext = LLVMBuildZExt(builder : BuilderRef, val : ValueRef, dest_ty : TypeRef, name : UInt8*) : ValueRef
fun const_array = LLVMConstArray(element_type : TypeRef, constant_vals : ValueRef*, length : UInt32) : ValueRef
fun const_int = LLVMConstInt(int_type : TypeRef, value : UInt64, sign_extend : Int32) : ValueRef
fun const_int_of_arbitrary_precision = LLVMConstIntOfArbitraryPrecision(int_type : TypeRef, num_words : UInt32, words : UInt64*) : ValueRef
fun const_null = LLVMConstNull(ty : TypeRef) : ValueRef
fun const_pointer_null = LLVMConstPointerNull(ty : TypeRef) : ValueRef
fun const_real = LLVMConstReal(real_ty : TypeRef, n : Float64) : ValueRef
Expand Down
7 changes: 6 additions & 1 deletion src/llvm/type.cr
Expand Up @@ -126,7 +126,12 @@ struct LLVM::Type
end

def const_int(value) : Value
Value.new LibLLVM.const_int(self, value, 0)
if !value.is_a?(Int128) && !value.is_a?(UInt128) && int_width != 128
Value.new LibLLVM.const_int(self, value, 0)
else
encoded_value = UInt64[value & UInt64::MAX, (value >> 64) & UInt64::MAX]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But this allocates memory. Why not use static_array?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAIK the reference is kept in llvm side. I couldn't find where the pointer was used to duplicate the data so I assume a reference was used. I could be wrong the documentation didn't said much.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it's kept in LLVM side then we must keep a reference on our side, otherwise the GC will collect it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Value.new LibLLVM.const_int_of_arbitrary_precision(self, encoded_value.size, encoded_value)
end
end

def const_float(value : Float32) : Value
Expand Down