Files
c3c/test/test_suite/macros/userland_bitcast.c3t

345 lines
11 KiB
C

// #target: macos-x64
macro testbitcast(expr, $Type)
{
$assert($sizeof(expr) == $Type.sizeof, "Cannot bitcast between types of different size.");
$Type x = void;
var $size = (usize)($sizeof(expr));
$if ($alignof(expr) >= 8 && $alignof($Type) >= 8):
ulong *b = (ulong*)(&expr);
ulong *to = (ulong*)(&x);
for (usize i = 0; i < $size; i += 8)
{
to[i] = b[i];
}
$elif ($alignof(expr) >= 4 && $alignof($Type) >= 4):
uint* b = (uint*)(&expr);
uint* to = (uint*)(&x);
for (usize i = 0; i < $size; i += 4)
{
to[i] = b[i];
}
$elif ($alignof(expr) >= 2 && $alignof($Type) >= 2):
ushort* b = (ushort*)(&expr);
ushort* to = (ushort*)(&x);
for (usize i = 0; i < $size; i += 2)
{
to[i] = b[i];
}
$else:
char* b = (char*)(&expr);
char* to = (char*)(&x);
for (usize i = 0; i < $size; i++)
{
to[i] = b[i];
}
$endif;
return x;
}
extern fn void printf(char*, ...);
struct Foo
{
short a;
char b;
char c;
short d;
short e;
}
fn ulong testFoo(short x)
{
Foo z;
z.a = x;
return testbitcast(z, ulong);
}
fn char[4] test(float x)
{
return testbitcast(x, char[4]);
}
fn void main()
{
float f = 12.353;
int i = testbitcast(f, int);
float f2 = testbitcast(i, float);
printf("%f => %d => %f\n", f, i, f2);
double d = 12.353e267;
ulong l = testbitcast(d, ulong);
double d2 = testbitcast(d, double);
printf("%e => %llu => %e\n", d, l, d2);
}
/* #expect: userland_bitcast.ll
%Foo = type { i16, i8, i8, i16, i16 }
@.typeid.userland_bitcast.Foo = linkonce constant { i8, i64 } { i8 10, i64 5 }, align 8
@.str = private unnamed_addr constant [16 x i8] c"%f => %d => %f\0A\00", align 1
@.str.1 = private unnamed_addr constant [18 x i8] c"%e => %llu => %e\0A\00", align 1
define i64 @userland_bitcast.testFoo(i16 signext %0) #0 {
entry:
%z = alloca %Foo, align 2
%expr = alloca %Foo, align 2
%x = alloca i64, align 8
%b = alloca i16*, align 8
%to = alloca i16*, align 8
%i = alloca i64, align 8
%1 = getelementptr inbounds %Foo, %Foo* %z, i32 0, i32 0
store i16 0, i16* %1, align 2
%2 = getelementptr inbounds %Foo, %Foo* %z, i32 0, i32 1
store i8 0, i8* %2, align 2
%3 = getelementptr inbounds %Foo, %Foo* %z, i32 0, i32 2
store i8 0, i8* %3, align 1
%4 = getelementptr inbounds %Foo, %Foo* %z, i32 0, i32 3
store i16 0, i16* %4, align 2
%5 = getelementptr inbounds %Foo, %Foo* %z, i32 0, i32 4
store i16 0, i16* %5, align 2
%6 = getelementptr inbounds %Foo, %Foo* %z, i32 0, i32 0
store i16 %0, i16* %6, align 2
%7 = load %Foo, %Foo* %z, align 2
store %Foo %7, %Foo* %expr, align 2
%ptrptr = bitcast %Foo* %expr to i16*
store i16* %ptrptr, i16** %b, align 8
%ptrptr1 = bitcast i64* %x to i16*
store i16* %ptrptr1, i16** %to, align 8
store i64 0, i64* %i, align 8
br label %loop.cond
loop.cond: ; preds = %loop.body, %entry
%8 = load i64, i64* %i, align 8
%lt = icmp ult i64 %8, 8
br i1 %lt, label %loop.body, label %loop.exit
loop.body: ; preds = %loop.cond
%9 = load i16*, i16** %to, align 8
%10 = load i64, i64* %i, align 8
%ptroffset = getelementptr inbounds i16, i16* %9, i64 %10
%11 = load i16*, i16** %b, align 8
%12 = load i64, i64* %i, align 8
%ptroffset2 = getelementptr inbounds i16, i16* %11, i64 %12
%13 = load i16, i16* %ptroffset2, align 2
store i16 %13, i16* %ptroffset, align 2
%14 = load i64, i64* %i, align 8
%add = add i64 %14, 2
store i64 %add, i64* %i, align 8
br label %loop.cond
loop.exit: ; preds = %loop.cond
%15 = load i64, i64* %x, align 8
ret i64 %15
}
define i32 @userland_bitcast.test(float %0) #0 {
entry:
%expr = alloca float, align 4
%x = alloca [4 x i8], align 1
%b = alloca i8*, align 8
%to = alloca i8*, align 8
%i = alloca i64, align 8
%tempcoerce = alloca i32, align 4
store float %0, float* %expr, align 4
%ptrptr = bitcast float* %expr to i8*
store i8* %ptrptr, i8** %b, align 8
%ptrptr1 = bitcast [4 x i8]* %x to i8*
store i8* %ptrptr1, i8** %to, align 8
store i64 0, i64* %i, align 8
br label %loop.cond
loop.cond: ; preds = %loop.body, %entry
%1 = load i64, i64* %i, align 8
%lt = icmp ult i64 %1, 4
br i1 %lt, label %loop.body, label %loop.exit
loop.body: ; preds = %loop.cond
%2 = load i8*, i8** %to, align 8
%3 = load i64, i64* %i, align 8
%ptroffset = getelementptr inbounds i8, i8* %2, i64 %3
%4 = load i8*, i8** %b, align 8
%5 = load i64, i64* %i, align 8
%ptroffset2 = getelementptr inbounds i8, i8* %4, i64 %5
%6 = load i8, i8* %ptroffset2, align 1
store i8 %6, i8* %ptroffset, align 1
%7 = load i64, i64* %i, align 8
%add = add i64 %7, 1
store i64 %add, i64* %i, align 8
br label %loop.cond
loop.exit: ; preds = %loop.cond
%8 = bitcast i32* %tempcoerce to i8*
%9 = bitcast [4 x i8]* %x to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %8, i8* align 1 %9, i32 4, i1 false)
%10 = load i32, i32* %tempcoerce, align 4
ret i32 %10
}
define void @userland_bitcast.main() #0 {
entry:
%f = alloca float, align 4
%i = alloca i32, align 4
%expr = alloca float, align 4
%x = alloca i32, align 4
%b = alloca i32*, align 8
%to = alloca i32*, align 8
%i1 = alloca i64, align 8
%f2 = alloca float, align 4
%expr3 = alloca i32, align 4
%x4 = alloca float, align 4
%b5 = alloca i32*, align 8
%to6 = alloca i32*, align 8
%i8 = alloca i64, align 8
%d = alloca double, align 8
%l = alloca i64, align 8
%expr17 = alloca double, align 8
%x18 = alloca i64, align 8
%b19 = alloca i64*, align 8
%to21 = alloca i64*, align 8
%i22 = alloca i64, align 8
%d2 = alloca double, align 8
%expr30 = alloca double, align 8
%x31 = alloca double, align 8
%b32 = alloca i64*, align 8
%to34 = alloca i64*, align 8
%i36 = alloca i64, align 8
store float 0x4028B4BC60000000, float* %f, align 4
%0 = load float, float* %f, align 4
store float %0, float* %expr, align 4
%ptrptr = bitcast float* %expr to i32*
store i32* %ptrptr, i32** %b, align 8
store i32* %x, i32** %to, align 8
store i64 0, i64* %i1, align 8
br label %loop.cond
loop.cond: ; preds = %loop.body, %entry
%1 = load i64, i64* %i1, align 8
%lt = icmp ult i64 %1, 4
br i1 %lt, label %loop.body, label %loop.exit
loop.body: ; preds = %loop.cond
%2 = load i32*, i32** %to, align 8
%3 = load i64, i64* %i1, align 8
%ptroffset = getelementptr inbounds i32, i32* %2, i64 %3
%4 = load i32*, i32** %b, align 8
%5 = load i64, i64* %i1, align 8
%ptroffset2 = getelementptr inbounds i32, i32* %4, i64 %5
%6 = load i32, i32* %ptroffset2, align 4
store i32 %6, i32* %ptroffset, align 4
%7 = load i64, i64* %i1, align 8
%add = add i64 %7, 4
store i64 %add, i64* %i1, align 8
br label %loop.cond
loop.exit: ; preds = %loop.cond
%8 = load i32, i32* %x, align 4
store i32 %8, i32* %i, align 4
%9 = load i32, i32* %i, align 4
store i32 %9, i32* %expr3, align 4
store i32* %expr3, i32** %b5, align 8
%ptrptr7 = bitcast float* %x4 to i32*
store i32* %ptrptr7, i32** %to6, align 8
store i64 0, i64* %i8, align 8
br label %loop.cond9
loop.cond9: ; preds = %loop.body11, %loop.exit
%10 = load i64, i64* %i8, align 8
%lt10 = icmp ult i64 %10, 4
br i1 %lt10, label %loop.body11, label %loop.exit15
loop.body11: ; preds = %loop.cond9
%11 = load i32*, i32** %to6, align 8
%12 = load i64, i64* %i8, align 8
%ptroffset12 = getelementptr inbounds i32, i32* %11, i64 %12
%13 = load i32*, i32** %b5, align 8
%14 = load i64, i64* %i8, align 8
%ptroffset13 = getelementptr inbounds i32, i32* %13, i64 %14
%15 = load i32, i32* %ptroffset13, align 4
store i32 %15, i32* %ptroffset12, align 4
%16 = load i64, i64* %i8, align 8
%add14 = add i64 %16, 4
store i64 %add14, i64* %i8, align 8
br label %loop.cond9
loop.exit15: ; preds = %loop.cond9
%17 = load float, float* %x4, align 4
store float %17, float* %f2, align 4
%18 = load float, float* %f, align 4
%fpfpext = fpext float %18 to double
%19 = load i32, i32* %i, align 4
%20 = load float, float* %f2, align 4
%fpfpext16 = fpext float %20 to double
call void (i8*, ...) @printf(i8* getelementptr inbounds ([16 x i8], [16 x i8]* @.str, i32 0, i32 0), double %fpfpext, i32 %19, double %fpfpext16)
store double 1.235300e+268, double* %d, align 8
%21 = load double, double* %d, align 8
store double %21, double* %expr17, align 8
%ptrptr20 = bitcast double* %expr17 to i64*
store i64* %ptrptr20, i64** %b19, align 8
store i64* %x18, i64** %to21, align 8
store i64 0, i64* %i22, align 8
br label %loop.cond23
loop.cond23: ; preds = %loop.body25, %loop.exit15
%22 = load i64, i64* %i22, align 8
%lt24 = icmp ult i64 %22, 8
br i1 %lt24, label %loop.body25, label %loop.exit29
loop.body25: ; preds = %loop.cond23
%23 = load i64*, i64** %to21, align 8
%24 = load i64, i64* %i22, align 8
%ptroffset26 = getelementptr inbounds i64, i64* %23, i64 %24
%25 = load i64*, i64** %b19, align 8
%26 = load i64, i64* %i22, align 8
%ptroffset27 = getelementptr inbounds i64, i64* %25, i64 %26
%27 = load i64, i64* %ptroffset27, align 8
store i64 %27, i64* %ptroffset26, align 8
%28 = load i64, i64* %i22, align 8
%add28 = add i64 %28, 8
store i64 %add28, i64* %i22, align 8
br label %loop.cond23
loop.exit29: ; preds = %loop.cond23
%29 = load i64, i64* %x18, align 8
store i64 %29, i64* %l, align 8
%30 = load double, double* %d, align 8
store double %30, double* %expr30, align 8
%ptrptr33 = bitcast double* %expr30 to i64*
store i64* %ptrptr33, i64** %b32, align 8
%ptrptr35 = bitcast double* %x31 to i64*
store i64* %ptrptr35, i64** %to34, align 8
store i64 0, i64* %i36, align 8
br label %loop.cond37
loop.cond37: ; preds = %loop.body39, %loop.exit29
%31 = load i64, i64* %i36, align 8
%lt38 = icmp ult i64 %31, 8
br i1 %lt38, label %loop.body39, label %loop.exit43
loop.body39: ; preds = %loop.cond37
%32 = load i64*, i64** %to34, align 8
%33 = load i64, i64* %i36, align 8
%ptroffset40 = getelementptr inbounds i64, i64* %32, i64 %33
%34 = load i64*, i64** %b32, align 8
%35 = load i64, i64* %i36, align 8
%ptroffset41 = getelementptr inbounds i64, i64* %34, i64 %35
%36 = load i64, i64* %ptroffset41, align 8
store i64 %36, i64* %ptroffset40, align 8
%37 = load i64, i64* %i36, align 8
%add42 = add i64 %37, 8
store i64 %add42, i64* %i36, align 8
br label %loop.cond37
loop.exit43: ; preds = %loop.cond37
%38 = load double, double* %x31, align 8
store double %38, double* %d2, align 8
%39 = load double, double* %d, align 8
%40 = load i64, i64* %l, align 8
%41 = load double, double* %d2, align 8
call void (i8*, ...) @printf(i8* getelementptr inbounds ([18 x i8], [18 x i8]* @.str.1, i32 0, i32 0), double %39, i64 %40, double %41)
ret void
}