Skip to content

Commit c26f02a

Browse files
committed
Loosened restraints on build_bitcast and added tests for it
1 parent d283801 commit c26f02a

File tree

2 files changed

+81
-3
lines changed

2 files changed

+81
-3
lines changed

src/builder.rs

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -333,14 +333,45 @@ impl Builder {
333333
PointerValue::new(value)
334334
}
335335

336-
pub fn build_bitcast<T: IntMathValue>(&self, int_val: T, int_type: T::BaseType, name: &str) -> T {
336+
/// Builds a bitcast instruction. A bitcast reinterprets the bits of one value
337+
/// into a value of another type which has the same bit width.
338+
///
339+
/// # Example
340+
///
341+
/// ```no_run
342+
/// use inkwell::context::Context;
343+
///
344+
/// let context = Context::create();
345+
/// let module = context.create_module("bc");
346+
/// let void_type = context.void_type();
347+
/// let f32_type = context.f32_type();
348+
/// let i32_type = context.i32_type();
349+
/// let arg_types = [i32_type.into()];
350+
/// let fn_type = void_type.fn_type(&arg_types, false);
351+
/// let fn_value = module.add_function("bc", fn_type, None);
352+
/// let builder = context.create_builder();
353+
/// let entry = fn_value.append_basic_block("entry");
354+
/// let i32_arg = fn_value.get_first_param().unwrap().into_int_value();
355+
///
356+
/// builder.position_at_end(&entry);
357+
///
358+
/// builder.build_bitcast(i32_arg, f32_type, "i32tof32");
359+
/// builder.build_return(None);
360+
///
361+
/// assert!(module.verify().is_ok());
362+
/// ```
363+
pub fn build_bitcast<T, V>(&self, val: V, ty: T, name: &str) -> BasicValueEnum
364+
where
365+
T: BasicType,
366+
V: BasicValue,
367+
{
337368
let c_string = CString::new(name).expect("Conversion to CString failed unexpectedly");
338369

339370
let value = unsafe {
340-
LLVMBuildBitCast(self.builder, int_val.as_value_ref(), int_type.as_type_ref(), c_string.as_ptr())
371+
LLVMBuildBitCast(self.builder, val.as_value_ref(), ty.as_type_ref(), c_string.as_ptr())
341372
};
342373

343-
T::new(value)
374+
BasicValueEnum::new(value)
344375
}
345376

346377
pub fn build_int_s_extend_or_bit_cast<T: IntMathValue>(&self, int_value: T, int_type: T::BaseType, name: &str) -> T {

tests/all/test_builder.rs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ extern crate inkwell;
33
use self::inkwell::{AddressSpace, OptimizationLevel};
44
use self::inkwell::context::Context;
55
use self::inkwell::builder::Builder;
6+
use self::inkwell::values::BasicValue;
67

78
// use std::ffi::CString;
89
use std::ptr::null;
@@ -652,3 +653,49 @@ fn test_insert_value() {
652653

653654
assert!(module.verify().is_ok());
654655
}
656+
657+
#[test]
658+
fn test_bitcast() {
659+
let context = Context::create();
660+
let module = context.create_module("bc");
661+
let void_type = context.void_type();
662+
let f32_type = context.f32_type();
663+
let i32_type = context.i32_type();
664+
let i64_type = context.i64_type();
665+
let i32_ptr_type = i32_type.ptr_type(AddressSpace::Generic);
666+
let i64_ptr_type = i64_type.ptr_type(AddressSpace::Generic);
667+
let i32_vec_type = i32_type.vec_type(2);
668+
let arg_types = [
669+
i32_type.into(),
670+
f32_type.into(),
671+
i32_vec_type.into(),
672+
i32_ptr_type.into(),
673+
];
674+
let fn_type = void_type.fn_type(&arg_types, false);
675+
let fn_value = module.add_function("bc", fn_type, None);
676+
let builder = context.create_builder();
677+
let entry = fn_value.append_basic_block("entry");
678+
let i32_arg = fn_value.get_first_param().unwrap().into_int_value();
679+
let f32_arg = fn_value.get_nth_param(1).unwrap().into_float_value();
680+
let i32_vec_arg = fn_value.get_nth_param(2).unwrap().into_vector_value();
681+
let i32_ptr_arg = fn_value.get_nth_param(3).unwrap().into_pointer_value();
682+
683+
builder.position_at_end(&entry);
684+
685+
let cast = builder.build_bitcast(i32_arg, f32_type, "i32tof32");
686+
687+
builder.build_bitcast(f32_arg, f32_type, "f32tof32");
688+
builder.build_bitcast(i32_vec_arg, i64_type, "2xi32toi64");
689+
builder.build_bitcast(i32_ptr_arg, i64_ptr_type, "i32*toi64*");
690+
691+
builder.build_return(None);
692+
693+
assert!(module.verify().is_ok(), module.print_to_string().to_string());
694+
695+
let first_iv = cast.as_instruction_value().unwrap();
696+
697+
builder.position_before(&first_iv);
698+
builder.build_bitcast(f32_arg, i64_type, "f32toi64");
699+
700+
assert!(module.verify().is_err());
701+
}

0 commit comments

Comments
 (0)