mirror of
https://github.com/LLVMParty/llvm-nanobind
synced 2026-06-21 13:43:38 +00:00
199 lines
7.0 KiB
C++
199 lines
7.0 KiB
C++
/**
|
|
* Test: test_builder_casts
|
|
* Tests LLVM Builder cast operations
|
|
*
|
|
* LLVM-C APIs covered:
|
|
* - LLVMBuildTrunc(), LLVMBuildZExt(), LLVMBuildSExt()
|
|
* - LLVMBuildFPToUI(), LLVMBuildFPToSI()
|
|
* - LLVMBuildUIToFP(), LLVMBuildSIToFP()
|
|
* - LLVMBuildFPTrunc(), LLVMBuildFPExt()
|
|
* - LLVMBuildPtrToInt(), LLVMBuildIntToPtr()
|
|
* - LLVMBuildBitCast()
|
|
* - LLVMBuildIntCast2()
|
|
*/
|
|
|
|
#include <cstdio>
|
|
#include <llvm-c/Analysis.h>
|
|
#include <llvm-c/Core.h>
|
|
|
|
int main() {
|
|
LLVMContextRef ctx = LLVMContextCreate();
|
|
LLVMModuleRef mod =
|
|
LLVMModuleCreateWithNameInContext("test_builder_casts", ctx);
|
|
|
|
LLVMTypeRef i8 = LLVMInt8TypeInContext(ctx);
|
|
LLVMTypeRef i16 = LLVMInt16TypeInContext(ctx);
|
|
LLVMTypeRef i32 = LLVMInt32TypeInContext(ctx);
|
|
LLVMTypeRef i64 = LLVMInt64TypeInContext(ctx);
|
|
LLVMTypeRef f32 = LLVMFloatTypeInContext(ctx);
|
|
LLVMTypeRef f64 = LLVMDoubleTypeInContext(ctx);
|
|
LLVMTypeRef ptr = LLVMPointerTypeInContext(ctx, 0);
|
|
LLVMTypeRef void_ty = LLVMVoidTypeInContext(ctx);
|
|
|
|
LLVMBuilderRef builder = LLVMCreateBuilderInContext(ctx);
|
|
|
|
// ==========================================
|
|
// Function 1: Integer casts
|
|
// ==========================================
|
|
LLVMTypeRef int_cast_params[] = {i64};
|
|
LLVMTypeRef int_cast_ty = LLVMFunctionType(i8, int_cast_params, 1, 0);
|
|
LLVMValueRef int_cast_func =
|
|
LLVMAddFunction(mod, "integer_casts", int_cast_ty);
|
|
LLVMValueRef i64_val = LLVMGetParam(int_cast_func, 0);
|
|
LLVMSetValueName2(i64_val, "val", 3);
|
|
|
|
LLVMBasicBlockRef int_entry =
|
|
LLVMAppendBasicBlockInContext(ctx, int_cast_func, "entry");
|
|
LLVMPositionBuilderAtEnd(builder, int_entry);
|
|
|
|
// Truncate i64 -> i32 -> i16 -> i8
|
|
LLVMValueRef trunc_32 = LLVMBuildTrunc(builder, i64_val, i32, "trunc_32");
|
|
LLVMValueRef trunc_16 = LLVMBuildTrunc(builder, trunc_32, i16, "trunc_16");
|
|
LLVMValueRef trunc_8 = LLVMBuildTrunc(builder, trunc_16, i8, "trunc_8");
|
|
|
|
// Zero extend i8 -> i16 -> i32 -> i64
|
|
LLVMValueRef zext_16 = LLVMBuildZExt(builder, trunc_8, i16, "zext_16");
|
|
LLVMValueRef zext_32 = LLVMBuildZExt(builder, zext_16, i32, "zext_32");
|
|
LLVMValueRef zext_64 = LLVMBuildZExt(builder, zext_32, i64, "zext_64");
|
|
|
|
// Sign extend i8 -> i16 -> i32 -> i64
|
|
LLVMValueRef sext_16 = LLVMBuildSExt(builder, trunc_8, i16, "sext_16");
|
|
LLVMValueRef sext_32 = LLVMBuildSExt(builder, sext_16, i32, "sext_32");
|
|
LLVMValueRef sext_64 = LLVMBuildSExt(builder, sext_32, i64, "sext_64");
|
|
|
|
// IntCast2 (auto-selects trunc/zext/sext)
|
|
LLVMValueRef intcast_unsigned =
|
|
LLVMBuildIntCast2(builder, i64_val, i32, 0, "intcast_unsigned");
|
|
LLVMValueRef intcast_signed =
|
|
LLVMBuildIntCast2(builder, trunc_8, i32, 1, "intcast_signed");
|
|
|
|
LLVMBuildRet(builder, trunc_8);
|
|
|
|
// ==========================================
|
|
// Function 2: Float casts
|
|
// ==========================================
|
|
LLVMTypeRef fp_cast_params[] = {f64};
|
|
LLVMTypeRef fp_cast_ty = LLVMFunctionType(f32, fp_cast_params, 1, 0);
|
|
LLVMValueRef fp_cast_func = LLVMAddFunction(mod, "float_casts", fp_cast_ty);
|
|
LLVMValueRef f64_val = LLVMGetParam(fp_cast_func, 0);
|
|
LLVMSetValueName2(f64_val, "val", 3);
|
|
|
|
LLVMBasicBlockRef fp_entry =
|
|
LLVMAppendBasicBlockInContext(ctx, fp_cast_func, "entry");
|
|
LLVMPositionBuilderAtEnd(builder, fp_entry);
|
|
|
|
// FP truncate f64 -> f32
|
|
LLVMValueRef fptrunc = LLVMBuildFPTrunc(builder, f64_val, f32, "fptrunc");
|
|
|
|
// FP extend f32 -> f64
|
|
LLVMValueRef fpext = LLVMBuildFPExt(builder, fptrunc, f64, "fpext");
|
|
|
|
LLVMBuildRet(builder, fptrunc);
|
|
|
|
// ==========================================
|
|
// Function 3: Int <-> Float casts
|
|
// ==========================================
|
|
LLVMTypeRef mixed_params[] = {i32, f64};
|
|
LLVMTypeRef mixed_ty = LLVMFunctionType(void_ty, mixed_params, 2, 0);
|
|
LLVMValueRef mixed_func = LLVMAddFunction(mod, "int_float_casts", mixed_ty);
|
|
LLVMValueRef int_param = LLVMGetParam(mixed_func, 0);
|
|
LLVMValueRef fp_param = LLVMGetParam(mixed_func, 1);
|
|
LLVMSetValueName2(int_param, "i", 1);
|
|
LLVMSetValueName2(fp_param, "f", 1);
|
|
|
|
LLVMBasicBlockRef mixed_entry =
|
|
LLVMAppendBasicBlockInContext(ctx, mixed_func, "entry");
|
|
LLVMPositionBuilderAtEnd(builder, mixed_entry);
|
|
|
|
// Int -> Float
|
|
LLVMValueRef uitofp = LLVMBuildUIToFP(builder, int_param, f64, "uitofp");
|
|
LLVMValueRef sitofp = LLVMBuildSIToFP(builder, int_param, f64, "sitofp");
|
|
|
|
// Float -> Int
|
|
LLVMValueRef fptoui = LLVMBuildFPToUI(builder, fp_param, i32, "fptoui");
|
|
LLVMValueRef fptosi = LLVMBuildFPToSI(builder, fp_param, i32, "fptosi");
|
|
|
|
LLVMBuildRetVoid(builder);
|
|
|
|
// ==========================================
|
|
// Function 4: Pointer casts
|
|
// ==========================================
|
|
LLVMTypeRef ptr_params[] = {ptr, i64};
|
|
LLVMTypeRef ptr_ty = LLVMFunctionType(void_ty, ptr_params, 2, 0);
|
|
LLVMValueRef ptr_func = LLVMAddFunction(mod, "pointer_casts", ptr_ty);
|
|
LLVMValueRef ptr_param = LLVMGetParam(ptr_func, 0);
|
|
LLVMValueRef int_for_ptr = LLVMGetParam(ptr_func, 1);
|
|
LLVMSetValueName2(ptr_param, "p", 1);
|
|
LLVMSetValueName2(int_for_ptr, "addr", 4);
|
|
|
|
LLVMBasicBlockRef ptr_entry =
|
|
LLVMAppendBasicBlockInContext(ctx, ptr_func, "entry");
|
|
LLVMPositionBuilderAtEnd(builder, ptr_entry);
|
|
|
|
// Pointer -> Int
|
|
LLVMValueRef ptrtoint =
|
|
LLVMBuildPtrToInt(builder, ptr_param, i64, "ptrtoint");
|
|
|
|
// Int -> Pointer
|
|
LLVMValueRef inttoptr =
|
|
LLVMBuildIntToPtr(builder, int_for_ptr, ptr, "inttoptr");
|
|
|
|
LLVMBuildRetVoid(builder);
|
|
|
|
// ==========================================
|
|
// Function 5: Bitcast
|
|
// ==========================================
|
|
LLVMTypeRef vec_i32 = LLVMVectorType(i32, 4);
|
|
LLVMTypeRef vec_f32 = LLVMVectorType(f32, 4);
|
|
|
|
LLVMTypeRef bitcast_params[] = {vec_i32};
|
|
LLVMTypeRef bitcast_ty = LLVMFunctionType(vec_f32, bitcast_params, 1, 0);
|
|
LLVMValueRef bitcast_func =
|
|
LLVMAddFunction(mod, "bitcast_example", bitcast_ty);
|
|
LLVMValueRef vec_param = LLVMGetParam(bitcast_func, 0);
|
|
LLVMSetValueName2(vec_param, "v", 1);
|
|
|
|
LLVMBasicBlockRef bitcast_entry =
|
|
LLVMAppendBasicBlockInContext(ctx, bitcast_func, "entry");
|
|
LLVMPositionBuilderAtEnd(builder, bitcast_entry);
|
|
|
|
LLVMValueRef bitcast =
|
|
LLVMBuildBitCast(builder, vec_param, vec_f32, "bitcast");
|
|
LLVMBuildRet(builder, bitcast);
|
|
|
|
LLVMDisposeBuilder(builder);
|
|
|
|
// Verify module
|
|
char *error = nullptr;
|
|
if (LLVMVerifyModule(mod, LLVMReturnStatusAction, &error)) {
|
|
fprintf(stderr, "; Verification failed: %s\n", error);
|
|
LLVMDisposeMessage(error);
|
|
LLVMDisposeModule(mod);
|
|
LLVMContextDispose(ctx);
|
|
return 1;
|
|
}
|
|
LLVMDisposeMessage(error);
|
|
|
|
// Print diagnostic comments
|
|
printf("; Test: test_builder_casts\n");
|
|
printf(";\n");
|
|
printf("; Cast operations demonstrated:\n");
|
|
printf("; Integer: trunc, zext, sext, intcast2\n");
|
|
printf("; Float: fptrunc, fpext\n");
|
|
printf("; Int<->Float: uitofp, sitofp, fptoui, fptosi\n");
|
|
printf("; Pointer: ptrtoint, inttoptr\n");
|
|
printf("; Reinterpret: bitcast\n");
|
|
printf("\n");
|
|
|
|
// Print module IR
|
|
char *ir = LLVMPrintModuleToString(mod);
|
|
printf("%s", ir);
|
|
LLVMDisposeMessage(ir);
|
|
|
|
// Cleanup
|
|
LLVMDisposeModule(mod);
|
|
LLVMContextDispose(ctx);
|
|
|
|
return 0;
|
|
}
|