Skip to content

Commit

Permalink
Loosened restraints on build_bitcast and added tests for it
Browse files Browse the repository at this point in the history
  • Loading branch information
TheDan64 committed Mar 10, 2019
1 parent d283801 commit c26f02a
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 3 deletions.
37 changes: 34 additions & 3 deletions src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -333,14 +333,45 @@ impl Builder {
PointerValue::new(value)
}

pub fn build_bitcast<T: IntMathValue>(&self, int_val: T, int_type: T::BaseType, name: &str) -> T {
/// Builds a bitcast instruction. A bitcast reinterprets the bits of one value
/// into a value of another type which has the same bit width.
///
/// # Example
///
/// ```no_run
/// use inkwell::context::Context;
///
/// let context = Context::create();
/// let module = context.create_module("bc");
/// let void_type = context.void_type();
/// let f32_type = context.f32_type();
/// let i32_type = context.i32_type();
/// let arg_types = [i32_type.into()];
/// let fn_type = void_type.fn_type(&arg_types, false);
/// let fn_value = module.add_function("bc", fn_type, None);
/// let builder = context.create_builder();
/// let entry = fn_value.append_basic_block("entry");
/// let i32_arg = fn_value.get_first_param().unwrap().into_int_value();
///
/// builder.position_at_end(&entry);
///
/// builder.build_bitcast(i32_arg, f32_type, "i32tof32");
/// builder.build_return(None);
///
/// assert!(module.verify().is_ok());
/// ```
pub fn build_bitcast<T, V>(&self, val: V, ty: T, name: &str) -> BasicValueEnum
where
T: BasicType,
V: BasicValue,
{
let c_string = CString::new(name).expect("Conversion to CString failed unexpectedly");

let value = unsafe {
LLVMBuildBitCast(self.builder, int_val.as_value_ref(), int_type.as_type_ref(), c_string.as_ptr())
LLVMBuildBitCast(self.builder, val.as_value_ref(), ty.as_type_ref(), c_string.as_ptr())
};

T::new(value)
BasicValueEnum::new(value)
}

pub fn build_int_s_extend_or_bit_cast<T: IntMathValue>(&self, int_value: T, int_type: T::BaseType, name: &str) -> T {
Expand Down
47 changes: 47 additions & 0 deletions tests/all/test_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ extern crate inkwell;
use self::inkwell::{AddressSpace, OptimizationLevel};
use self::inkwell::context::Context;
use self::inkwell::builder::Builder;
use self::inkwell::values::BasicValue;

// use std::ffi::CString;
use std::ptr::null;
Expand Down Expand Up @@ -652,3 +653,49 @@ fn test_insert_value() {

assert!(module.verify().is_ok());
}

#[test]
fn test_bitcast() {
let context = Context::create();
let module = context.create_module("bc");
let void_type = context.void_type();
let f32_type = context.f32_type();
let i32_type = context.i32_type();
let i64_type = context.i64_type();
let i32_ptr_type = i32_type.ptr_type(AddressSpace::Generic);
let i64_ptr_type = i64_type.ptr_type(AddressSpace::Generic);
let i32_vec_type = i32_type.vec_type(2);
let arg_types = [
i32_type.into(),
f32_type.into(),
i32_vec_type.into(),
i32_ptr_type.into(),
];
let fn_type = void_type.fn_type(&arg_types, false);
let fn_value = module.add_function("bc", fn_type, None);
let builder = context.create_builder();
let entry = fn_value.append_basic_block("entry");
let i32_arg = fn_value.get_first_param().unwrap().into_int_value();
let f32_arg = fn_value.get_nth_param(1).unwrap().into_float_value();
let i32_vec_arg = fn_value.get_nth_param(2).unwrap().into_vector_value();
let i32_ptr_arg = fn_value.get_nth_param(3).unwrap().into_pointer_value();

builder.position_at_end(&entry);

let cast = builder.build_bitcast(i32_arg, f32_type, "i32tof32");

builder.build_bitcast(f32_arg, f32_type, "f32tof32");
builder.build_bitcast(i32_vec_arg, i64_type, "2xi32toi64");
builder.build_bitcast(i32_ptr_arg, i64_ptr_type, "i32*toi64*");

builder.build_return(None);

assert!(module.verify().is_ok(), module.print_to_string().to_string());

let first_iv = cast.as_instruction_value().unwrap();

builder.position_before(&first_iv);
builder.build_bitcast(f32_arg, i64_type, "f32toi64");

assert!(module.verify().is_err());
}

0 comments on commit c26f02a

Please sign in to comment.