Fixes to bitstruct.

This commit is contained in:
Christoffer Lerno
2022-08-14 01:06:00 +02:00
parent b72718ba2a
commit 63d9853bd3
10 changed files with 854 additions and 89 deletions

61
lib/std/core/bitorder.c3 Normal file
View File

@@ -0,0 +1,61 @@
module std::core::bitorder;
bitstruct ShortBE : short @bigendian
{
short val : 0..15;
}
bitstruct UShortBE : ushort @bigendian
{
ushort val : 0..15;
}
bitstruct IntBE : int @bigendian
{
int val : 0..31;
}
bitstruct UIntBE : int @bigendian
{
uint val : 0..31;
}
bitstruct LongBE : long @bigendian
{
long val : 0..63;
}
bitstruct ULongBE : ulong @bigendian
{
ulong val : 0..63;
}
bitstruct ShortLE : short @littleendian
{
short val : 0..15;
}
bitstruct UShortLE : ushort @littleendian
{
ushort val : 0..15;
}
bitstruct IntLE : int @littleendian
{
int val : 0..31;
}
bitstruct UIntLE : int @littleendian
{
uint val : 0..31;
}
bitstruct LongLE : long @littleendian
{
long val : 0..63;
}
bitstruct ULongLE : ulong @littleendian
{
ulong val : 0..63;
}

View File

@@ -18,6 +18,7 @@ static void llvm_emit_initialize_designated(GenContext *c, BEValue *ref, AlignSi
static inline void llvm_emit_const_initialize_reference(GenContext *c, BEValue *ref, Expr *expr);
static inline void llvm_emit_initialize_reference(GenContext *c, BEValue *ref, Expr *expr);
static void llvm_convert_vector_comparison(GenContext *c, BEValue *be_value, LLVMValueRef val, Type *vector_type);
static bool bitstruct_requires_bitswap(Decl *decl);
BEValue llvm_emit_assign_expr(GenContext *c, BEValue *ref, Expr *expr, LLVMValueRef failable)
{
@@ -207,7 +208,7 @@ LLVMValueRef llvm_mask_low_bits(GenContext *c, LLVMValueRef value, unsigned low_
BitSize type_bits = llvm_bitsize(c, type);
if (type_bits <= low_bits) return value;
LLVMValueRef mask = llvm_emit_lshr_fixed(c, llvm_get_ones_raw(type), type_bits - low_bits);
return LLVMBuildAnd(c->builder, mask, value, "");
return llvm_emit_and_raw(c, mask, value);
}
LLVMTypeRef llvm_const_padding_type(GenContext *c, AlignSize size)
@@ -743,9 +744,7 @@ static inline void llvm_extract_bitvalue_from_array(GenContext *c, BEValue *be_v
llvm_extract_bool_bit_from_array(c, be_value, member);
return;
}
bool big_endian = platform_target.big_endian;
if (parent_decl->bitstruct.big_endian) big_endian = true;
if (parent_decl->bitstruct.little_endian) big_endian = false;
bool bswap = bitstruct_requires_bitswap(parent_decl);
unsigned start = member->var.start_bit;
unsigned end = member->var.end_bit;
LLVMValueRef array_ptr = be_value->value;
@@ -780,9 +779,9 @@ static inline void llvm_extract_bitvalue_from_array(GenContext *c, BEValue *be_v
continue;
}
if (!llvm_is_const_null(element)) res = LLVMBuildOr(c->builder, element, res, "");
res = llvm_emit_or_raw(c, element, res);
}
if (big_endian)
if (bswap)
{
res = llvm_bswap_non_integral(c, res, end - start + 1);
}
@@ -812,12 +811,8 @@ static inline void llvm_extract_bitvalue(GenContext *c, BEValue *be_value, Expr
llvm_extract_bitvalue_from_array(c, be_value, member, parent_decl);
return;
}
bool bswap = false;
if (parent_decl->bitstruct.big_endian && !platform_target.big_endian) bswap = true;
if (parent_decl->bitstruct.little_endian && platform_target.big_endian) bswap = true;
LLVMValueRef value = llvm_load_value_store(c, be_value);
if (bswap) value = llvm_emit_bswap(c, value);
LLVMTypeRef container_type = LLVMTypeOf(value);
if (bitstruct_requires_bitswap(parent_decl)) value = llvm_emit_bswap(c, value);
BitSize container_size = type_size(be_value->type);
BitSize container_bit_size = container_size * 8;
unsigned start = (unsigned)member->var.start_bit;
@@ -882,18 +877,16 @@ static inline void llvm_emit_bitassign_array(GenContext *c, BEValue *result, BEV
LLVMValueRef byte_ptr = llvm_emit_array_gep_raw(c, array_ptr, array_type, start_bit / 8, parent.alignment, &alignment);
LLVMValueRef current = llvm_load(c, c->byte_type, byte_ptr, alignment, "");
LLVMValueRef bit = llvm_emit_shl_fixed(c, LLVMConstInt(c->byte_type, 1, 0), start_bit % 8);
current = LLVMBuildAnd(c->builder, current, LLVMBuildNot(c->builder, bit, ""), "");
if (!llvm_is_const_null(value)) current = LLVMBuildOr(c->builder, current, value, "");
current = llvm_emit_and_raw(c, current, LLVMBuildNot(c->builder, bit, ""));
current = llvm_emit_or_raw(c, current, value);
llvm_store_to_ptr_raw_aligned(c, byte_ptr, current, alignment);
return;
}
bool big_endian = platform_target.big_endian;
if (parent_decl->bitstruct.big_endian) big_endian = true;
if (parent_decl->bitstruct.little_endian) big_endian = false;
bool need_bitswap = bitstruct_requires_bitswap(parent_decl);
unsigned bit_size = end_bit - start_bit + 1;
if (big_endian)
if (need_bitswap)
{
value = llvm_bswap_non_integral(c, value, bit_size);
}
@@ -924,15 +917,15 @@ static inline void llvm_emit_bitassign_array(GenContext *c, BEValue *result, BEV
// We might need to mask the top bits
if (i == end_byte && end_mod != 7)
{
res = LLVMBuildAnd(c->builder, res, llvm_const_low_bitmask(c, c->byte_type, 8, end_mod + 1), "");
mask = LLVMBuildOr(c->builder, mask, llvm_const_high_bitmask(c, c->byte_type, 8, 7 - (int)end_bit), "");
res = llvm_emit_and_raw(c, res, llvm_const_low_bitmask(c, c->byte_type, 8, end_mod + 1));
mask = llvm_emit_or_raw(c, mask, llvm_const_high_bitmask(c, c->byte_type, 8, 7 - (int)end_bit));
}
// Load the current value.
LLVMValueRef current = llvm_load(c, c->byte_type, byte_ptr, alignment, "");
// Empty the top bits.
current = LLVMBuildAnd(c->builder, current, mask, "");
current = llvm_emit_and_raw(c, current, mask);
// Use *or* with the top bits from "res":
if (!llvm_is_const_null(res)) current = LLVMBuildOr(c->builder, current, res, "");
current = llvm_emit_or_raw(c, current, res);
// And store it back.
llvm_store_to_ptr_raw_aligned(c, byte_ptr, current, alignment);
// We now shift the value by the number of bits we used.
@@ -946,13 +939,13 @@ static inline void llvm_emit_bitassign_array(GenContext *c, BEValue *result, BEV
value = llvm_zext_trunc(c, value, c->byte_type);
// Create a mask for the lower bits.
LLVMValueRef mask = llvm_const_low_bitmask(c, c->byte_type, 8, end_mod + 1);
value = LLVMBuildAnd(c->builder, value, mask, "");
value = llvm_emit_and_raw(c, value, mask);
// Load the current value.
LLVMValueRef current = llvm_load(c, c->byte_type, byte_ptr, alignment, "");
// Clear the lower bits.
current = LLVMBuildAnd(c->builder, current, LLVMBuildNot(c->builder, mask, ""), "");
current = llvm_emit_and_raw(c, current, LLVMBuildNot(c->builder, mask, ""));
// Use *or* with the bottom bits from "value":
if (!llvm_is_const_null(value)) current = LLVMBuildOr(c->builder, current, value, "");
llvm_emit_or_raw(c, current, value);
// And store it back.
llvm_store_to_ptr_raw_aligned(c, byte_ptr, current, alignment);
continue;
@@ -989,15 +982,17 @@ static inline void llvm_emit_bitassign_expr(GenContext *c, BEValue *be_value, Ex
llvm_emit_expr(c, be_value, exprptr(expr->binary_expr.right));
}
if (type_lowering(parent_expr->type)->type_kind == TYPE_ARRAY)
Type *parent_type = type_flatten_distinct(parent_expr->type);
if (type_lowering(parent_type)->type_kind == TYPE_ARRAY)
{
llvm_emit_bitassign_array(c, be_value, parent, type_flatten_distinct(parent_expr->type)->decl, member);
llvm_emit_bitassign_array(c, be_value, parent, parent_type->decl, member);
return;
}
// To start the assign, pull out the current value.
LLVMValueRef current_value = llvm_load_value_store(c, &parent);
bool bswap = bitstruct_requires_bitswap(parent_type->decl);
if (bswap) current_value = llvm_emit_bswap(c, current_value);
// Get the type.
LLVMTypeRef struct_type = LLVMTypeOf(current_value);
@@ -1021,10 +1016,11 @@ static inline void llvm_emit_bitassign_expr(GenContext *c, BEValue *be_value, Ex
// Shift to the correct location.
value = llvm_emit_shl_fixed(c, value, start_bit);
// And combine using ((current_value & ~mask) | (value & mask))
value = LLVMBuildAnd(c->builder, value, mask, "");
current_value = LLVMBuildAnd(c->builder, current_value, LLVMBuildNot(c->builder, mask, ""), "");
value = llvm_emit_and_raw(c, value, mask);
current_value = llvm_emit_and_raw(c, current_value, LLVMBuildNot(c->builder, mask, ""));
// Skip this op for LLVM14 if zero.
if (!llvm_is_const_null(value)) current_value = LLVMBuildOr(c->builder, current_value, value, "");
current_value = llvm_emit_or_raw(c, current_value, value);
if (bswap) current_value = llvm_emit_bswap(c, current_value);
llvm_store_raw(c, &parent, current_value);
}
static inline void llvm_emit_bitaccess(GenContext *c, BEValue *be_value, Expr *expr)
@@ -1693,13 +1689,18 @@ static inline void llvm_emit_initialize_reference_designated(GenContext *c, BEVa
#define MAX_AGG 16
static bool bitstruct_requires_bitswap(Decl *decl)
{
bool big_endian = platform_target.big_endian;
if (decl->bitstruct.big_endian) return !big_endian;
if (decl->bitstruct.little_endian) return big_endian;
return false;
}
LLVMValueRef llvm_emit_const_bitstruct_array(GenContext *c, ConstInitializer *initializer)
{
Decl *decl = initializer->type->decl;
Type *base_type = decl->bitstruct.base_type->type;
bool big_endian = platform_target.big_endian;
if (decl->bitstruct.big_endian) big_endian = true;
if (decl->bitstruct.little_endian) big_endian = false;
unsigned elements = base_type->array.len;
LLVMValueRef stack_data[MAX_AGG];
LLVMValueRef* slots = elements > MAX_AGG ? MALLOC(elements * sizeof(LLVMValueRef)) : stack_data;
@@ -1730,7 +1731,7 @@ LLVMValueRef llvm_emit_const_bitstruct_array(GenContext *c, ConstInitializer *in
LLVMValueRef bit = llvm_emit_shl_fixed(c, LLVMConstInt(c->byte_type, 1, 0), start_bit % 8);
unsigned byte = start_bit / 8;
LLVMValueRef current_value = slots[byte];
slots[byte] = LLVMBuildOr(c->builder, current_value, bit, "");
slots[byte] = llvm_emit_or_raw(c, current_value, bit);
continue;
}
unsigned bit_size = end_bit - start_bit + 1;
@@ -1743,7 +1744,7 @@ LLVMValueRef llvm_emit_const_bitstruct_array(GenContext *c, ConstInitializer *in
int end_byte = end_bit / 8;
ByteSize member_type_bitsize = type_size(member_type) * 8;
value = llvm_mask_low_bits(c, value, bit_size);
if (big_endian && bit_size > 8)
if (bitstruct_requires_bitswap(decl) && bit_size > 8)
{
value = llvm_bswap_non_integral(c, value, bit_size);
}
@@ -1765,7 +1766,7 @@ LLVMValueRef llvm_emit_const_bitstruct_array(GenContext *c, ConstInitializer *in
}
if (member_type_bitsize > 8) to_or = LLVMBuildTrunc(c->builder, to_or, c->byte_type, "");
LLVMValueRef current_value = slots[(unsigned)j];
slots[(unsigned)j] = LLVMBuildOr(c->builder, to_or, current_value, "");
slots[(unsigned)j] = llvm_emit_or_raw(c, to_or, current_value);
}
}
return llvm_get_array(c->byte_type, slots, elements);
@@ -1811,19 +1812,15 @@ LLVMValueRef llvm_emit_const_bitstruct(GenContext *c, ConstInitializer *initiali
if (bit_size < base_type_bitsize)
{
LLVMValueRef mask = llvm_emit_lshr_fixed(c, llvm_get_ones_raw(llvm_base_type), base_type_bitsize - bit_size);
value = LLVMBuildAnd(c->builder, mask, value, "");
value = llvm_emit_and_raw(c, mask, value);
}
if (start_bit > 0)
{
value = llvm_emit_shl_fixed(c, value, start_bit);
}
result = LLVMBuildOr(c->builder, value, result, "");
result = llvm_emit_or_raw(c, value, result);
}
if (decl->bitstruct.little_endian && platform_target.big_endian)
{
return LLVMConstBswap(result);
}
if (decl->bitstruct.big_endian && !platform_target.big_endian)
if (bitstruct_requires_bitswap(decl))
{
return LLVMConstBswap(result);
}

View File

@@ -386,6 +386,8 @@ INLINE LLVMValueRef llvm_emit_lshr(GenContext *c, LLVMValueRef value, LLVMValueR
INLINE LLVMValueRef llvm_emit_trunc(GenContext *c, LLVMValueRef value, Type *type);
INLINE LLVMValueRef llvm_emit_trunc_bool(GenContext *c, LLVMValueRef value);
INLINE LLVMValueRef llvm_emit_and(GenContext *c, BEValue *lhs, BEValue *rhs);
INLINE LLVMValueRef llvm_emit_and_raw(GenContext *c, LLVMValueRef lhs, LLVMValueRef rhs);
INLINE LLVMValueRef llvm_emit_or_raw(GenContext *c, LLVMValueRef lhs, LLVMValueRef rhs);
// -- Mem ops --
LLVMValueRef llvm_emit_memclear_size_align(GenContext *c, LLVMValueRef ptr, uint64_t size, AlignSize align);

View File

@@ -172,9 +172,23 @@ INLINE LLVMTypeRef llvm_get_ptr_type(GenContext *c, Type *type)
return llvm_get_type(c, type_get_ptr(type));
}
INLINE LLVMValueRef llvm_emit_and_raw(GenContext *c, LLVMValueRef lhs, LLVMValueRef rhs)
{
if (llvm_is_const_null(lhs)) return lhs;
if (llvm_is_const_null(rhs)) return rhs;
return LLVMBuildAnd(c->builder, lhs, rhs, "");
}
INLINE LLVMValueRef llvm_emit_or_raw(GenContext *c, LLVMValueRef lhs, LLVMValueRef rhs)
{
if (llvm_is_const_null(lhs)) return rhs;
if (llvm_is_const_null(rhs)) return lhs;
return LLVMBuildOr(c->builder, lhs, rhs, "");
}
INLINE LLVMValueRef llvm_emit_and(GenContext *c, BEValue *lhs, BEValue *rhs)
{
return LLVMBuildAnd(c->builder, lhs->value, rhs->value, "");
return llvm_emit_and_raw(c, lhs->value, rhs->value);
}
INLINE LLVMValueRef llvm_get_zero(GenContext *c, Type *type)

View File

@@ -350,7 +350,7 @@ entry:
%1 = load i8, i8* %0, align 1
%2 = and i8 %1, -8
%3 = or i8 %2, 3
store i8 %3, i8* %0, align 1
store i8 %2, i8* %0, align 1
%4 = getelementptr inbounds [3 x i8], [3 x i8]* %xx, i64 0, i64 0
%5 = load i8, i8* %4, align 1
%zext = zext i8 %5 to i32
@@ -380,7 +380,7 @@ entry:
%15 = load i8, i8* %13, align 1
%16 = and i8 %15, -8
%17 = or i8 %16, %14
store i8 %17, i8* %13, align 1
store i8 %16, i8* %13, align 1
%18 = getelementptr inbounds [3 x i8], [3 x i8]* %xx, i64 0, i64 0
%19 = load i8, i8* %18, align 1
%zext9 = zext i8 %19 to i32
@@ -424,7 +424,7 @@ entry:
%36 = load i8, i8* %34, align 1
%37 = and i8 %36, -2
%38 = or i8 %37, %35
store i8 %38, i8* %34, align 1
store i8 %37, i8* %34, align 1
%39 = getelementptr inbounds [3 x i8], [3 x i8]* %xx, i64 0, i64 0
%40 = load i8, i8* %39, align 1
%zext28 = zext i8 %40 to i32
@@ -468,7 +468,7 @@ entry:
%57 = load i8, i8* %55, align 1
%58 = and i8 %57, -2
%59 = or i8 %58, %56
store i8 %59, i8* %55, align 1
store i8 %58, i8* %55, align 1
%60 = getelementptr inbounds [3 x i8], [3 x i8]* %xx, i64 0, i64 0
%61 = load i8, i8* %60, align 1
%zext47 = zext i8 %61 to i32
@@ -512,7 +512,7 @@ entry:
%78 = load i8, i8* %76, align 1
%79 = and i8 %78, -2
%80 = or i8 %79, %77
store i8 %80, i8* %76, align 1
store i8 %79, i8* %76, align 1
%81 = getelementptr inbounds [3 x i8], [3 x i8]* %xx, i64 0, i64 0
%82 = load i8, i8* %81, align 1
%zext66 = zext i8 %82 to i32
@@ -557,7 +557,7 @@ entry:
%100 = load i8, i8* %98, align 1
%101 = and i8 %100, -2
%102 = or i8 %101, %99
store i8 %102, i8* %98, align 1
store i8 %101, i8* %98, align 1
%103 = getelementptr inbounds [3 x i8], [3 x i8]* %xx, i64 0, i64 0
%104 = load i8, i8* %103, align 1
%zext86 = zext i8 %104 to i32
@@ -602,7 +602,7 @@ entry:
%122 = load i8, i8* %120, align 1
%123 = and i8 %122, -2
%124 = or i8 %123, %121
store i8 %124, i8* %120, align 1
store i8 %123, i8* %120, align 1
%125 = getelementptr inbounds [3 x i8], [3 x i8]* %xx, i64 0, i64 0
%126 = load i8, i8* %125, align 1
%zext106 = zext i8 %126 to i32
@@ -646,7 +646,7 @@ entry:
%143 = load i8, i8* %141, align 1
%144 = and i8 %143, -2
%145 = or i8 %144, %142
store i8 %145, i8* %141, align 1
store i8 %144, i8* %141, align 1
%146 = getelementptr inbounds [3 x i8], [3 x i8]* %xx, i64 0, i64 0
%147 = load i8, i8* %146, align 1
%zext125 = zext i8 %147 to i32
@@ -690,7 +690,7 @@ entry:
%164 = load i8, i8* %162, align 1
%165 = and i8 %164, -2
%166 = or i8 %165, %163
store i8 %166, i8* %162, align 1
store i8 %165, i8* %162, align 1
%167 = getelementptr inbounds [3 x i8], [3 x i8]* %xx, i64 0, i64 0
%168 = load i8, i8* %167, align 1
%zext144 = zext i8 %168 to i32
@@ -826,7 +826,7 @@ entry:
%36 = load i8, i8* %34, align 1
%37 = and i8 %36, -4
%38 = or i8 %37, %35
store i8 %38, i8* %34, align 1
store i8 %37, i8* %34, align 1
%39 = getelementptr inbounds [3 x i8], [3 x i8]* %xx, i64 0, i64 0
%40 = load i8, i8* %39, align 1
%zext33 = zext i8 %40 to i32
@@ -871,7 +871,7 @@ entry:
%57 = load i8, i8* %55, align 1
%58 = and i8 %57, -4
%59 = or i8 %58, %56
store i8 %59, i8* %55, align 1
store i8 %58, i8* %55, align 1
%60 = getelementptr inbounds [3 x i8], [3 x i8]* %xx, i64 0, i64 0
%61 = load i8, i8* %60, align 1
%zext53 = zext i8 %61 to i32
@@ -916,7 +916,7 @@ entry:
%78 = load i8, i8* %76, align 1
%79 = and i8 %78, -4
%80 = or i8 %79, %77
store i8 %80, i8* %76, align 1
store i8 %79, i8* %76, align 1
%81 = getelementptr inbounds [3 x i8], [3 x i8]* %xx, i64 0, i64 0
%82 = load i8, i8* %81, align 1
%zext73 = zext i8 %82 to i32
@@ -962,7 +962,7 @@ entry:
%100 = load i8, i8* %98, align 1
%101 = and i8 %100, -4
%102 = or i8 %101, %99
store i8 %102, i8* %98, align 1
store i8 %101, i8* %98, align 1
%103 = getelementptr inbounds [3 x i8], [3 x i8]* %xx, i64 0, i64 0
%104 = load i8, i8* %103, align 1
%zext94 = zext i8 %104 to i32
@@ -1008,7 +1008,7 @@ entry:
%122 = load i8, i8* %120, align 1
%123 = and i8 %122, -4
%124 = or i8 %123, %121
store i8 %124, i8* %120, align 1
store i8 %123, i8* %120, align 1
%125 = getelementptr inbounds [3 x i8], [3 x i8]* %xx, i64 0, i64 0
%126 = load i8, i8* %125, align 1
%zext115 = zext i8 %126 to i32
@@ -1053,7 +1053,7 @@ entry:
%143 = load i8, i8* %141, align 1
%144 = and i8 %143, -4
%145 = or i8 %144, %142
store i8 %145, i8* %141, align 1
store i8 %144, i8* %141, align 1
%146 = getelementptr inbounds [3 x i8], [3 x i8]* %xx, i64 0, i64 0
%147 = load i8, i8* %146, align 1
%zext135 = zext i8 %147 to i32
@@ -1098,7 +1098,7 @@ entry:
%164 = load i8, i8* %162, align 1
%165 = and i8 %164, -4
%166 = or i8 %165, %163
store i8 %166, i8* %162, align 1
store i8 %165, i8* %162, align 1
%167 = getelementptr inbounds [3 x i8], [3 x i8]* %xx, i64 0, i64 0
%168 = load i8, i8* %167, align 1
%zext155 = zext i8 %168 to i32

View File

@@ -95,7 +95,7 @@ entry:
%26 = load i8, i8* %25, align 1
%27 = and i8 %26, -16
%28 = or i8 %27, 11
store i8 %28, i8* %25, align 1
store i8 %27, i8* %25, align 1
%29 = getelementptr inbounds [4 x i8], [4 x i8]* %xy, i64 0, i64 0
%30 = load i8, i8* %29, align 1
%zext12 = zext i8 %30 to i32
@@ -123,7 +123,7 @@ entry:
%44 = load i8, i8* %43, align 1
%45 = and i8 %44, -16
%46 = or i8 %45, 14
store i8 %46, i8* %43, align 1
store i8 %45, i8* %43, align 1
%47 = getelementptr inbounds [4 x i8], [4 x i8]* %xx, i64 0, i64 0
%48 = load i8, i8* %47, align 1
%zext18 = zext i8 %48 to i32

View File

@@ -0,0 +1,364 @@
// #target: macos-x64
module test;
import std::io;
bitstruct Test : int @bigendian
{
ushort a : 0..15;
ushort b : 16..31;
}
bitstruct Test2 : char[4] @bigendian
{
ushort a : 0..15;
ushort b : 16..31;
}
fn void main()
{
IntBE x;
x.val = 123;
io::printf("BE 123 => %d (%d)\n", (int)x, x.val);
Test abc = { .a = 0x1234, .b = 0x5678 };
Test2 abc2 = { .a = 0x1234, .b = 0x5678 };
char[4]* z = (char[4]*)&abc;
char[4]* z2 = (char[4]*)&abc2;
foreach (d : z2) io::printf(" %x", d);
io::println("");
foreach (d : z) io::printf(" %x", d);
io::println("");
io::printfln("abc.a = %x", abc.a);
abc.a = 0x1234;
abc.b = 0x5678;
io::printfln("->abc.a = %x", abc.a);
foreach (d : z) io::printf(" %x", d);
io::println("");
IntLE y;
y.val = 123;
io::printf("LE 123 => %d (%d)\n", (int)y, y.val);
}
/* #expect: test.ll
%0 = load i32, i32* %x, align 4
%1 = call i32 @llvm.bswap.i32(i32 %0)
store i32 2063597568, i32* %x, align 4
store %"char[]" { i8* getelementptr inbounds ([19 x i8], [19 x i8]* @.str, i32 0, i32 0), i64 18 }, %"char[]"* %taddr, align 8
%2 = bitcast %"char[]"* %taddr to { i8*, i64 }*
%3 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %2, i32 0, i32 0
%lo = load i8*, i8** %3, align 8
%4 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %2, i32 0, i32 1
%hi = load i64, i64* %4, align 8
%5 = bitcast i32* %x to i8*
%6 = insertvalue %variant undef, i8* %5, 0
%7 = insertvalue %variant %6, i64 ptrtoint (%.introspect* @"ct$int" to i64), 1
%8 = getelementptr inbounds [2 x %variant], [2 x %variant]* %varargslots, i64 0, i64 0
store %variant %7, %variant* %8, align 16
%9 = load i32, i32* %x, align 4
%10 = call i32 @llvm.bswap.i32(i32 %9)
store i32 %10, i32* %taddr1, align 4
%11 = bitcast i32* %taddr1 to i8*
%12 = insertvalue %variant undef, i8* %11, 0
%13 = insertvalue %variant %12, i64 ptrtoint (%.introspect* @"ct$int" to i64), 1
%14 = getelementptr inbounds [2 x %variant], [2 x %variant]* %varargslots, i64 0, i64 1
store %variant %13, %variant* %14, align 16
%15 = getelementptr inbounds %"variant[]", %"variant[]"* %vararg, i32 0, i32 1
store i64 2, i64* %15, align 8
%16 = getelementptr inbounds %"variant[]", %"variant[]"* %vararg, i32 0, i32 0
%17 = bitcast [2 x %variant]* %varargslots to %variant*
store %variant* %17, %variant** %16, align 8
%18 = bitcast %"variant[]"* %vararg to { i8*, i64 }*
%19 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %18, i32 0, i32 0
%lo2 = load i8*, i8** %19, align 8
%20 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %18, i32 0, i32 1
%hi3 = load i64, i64* %20, align 8
%21 = call i64 @std_io_printf(i64* %retparam, i8* %lo, i64 %hi, i8* %lo2, i64 %hi3)
%not_err = icmp eq i64 %21, 0
br i1 %not_err, label %after_check, label %voiderr
after_check: ; preds = %entry
br label %voiderr
voiderr: ; preds = %after_check, %entry
store i32 873625686, i32* %abc, align 4
store [4 x i8] c"\124Vx", [4 x i8]* %abc2, align 1
%ptrptr = bitcast i32* %abc to [4 x i8]*
store [4 x i8]* %ptrptr, [4 x i8]** %z, align 8
store [4 x i8]* %abc2, [4 x i8]** %z2, align 8
%22 = load [4 x i8]*, [4 x i8]** %z2, align 8
store [4 x i8]* %22, [4 x i8]** %.anon, align 8
store i64 0, i64* %.anon4, align 8
br label %loop.cond
loop.cond: ; preds = %voiderr15, %voiderr
%23 = load i64, i64* %.anon4, align 8
%gt = icmp ugt i64 4, %23
br i1 %gt, label %loop.body, label %loop.exit
loop.body: ; preds = %loop.cond
%24 = load [4 x i8]*, [4 x i8]** %.anon, align 8
%25 = load i64, i64* %.anon4, align 8
%26 = getelementptr inbounds [4 x i8], [4 x i8]* %24, i64 0, i64 %25
%27 = load i8, i8* %26, align 1
store i8 %27, i8* %d, align 1
store %"char[]" { i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.1, i32 0, i32 0), i64 3 }, %"char[]"* %taddr6, align 8
%28 = bitcast %"char[]"* %taddr6 to { i8*, i64 }*
%29 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %28, i32 0, i32 0
%lo7 = load i8*, i8** %29, align 8
%30 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %28, i32 0, i32 1
%hi8 = load i64, i64* %30, align 8
%31 = insertvalue %variant undef, i8* %d, 0
%32 = insertvalue %variant %31, i64 ptrtoint (%.introspect* @"ct$char" to i64), 1
%33 = getelementptr inbounds [1 x %variant], [1 x %variant]* %varargslots10, i64 0, i64 0
store %variant %32, %variant* %33, align 16
%34 = getelementptr inbounds %"variant[]", %"variant[]"* %vararg9, i32 0, i32 1
store i64 1, i64* %34, align 8
%35 = getelementptr inbounds %"variant[]", %"variant[]"* %vararg9, i32 0, i32 0
%36 = bitcast [1 x %variant]* %varargslots10 to %variant*
store %variant* %36, %variant** %35, align 8
%37 = bitcast %"variant[]"* %vararg9 to { i8*, i64 }*
%38 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %37, i32 0, i32 0
%lo11 = load i8*, i8** %38, align 8
%39 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %37, i32 0, i32 1
%hi12 = load i64, i64* %39, align 8
%40 = call i64 @std_io_printf(i64* %retparam5, i8* %lo7, i64 %hi8, i8* %lo11, i64 %hi12)
%not_err13 = icmp eq i64 %40, 0
br i1 %not_err13, label %after_check14, label %voiderr15
after_check14: ; preds = %loop.body
br label %voiderr15
voiderr15: ; preds = %after_check14, %loop.body
%41 = load i64, i64* %.anon4, align 8
%add = add i64 %41, 1
store i64 %add, i64* %.anon4, align 8
br label %loop.cond
loop.exit: ; preds = %loop.cond
%42 = call i32 @std_io_println(i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str.2, i32 0, i32 0)) #2
%43 = load [4 x i8]*, [4 x i8]** %z, align 8
store [4 x i8]* %43, [4 x i8]** %.anon16, align 8
store i64 0, i64* %.anon17, align 8
br label %loop.cond18
loop.cond18: ; preds = %voiderr32, %loop.exit
%44 = load i64, i64* %.anon17, align 8
%gt19 = icmp ugt i64 4, %44
br i1 %gt19, label %loop.body20, label %loop.exit34
loop.body20: ; preds = %loop.cond18
%45 = load [4 x i8]*, [4 x i8]** %.anon16, align 8
%46 = load i64, i64* %.anon17, align 8
%47 = getelementptr inbounds [4 x i8], [4 x i8]* %45, i64 0, i64 %46
%48 = load i8, i8* %47, align 1
store i8 %48, i8* %d21, align 1
store %"char[]" { i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.3, i32 0, i32 0), i64 3 }, %"char[]"* %taddr23, align 8
%49 = bitcast %"char[]"* %taddr23 to { i8*, i64 }*
%50 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %49, i32 0, i32 0
%lo24 = load i8*, i8** %50, align 8
%51 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %49, i32 0, i32 1
%hi25 = load i64, i64* %51, align 8
%52 = insertvalue %variant undef, i8* %d21, 0
%53 = insertvalue %variant %52, i64 ptrtoint (%.introspect* @"ct$char" to i64), 1
%54 = getelementptr inbounds [1 x %variant], [1 x %variant]* %varargslots27, i64 0, i64 0
store %variant %53, %variant* %54, align 16
%55 = getelementptr inbounds %"variant[]", %"variant[]"* %vararg26, i32 0, i32 1
store i64 1, i64* %55, align 8
%56 = getelementptr inbounds %"variant[]", %"variant[]"* %vararg26, i32 0, i32 0
%57 = bitcast [1 x %variant]* %varargslots27 to %variant*
store %variant* %57, %variant** %56, align 8
%58 = bitcast %"variant[]"* %vararg26 to { i8*, i64 }*
%59 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %58, i32 0, i32 0
%lo28 = load i8*, i8** %59, align 8
%60 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %58, i32 0, i32 1
%hi29 = load i64, i64* %60, align 8
%61 = call i64 @std_io_printf(i64* %retparam22, i8* %lo24, i64 %hi25, i8* %lo28, i64 %hi29)
%not_err30 = icmp eq i64 %61, 0
br i1 %not_err30, label %after_check31, label %voiderr32
after_check31: ; preds = %loop.body20
br label %voiderr32
voiderr32: ; preds = %after_check31, %loop.body20
%62 = load i64, i64* %.anon17, align 8
%add33 = add i64 %62, 1
store i64 %add33, i64* %.anon17, align 8
br label %loop.cond18
loop.exit34: ; preds = %loop.cond18
%63 = call i32 @std_io_println(i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str.4, i32 0, i32 0)) #2
store %"char[]" { i8* getelementptr inbounds ([11 x i8], [11 x i8]* @.str.5, i32 0, i32 0), i64 10 }, %"char[]"* %taddr36, align 8
%64 = bitcast %"char[]"* %taddr36 to { i8*, i64 }*
%65 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %64, i32 0, i32 0
%lo37 = load i8*, i8** %65, align 8
%66 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %64, i32 0, i32 1
%hi38 = load i64, i64* %66, align 8
%67 = load i32, i32* %abc, align 4
%68 = call i32 @llvm.bswap.i32(i32 %67)
%69 = and i32 65535, %68
%ztrunc = trunc i32 %69 to i16
store i16 %ztrunc, i16* %taddr41, align 2
%70 = bitcast i16* %taddr41 to i8*
%71 = insertvalue %variant undef, i8* %70, 0
%72 = insertvalue %variant %71, i64 ptrtoint (%.introspect* @"ct$ushort" to i64), 1
%73 = getelementptr inbounds [1 x %variant], [1 x %variant]* %varargslots40, i64 0, i64 0
store %variant %72, %variant* %73, align 16
%74 = getelementptr inbounds %"variant[]", %"variant[]"* %vararg39, i32 0, i32 1
store i64 1, i64* %74, align 8
%75 = getelementptr inbounds %"variant[]", %"variant[]"* %vararg39, i32 0, i32 0
%76 = bitcast [1 x %variant]* %varargslots40 to %variant*
store %variant* %76, %variant** %75, align 8
%77 = bitcast %"variant[]"* %vararg39 to { i8*, i64 }*
%78 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %77, i32 0, i32 0
%lo42 = load i8*, i8** %78, align 8
%79 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %77, i32 0, i32 1
%hi43 = load i64, i64* %79, align 8
%80 = call i64 @std_io_printfln(i64* %retparam35, i8* %lo37, i64 %hi38, i8* %lo42, i64 %hi43)
%not_err44 = icmp eq i64 %80, 0
br i1 %not_err44, label %after_check45, label %voiderr46
after_check45: ; preds = %loop.exit34
br label %voiderr46
voiderr46: ; preds = %after_check45, %loop.exit34
%81 = load i32, i32* %abc, align 4
%82 = call i32 @llvm.bswap.i32(i32 %81)
%83 = and i32 %82, -65536
%84 = or i32 %83, 4660
%85 = call i32 @llvm.bswap.i32(i32 %84)
store i32 %85, i32* %abc, align 4
%86 = load i32, i32* %abc, align 4
%87 = call i32 @llvm.bswap.i32(i32 %86)
%88 = and i32 %87, 65535
%89 = or i32 %88, 1450704896
%90 = call i32 @llvm.bswap.i32(i32 %89)
store i32 %90, i32* %abc, align 4
store %"char[]" { i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str.6, i32 0, i32 0), i64 12 }, %"char[]"* %taddr48, align 8
%91 = bitcast %"char[]"* %taddr48 to { i8*, i64 }*
%92 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %91, i32 0, i32 0
%lo49 = load i8*, i8** %92, align 8
%93 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %91, i32 0, i32 1
%hi50 = load i64, i64* %93, align 8
%94 = load i32, i32* %abc, align 4
%95 = call i32 @llvm.bswap.i32(i32 %94)
%96 = and i32 65535, %95
%ztrunc53 = trunc i32 %96 to i16
store i16 %ztrunc53, i16* %taddr54, align 2
%97 = bitcast i16* %taddr54 to i8*
%98 = insertvalue %variant undef, i8* %97, 0
%99 = insertvalue %variant %98, i64 ptrtoint (%.introspect* @"ct$ushort" to i64), 1
%100 = getelementptr inbounds [1 x %variant], [1 x %variant]* %varargslots52, i64 0, i64 0
store %variant %99, %variant* %100, align 16
%101 = getelementptr inbounds %"variant[]", %"variant[]"* %vararg51, i32 0, i32 1
store i64 1, i64* %101, align 8
%102 = getelementptr inbounds %"variant[]", %"variant[]"* %vararg51, i32 0, i32 0
%103 = bitcast [1 x %variant]* %varargslots52 to %variant*
store %variant* %103, %variant** %102, align 8
%104 = bitcast %"variant[]"* %vararg51 to { i8*, i64 }*
%105 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %104, i32 0, i32 0
%lo55 = load i8*, i8** %105, align 8
%106 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %104, i32 0, i32 1
%hi56 = load i64, i64* %106, align 8
%107 = call i64 @std_io_printfln(i64* %retparam47, i8* %lo49, i64 %hi50, i8* %lo55, i64 %hi56)
%not_err57 = icmp eq i64 %107, 0
br i1 %not_err57, label %after_check58, label %voiderr59
after_check58: ; preds = %voiderr46
br label %voiderr59
voiderr59: ; preds = %after_check58, %voiderr46
%108 = load [4 x i8]*, [4 x i8]** %z, align 8
store [4 x i8]* %108, [4 x i8]** %.anon60, align 8
store i64 0, i64* %.anon61, align 8
br label %loop.cond62
loop.cond62: ; preds = %voiderr76, %voiderr59
%109 = load i64, i64* %.anon61, align 8
%gt63 = icmp ugt i64 4, %109
br i1 %gt63, label %loop.body64, label %loop.exit78
loop.body64: ; preds = %loop.cond62
%110 = load [4 x i8]*, [4 x i8]** %.anon60, align 8
%111 = load i64, i64* %.anon61, align 8
%112 = getelementptr inbounds [4 x i8], [4 x i8]* %110, i64 0, i64 %111
%113 = load i8, i8* %112, align 1
store i8 %113, i8* %d65, align 1
store %"char[]" { i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.7, i32 0, i32 0), i64 3 }, %"char[]"* %taddr67, align 8
%114 = bitcast %"char[]"* %taddr67 to { i8*, i64 }*
%115 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %114, i32 0, i32 0
%lo68 = load i8*, i8** %115, align 8
%116 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %114, i32 0, i32 1
%hi69 = load i64, i64* %116, align 8
%117 = insertvalue %variant undef, i8* %d65, 0
%118 = insertvalue %variant %117, i64 ptrtoint (%.introspect* @"ct$char" to i64), 1
%119 = getelementptr inbounds [1 x %variant], [1 x %variant]* %varargslots71, i64 0, i64 0
store %variant %118, %variant* %119, align 16
%120 = getelementptr inbounds %"variant[]", %"variant[]"* %vararg70, i32 0, i32 1
store i64 1, i64* %120, align 8
%121 = getelementptr inbounds %"variant[]", %"variant[]"* %vararg70, i32 0, i32 0
%122 = bitcast [1 x %variant]* %varargslots71 to %variant*
store %variant* %122, %variant** %121, align 8
%123 = bitcast %"variant[]"* %vararg70 to { i8*, i64 }*
%124 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %123, i32 0, i32 0
%lo72 = load i8*, i8** %124, align 8
%125 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %123, i32 0, i32 1
%hi73 = load i64, i64* %125, align 8
%126 = call i64 @std_io_printf(i64* %retparam66, i8* %lo68, i64 %hi69, i8* %lo72, i64 %hi73)
%not_err74 = icmp eq i64 %126, 0
br i1 %not_err74, label %after_check75, label %voiderr76
after_check75: ; preds = %loop.body64
br label %voiderr76
voiderr76: ; preds = %after_check75, %loop.body64
%127 = load i64, i64* %.anon61, align 8
%add77 = add i64 %127, 1
store i64 %add77, i64* %.anon61, align 8
br label %loop.cond62
loop.exit78: ; preds = %loop.cond62
%128 = call i32 @std_io_println(i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str.8, i32 0, i32 0)) #2
store i32 0, i32* %y, align 4
%129 = load i32, i32* %y, align 4
store i32 123, i32* %y, align 4
store %"char[]" { i8* getelementptr inbounds ([19 x i8], [19 x i8]* @.str.9, i32 0, i32 0), i64 18 }, %"char[]"* %taddr80, align 8
%130 = bitcast %"char[]"* %taddr80 to { i8*, i64 }*
%131 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %130, i32 0, i32 0
%lo81 = load i8*, i8** %131, align 8
%132 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %130, i32 0, i32 1
%hi82 = load i64, i64* %132, align 8
%133 = bitcast i32* %y to i8*
%134 = insertvalue %variant undef, i8* %133, 0
%135 = insertvalue %variant %134, i64 ptrtoint (%.introspect* @"ct$int" to i64), 1
%136 = getelementptr inbounds [2 x %variant], [2 x %variant]* %varargslots84, i64 0, i64 0
store %variant %135, %variant* %136, align 16
%137 = load i32, i32* %y, align 4
store i32 %137, i32* %taddr85, align 4
%138 = bitcast i32* %taddr85 to i8*
%139 = insertvalue %variant undef, i8* %138, 0
%140 = insertvalue %variant %139, i64 ptrtoint (%.introspect* @"ct$int" to i64), 1
%141 = getelementptr inbounds [2 x %variant], [2 x %variant]* %varargslots84, i64 0, i64 1
store %variant %140, %variant* %141, align 16
%142 = getelementptr inbounds %"variant[]", %"variant[]"* %vararg83, i32 0, i32 1
store i64 2, i64* %142, align 8
%143 = getelementptr inbounds %"variant[]", %"variant[]"* %vararg83, i32 0, i32 0
%144 = bitcast [2 x %variant]* %varargslots84 to %variant*
store %variant* %144, %variant** %143, align 8
%145 = bitcast %"variant[]"* %vararg83 to { i8*, i64 }*
%146 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %145, i32 0, i32 0
%lo86 = load i8*, i8** %146, align 8
%147 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %145, i32 0, i32 1
%hi87 = load i64, i64* %147, align 8
%148 = call i64 @std_io_printf(i64* %retparam79, i8* %lo81, i64 %hi82, i8* %lo86, i64 %hi87)
%not_err88 = icmp eq i64 %148, 0
br i1 %not_err88, label %after_check89, label %voiderr90
after_check89: ; preds = %loop.exit78
br label %voiderr90
voiderr90: ; preds = %after_check89, %loop.exit78
ret void
}

View File

@@ -122,15 +122,6 @@ fn void test3()
/* #expect: foo.ll
define void @foo_main() #0 {
entry:
call void @foo_test1()
call void @foo_test2()
call void @foo_test3()
ret void
}
; Function Attrs: nounwind
define void @foo_test1() #0 {
entry:
%xx = alloca i64, align 8
@@ -350,7 +341,7 @@ entry:
%1 = load i8, ptr %0, align 1
%2 = and i8 %1, -8
%3 = or i8 %2, 3
store i8 %3, ptr %0, align 1
store i8 %2, ptr %0, align 1
%4 = getelementptr inbounds [3 x i8], ptr %xx, i64 0, i64 0
%5 = load i8, ptr %4, align 1
%zext = zext i8 %5 to i32
@@ -380,7 +371,7 @@ entry:
%15 = load i8, ptr %13, align 1
%16 = and i8 %15, -8
%17 = or i8 %16, %14
store i8 %17, ptr %13, align 1
store i8 %16, ptr %13, align 1
%18 = getelementptr inbounds [3 x i8], ptr %xx, i64 0, i64 0
%19 = load i8, ptr %18, align 1
%zext9 = zext i8 %19 to i32
@@ -424,7 +415,7 @@ entry:
%36 = load i8, ptr %34, align 1
%37 = and i8 %36, -2
%38 = or i8 %37, %35
store i8 %38, ptr %34, align 1
store i8 %37, ptr %34, align 1
%39 = getelementptr inbounds [3 x i8], ptr %xx, i64 0, i64 0
%40 = load i8, ptr %39, align 1
%zext28 = zext i8 %40 to i32
@@ -468,7 +459,7 @@ entry:
%57 = load i8, ptr %55, align 1
%58 = and i8 %57, -2
%59 = or i8 %58, %56
store i8 %59, ptr %55, align 1
store i8 %58, ptr %55, align 1
%60 = getelementptr inbounds [3 x i8], ptr %xx, i64 0, i64 0
%61 = load i8, ptr %60, align 1
%zext47 = zext i8 %61 to i32
@@ -512,7 +503,7 @@ entry:
%78 = load i8, ptr %76, align 1
%79 = and i8 %78, -2
%80 = or i8 %79, %77
store i8 %80, ptr %76, align 1
store i8 %79, ptr %76, align 1
%81 = getelementptr inbounds [3 x i8], ptr %xx, i64 0, i64 0
%82 = load i8, ptr %81, align 1
%zext66 = zext i8 %82 to i32
@@ -557,7 +548,7 @@ entry:
%100 = load i8, ptr %98, align 1
%101 = and i8 %100, -2
%102 = or i8 %101, %99
store i8 %102, ptr %98, align 1
store i8 %101, ptr %98, align 1
%103 = getelementptr inbounds [3 x i8], ptr %xx, i64 0, i64 0
%104 = load i8, ptr %103, align 1
%zext86 = zext i8 %104 to i32
@@ -602,7 +593,7 @@ entry:
%122 = load i8, ptr %120, align 1
%123 = and i8 %122, -2
%124 = or i8 %123, %121
store i8 %124, ptr %120, align 1
store i8 %123, ptr %120, align 1
%125 = getelementptr inbounds [3 x i8], ptr %xx, i64 0, i64 0
%126 = load i8, ptr %125, align 1
%zext106 = zext i8 %126 to i32
@@ -646,7 +637,7 @@ entry:
%143 = load i8, ptr %141, align 1
%144 = and i8 %143, -2
%145 = or i8 %144, %142
store i8 %145, ptr %141, align 1
store i8 %144, ptr %141, align 1
%146 = getelementptr inbounds [3 x i8], ptr %xx, i64 0, i64 0
%147 = load i8, ptr %146, align 1
%zext125 = zext i8 %147 to i32
@@ -690,7 +681,7 @@ entry:
%164 = load i8, ptr %162, align 1
%165 = and i8 %164, -2
%166 = or i8 %165, %163
store i8 %166, ptr %162, align 1
store i8 %165, ptr %162, align 1
%167 = getelementptr inbounds [3 x i8], ptr %xx, i64 0, i64 0
%168 = load i8, ptr %167, align 1
%zext144 = zext i8 %168 to i32
@@ -826,7 +817,7 @@ entry:
%36 = load i8, ptr %34, align 1
%37 = and i8 %36, -4
%38 = or i8 %37, %35
store i8 %38, ptr %34, align 1
store i8 %37, ptr %34, align 1
%39 = getelementptr inbounds [3 x i8], ptr %xx, i64 0, i64 0
%40 = load i8, ptr %39, align 1
%zext33 = zext i8 %40 to i32
@@ -871,7 +862,7 @@ entry:
%57 = load i8, ptr %55, align 1
%58 = and i8 %57, -4
%59 = or i8 %58, %56
store i8 %59, ptr %55, align 1
store i8 %58, ptr %55, align 1
%60 = getelementptr inbounds [3 x i8], ptr %xx, i64 0, i64 0
%61 = load i8, ptr %60, align 1
%zext53 = zext i8 %61 to i32
@@ -916,7 +907,7 @@ entry:
%78 = load i8, ptr %76, align 1
%79 = and i8 %78, -4
%80 = or i8 %79, %77
store i8 %80, ptr %76, align 1
store i8 %79, ptr %76, align 1
%81 = getelementptr inbounds [3 x i8], ptr %xx, i64 0, i64 0
%82 = load i8, ptr %81, align 1
%zext73 = zext i8 %82 to i32
@@ -962,7 +953,7 @@ entry:
%100 = load i8, ptr %98, align 1
%101 = and i8 %100, -4
%102 = or i8 %101, %99
store i8 %102, ptr %98, align 1
store i8 %101, ptr %98, align 1
%103 = getelementptr inbounds [3 x i8], ptr %xx, i64 0, i64 0
%104 = load i8, ptr %103, align 1
%zext94 = zext i8 %104 to i32
@@ -1008,7 +999,7 @@ entry:
%122 = load i8, ptr %120, align 1
%123 = and i8 %122, -4
%124 = or i8 %123, %121
store i8 %124, ptr %120, align 1
store i8 %123, ptr %120, align 1
%125 = getelementptr inbounds [3 x i8], ptr %xx, i64 0, i64 0
%126 = load i8, ptr %125, align 1
%zext115 = zext i8 %126 to i32
@@ -1053,7 +1044,7 @@ entry:
%143 = load i8, ptr %141, align 1
%144 = and i8 %143, -4
%145 = or i8 %144, %142
store i8 %145, ptr %141, align 1
store i8 %144, ptr %141, align 1
%146 = getelementptr inbounds [3 x i8], ptr %xx, i64 0, i64 0
%147 = load i8, ptr %146, align 1
%zext135 = zext i8 %147 to i32
@@ -1098,7 +1089,7 @@ entry:
%164 = load i8, ptr %162, align 1
%165 = and i8 %164, -4
%166 = or i8 %165, %163
store i8 %166, ptr %162, align 1
store i8 %165, ptr %162, align 1
%167 = getelementptr inbounds [3 x i8], ptr %xx, i64 0, i64 0
%168 = load i8, ptr %167, align 1
%zext155 = zext i8 %168 to i32

View File

@@ -93,7 +93,7 @@ entry:
%26 = load i8, ptr %25, align 1
%27 = and i8 %26, -16
%28 = or i8 %27, 11
store i8 %28, ptr %25, align 1
store i8 %27, ptr %25, align 1
%29 = getelementptr inbounds [4 x i8], ptr %xy, i64 0, i64 0
%30 = load i8, ptr %29, align 1
%zext11 = zext i8 %30 to i32
@@ -121,7 +121,7 @@ entry:
%44 = load i8, ptr %43, align 1
%45 = and i8 %44, -16
%46 = or i8 %45, 14
store i8 %46, ptr %43, align 1
store i8 %45, ptr %43, align 1
%47 = getelementptr inbounds [4 x i8], ptr %xx, i64 0, i64 0
%48 = load i8, ptr %47, align 1
%zext17 = zext i8 %48 to i32

View File

@@ -0,0 +1,336 @@
// #target: macos-x64
module test;
import std::io;
bitstruct Test : int @bigendian
{
ushort a : 0..15;
ushort b : 16..31;
}
bitstruct Test2 : char[4] @bigendian
{
ushort a : 0..15;
ushort b : 16..31;
}
fn void main()
{
IntBE x;
x.val = 123;
io::printf("BE 123 => %d (%d)\n", (int)x, x.val);
Test abc = { .a = 0x1234, .b = 0x5678 };
Test2 abc2 = { .a = 0x1234, .b = 0x5678 };
char[4]* z = (char[4]*)&abc;
char[4]* z2 = (char[4]*)&abc2;
foreach (d : z2) io::printf(" %x", d);
io::println("");
foreach (d : z) io::printf(" %x", d);
io::println("");
io::printfln("abc.a = %x", abc.a);
abc.a = 0x1234;
abc.b = 0x5678;
io::printfln("->abc.a = %x", abc.a);
foreach (d : z) io::printf(" %x", d);
io::println("");
IntLE y;
y.val = 123;
io::printf("LE 123 => %d (%d)\n", (int)y, y.val);
}
/* #expect: test.ll
%0 = load i32, ptr %x, align 4
%1 = call i32 @llvm.bswap.i32(i32 %0)
store i32 2063597568, ptr %x, align 4
store %"char[]" { ptr @.str, i64 18 }, ptr %taddr, align 8
%2 = getelementptr inbounds { ptr, i64 }, ptr %taddr, i32 0, i32 0
%lo = load ptr, ptr %2, align 8
%3 = getelementptr inbounds { ptr, i64 }, ptr %taddr, i32 0, i32 1
%hi = load i64, ptr %3, align 8
%4 = insertvalue %variant undef, ptr %x, 0
%5 = insertvalue %variant %4, i64 ptrtoint (ptr @"ct$int" to i64), 1
%6 = getelementptr inbounds [2 x %variant], ptr %varargslots, i64 0, i64 0
store %variant %5, ptr %6, align 16
%7 = load i32, ptr %x, align 4
%8 = call i32 @llvm.bswap.i32(i32 %7)
store i32 %8, ptr %taddr1, align 4
%9 = insertvalue %variant undef, ptr %taddr1, 0
%10 = insertvalue %variant %9, i64 ptrtoint (ptr @"ct$int" to i64), 1
%11 = getelementptr inbounds [2 x %variant], ptr %varargslots, i64 0, i64 1
store %variant %10, ptr %11, align 16
%12 = getelementptr inbounds %"variant[]", ptr %vararg, i32 0, i32 1
store i64 2, ptr %12, align 8
%13 = getelementptr inbounds %"variant[]", ptr %vararg, i32 0, i32 0
store ptr %varargslots, ptr %13, align 8
%14 = getelementptr inbounds { ptr, i64 }, ptr %vararg, i32 0, i32 0
%lo2 = load ptr, ptr %14, align 8
%15 = getelementptr inbounds { ptr, i64 }, ptr %vararg, i32 0, i32 1
%hi3 = load i64, ptr %15, align 8
%16 = call i64 @std_io_printf(ptr %retparam, ptr %lo, i64 %hi, ptr %lo2, i64 %hi3)
%not_err = icmp eq i64 %16, 0
br i1 %not_err, label %after_check, label %voiderr
after_check: ; preds = %entry
br label %voiderr
voiderr: ; preds = %after_check, %entry
store i32 873625686, ptr %abc, align 4
store [4 x i8] c"\124Vx", ptr %abc2, align 1
store ptr %abc, ptr %z, align 8
store ptr %abc2, ptr %z2, align 8
%17 = load ptr, ptr %z2, align 8
store ptr %17, ptr %.anon, align 8
store i64 0, ptr %.anon4, align 8
br label %loop.cond
loop.cond: ; preds = %voiderr15, %voiderr
%18 = load i64, ptr %.anon4, align 8
%gt = icmp ugt i64 4, %18
br i1 %gt, label %loop.body, label %loop.exit
loop.body: ; preds = %loop.cond
%19 = load ptr, ptr %.anon, align 8
%20 = load i64, ptr %.anon4, align 8
%21 = getelementptr inbounds [4 x i8], ptr %19, i64 0, i64 %20
%22 = load i8, ptr %21, align 1
store i8 %22, ptr %d, align 1
store %"char[]" { ptr @.str.1, i64 3 }, ptr %taddr6, align 8
%23 = getelementptr inbounds { ptr, i64 }, ptr %taddr6, i32 0, i32 0
%lo7 = load ptr, ptr %23, align 8
%24 = getelementptr inbounds { ptr, i64 }, ptr %taddr6, i32 0, i32 1
%hi8 = load i64, ptr %24, align 8
%25 = insertvalue %variant undef, ptr %d, 0
%26 = insertvalue %variant %25, i64 ptrtoint (ptr @"ct$char" to i64), 1
%27 = getelementptr inbounds [1 x %variant], ptr %varargslots10, i64 0, i64 0
store %variant %26, ptr %27, align 16
%28 = getelementptr inbounds %"variant[]", ptr %vararg9, i32 0, i32 1
store i64 1, ptr %28, align 8
%29 = getelementptr inbounds %"variant[]", ptr %vararg9, i32 0, i32 0
store ptr %varargslots10, ptr %29, align 8
%30 = getelementptr inbounds { ptr, i64 }, ptr %vararg9, i32 0, i32 0
%lo11 = load ptr, ptr %30, align 8
%31 = getelementptr inbounds { ptr, i64 }, ptr %vararg9, i32 0, i32 1
%hi12 = load i64, ptr %31, align 8
%32 = call i64 @std_io_printf(ptr %retparam5, ptr %lo7, i64 %hi8, ptr %lo11, i64 %hi12)
%not_err13 = icmp eq i64 %32, 0
br i1 %not_err13, label %after_check14, label %voiderr15
after_check14: ; preds = %loop.body
br label %voiderr15
voiderr15: ; preds = %after_check14, %loop.body
%33 = load i64, ptr %.anon4, align 8
%add = add i64 %33, 1
store i64 %add, ptr %.anon4, align 8
br label %loop.cond
loop.exit: ; preds = %loop.cond
%34 = call i32 @std_io_println(ptr @.str.2) #2
%35 = load ptr, ptr %z, align 8
store ptr %35, ptr %.anon16, align 8
store i64 0, ptr %.anon17, align 8
br label %loop.cond18
loop.cond18: ; preds = %voiderr32, %loop.exit
%36 = load i64, ptr %.anon17, align 8
%gt19 = icmp ugt i64 4, %36
br i1 %gt19, label %loop.body20, label %loop.exit34
loop.body20: ; preds = %loop.cond18
%37 = load ptr, ptr %.anon16, align 8
%38 = load i64, ptr %.anon17, align 8
%39 = getelementptr inbounds [4 x i8], ptr %37, i64 0, i64 %38
%40 = load i8, ptr %39, align 1
store i8 %40, ptr %d21, align 1
store %"char[]" { ptr @.str.3, i64 3 }, ptr %taddr23, align 8
%41 = getelementptr inbounds { ptr, i64 }, ptr %taddr23, i32 0, i32 0
%lo24 = load ptr, ptr %41, align 8
%42 = getelementptr inbounds { ptr, i64 }, ptr %taddr23, i32 0, i32 1
%hi25 = load i64, ptr %42, align 8
%43 = insertvalue %variant undef, ptr %d21, 0
%44 = insertvalue %variant %43, i64 ptrtoint (ptr @"ct$char" to i64), 1
%45 = getelementptr inbounds [1 x %variant], ptr %varargslots27, i64 0, i64 0
store %variant %44, ptr %45, align 16
%46 = getelementptr inbounds %"variant[]", ptr %vararg26, i32 0, i32 1
store i64 1, ptr %46, align 8
%47 = getelementptr inbounds %"variant[]", ptr %vararg26, i32 0, i32 0
store ptr %varargslots27, ptr %47, align 8
%48 = getelementptr inbounds { ptr, i64 }, ptr %vararg26, i32 0, i32 0
%lo28 = load ptr, ptr %48, align 8
%49 = getelementptr inbounds { ptr, i64 }, ptr %vararg26, i32 0, i32 1
%hi29 = load i64, ptr %49, align 8
%50 = call i64 @std_io_printf(ptr %retparam22, ptr %lo24, i64 %hi25, ptr %lo28, i64 %hi29)
%not_err30 = icmp eq i64 %50, 0
br i1 %not_err30, label %after_check31, label %voiderr32
after_check31: ; preds = %loop.body20
br label %voiderr32
voiderr32: ; preds = %after_check31, %loop.body20
%51 = load i64, ptr %.anon17, align 8
%add33 = add i64 %51, 1
store i64 %add33, ptr %.anon17, align 8
br label %loop.cond18
loop.exit34: ; preds = %loop.cond18
%52 = call i32 @std_io_println(ptr @.str.4) #2
store %"char[]" { ptr @.str.5, i64 10 }, ptr %taddr36, align 8
%53 = getelementptr inbounds { ptr, i64 }, ptr %taddr36, i32 0, i32 0
%lo37 = load ptr, ptr %53, align 8
%54 = getelementptr inbounds { ptr, i64 }, ptr %taddr36, i32 0, i32 1
%hi38 = load i64, ptr %54, align 8
%55 = load i32, ptr %abc, align 4
%56 = call i32 @llvm.bswap.i32(i32 %55)
%57 = and i32 65535, %56
%ztrunc = trunc i32 %57 to i16
store i16 %ztrunc, ptr %taddr41, align 2
%58 = insertvalue %variant undef, ptr %taddr41, 0
%59 = insertvalue %variant %58, i64 ptrtoint (ptr @"ct$ushort" to i64), 1
%60 = getelementptr inbounds [1 x %variant], ptr %varargslots40, i64 0, i64 0
store %variant %59, ptr %60, align 16
%61 = getelementptr inbounds %"variant[]", ptr %vararg39, i32 0, i32 1
store i64 1, ptr %61, align 8
%62 = getelementptr inbounds %"variant[]", ptr %vararg39, i32 0, i32 0
store ptr %varargslots40, ptr %62, align 8
%63 = getelementptr inbounds { ptr, i64 }, ptr %vararg39, i32 0, i32 0
%lo42 = load ptr, ptr %63, align 8
%64 = getelementptr inbounds { ptr, i64 }, ptr %vararg39, i32 0, i32 1
%hi43 = load i64, ptr %64, align 8
%65 = call i64 @std_io_printfln(ptr %retparam35, ptr %lo37, i64 %hi38, ptr %lo42, i64 %hi43)
%not_err44 = icmp eq i64 %65, 0
br i1 %not_err44, label %after_check45, label %voiderr46
after_check45: ; preds = %loop.exit34
br label %voiderr46
voiderr46: ; preds = %after_check45, %loop.exit34
%66 = load i32, ptr %abc, align 4
%67 = call i32 @llvm.bswap.i32(i32 %66)
%68 = and i32 %67, -65536
%69 = or i32 %68, 4660
%70 = call i32 @llvm.bswap.i32(i32 %69)
store i32 %70, ptr %abc, align 4
%71 = load i32, ptr %abc, align 4
%72 = call i32 @llvm.bswap.i32(i32 %71)
%73 = and i32 %72, 65535
%74 = or i32 %73, 1450704896
%75 = call i32 @llvm.bswap.i32(i32 %74)
store i32 %75, ptr %abc, align 4
store %"char[]" { ptr @.str.6, i64 12 }, ptr %taddr48, align 8
%76 = getelementptr inbounds { ptr, i64 }, ptr %taddr48, i32 0, i32 0
%lo49 = load ptr, ptr %76, align 8
%77 = getelementptr inbounds { ptr, i64 }, ptr %taddr48, i32 0, i32 1
%hi50 = load i64, ptr %77, align 8
%78 = load i32, ptr %abc, align 4
%79 = call i32 @llvm.bswap.i32(i32 %78)
%80 = and i32 65535, %79
%ztrunc53 = trunc i32 %80 to i16
store i16 %ztrunc53, ptr %taddr54, align 2
%81 = insertvalue %variant undef, ptr %taddr54, 0
%82 = insertvalue %variant %81, i64 ptrtoint (ptr @"ct$ushort" to i64), 1
%83 = getelementptr inbounds [1 x %variant], ptr %varargslots52, i64 0, i64 0
store %variant %82, ptr %83, align 16
%84 = getelementptr inbounds %"variant[]", ptr %vararg51, i32 0, i32 1
store i64 1, ptr %84, align 8
%85 = getelementptr inbounds %"variant[]", ptr %vararg51, i32 0, i32 0
store ptr %varargslots52, ptr %85, align 8
%86 = getelementptr inbounds { ptr, i64 }, ptr %vararg51, i32 0, i32 0
%lo55 = load ptr, ptr %86, align 8
%87 = getelementptr inbounds { ptr, i64 }, ptr %vararg51, i32 0, i32 1
%hi56 = load i64, ptr %87, align 8
%88 = call i64 @std_io_printfln(ptr %retparam47, ptr %lo49, i64 %hi50, ptr %lo55, i64 %hi56)
%not_err57 = icmp eq i64 %88, 0
br i1 %not_err57, label %after_check58, label %voiderr59
after_check58: ; preds = %voiderr46
br label %voiderr59
voiderr59: ; preds = %after_check58, %voiderr46
%89 = load ptr, ptr %z, align 8
store ptr %89, ptr %.anon60, align 8
store i64 0, ptr %.anon61, align 8
br label %loop.cond62
loop.cond62: ; preds = %voiderr76, %voiderr59
%90 = load i64, ptr %.anon61, align 8
%gt63 = icmp ugt i64 4, %90
br i1 %gt63, label %loop.body64, label %loop.exit78
loop.body64: ; preds = %loop.cond62
%91 = load ptr, ptr %.anon60, align 8
%92 = load i64, ptr %.anon61, align 8
%93 = getelementptr inbounds [4 x i8], ptr %91, i64 0, i64 %92
%94 = load i8, ptr %93, align 1
store i8 %94, ptr %d65, align 1
store %"char[]" { ptr @.str.7, i64 3 }, ptr %taddr67, align 8
%95 = getelementptr inbounds { ptr, i64 }, ptr %taddr67, i32 0, i32 0
%lo68 = load ptr, ptr %95, align 8
%96 = getelementptr inbounds { ptr, i64 }, ptr %taddr67, i32 0, i32 1
%hi69 = load i64, ptr %96, align 8
%97 = insertvalue %variant undef, ptr %d65, 0
%98 = insertvalue %variant %97, i64 ptrtoint (ptr @"ct$char" to i64), 1
%99 = getelementptr inbounds [1 x %variant], ptr %varargslots71, i64 0, i64 0
store %variant %98, ptr %99, align 16
%100 = getelementptr inbounds %"variant[]", ptr %vararg70, i32 0, i32 1
store i64 1, ptr %100, align 8
%101 = getelementptr inbounds %"variant[]", ptr %vararg70, i32 0, i32 0
store ptr %varargslots71, ptr %101, align 8
%102 = getelementptr inbounds { ptr, i64 }, ptr %vararg70, i32 0, i32 0
%lo72 = load ptr, ptr %102, align 8
%103 = getelementptr inbounds { ptr, i64 }, ptr %vararg70, i32 0, i32 1
%hi73 = load i64, ptr %103, align 8
%104 = call i64 @std_io_printf(ptr %retparam66, ptr %lo68, i64 %hi69, ptr %lo72, i64 %hi73)
%not_err74 = icmp eq i64 %104, 0
br i1 %not_err74, label %after_check75, label %voiderr76
after_check75: ; preds = %loop.body64
br label %voiderr76
voiderr76: ; preds = %after_check75, %loop.body64
%105 = load i64, ptr %.anon61, align 8
%add77 = add i64 %105, 1
store i64 %add77, ptr %.anon61, align 8
br label %loop.cond62
loop.exit78: ; preds = %loop.cond62
%106 = call i32 @std_io_println(ptr @.str.8) #2
store i32 0, ptr %y, align 4
%107 = load i32, ptr %y, align 4
store i32 123, ptr %y, align 4
store %"char[]" { ptr @.str.9, i64 18 }, ptr %taddr80, align 8
%108 = getelementptr inbounds { ptr, i64 }, ptr %taddr80, i32 0, i32 0
%lo81 = load ptr, ptr %108, align 8
%109 = getelementptr inbounds { ptr, i64 }, ptr %taddr80, i32 0, i32 1
%hi82 = load i64, ptr %109, align 8
%110 = insertvalue %variant undef, ptr %y, 0
%111 = insertvalue %variant %110, i64 ptrtoint (ptr @"ct$int" to i64), 1
%112 = getelementptr inbounds [2 x %variant], ptr %varargslots84, i64 0, i64 0
store %variant %111, ptr %112, align 16
%113 = load i32, ptr %y, align 4
store i32 %113, ptr %taddr85, align 4
%114 = insertvalue %variant undef, ptr %taddr85, 0
%115 = insertvalue %variant %114, i64 ptrtoint (ptr @"ct$int" to i64), 1
%116 = getelementptr inbounds [2 x %variant], ptr %varargslots84, i64 0, i64 1
store %variant %115, ptr %116, align 16
%117 = getelementptr inbounds %"variant[]", ptr %vararg83, i32 0, i32 1
store i64 2, ptr %117, align 8
%118 = getelementptr inbounds %"variant[]", ptr %vararg83, i32 0, i32 0
store ptr %varargslots84, ptr %118, align 8
%119 = getelementptr inbounds { ptr, i64 }, ptr %vararg83, i32 0, i32 0
%lo86 = load ptr, ptr %119, align 8
%120 = getelementptr inbounds { ptr, i64 }, ptr %vararg83, i32 0, i32 1
%hi87 = load i64, ptr %120, align 8
%121 = call i64 @std_io_printf(ptr %retparam79, ptr %lo81, i64 %hi82, ptr %lo86, i64 %hi87)
%not_err88 = icmp eq i64 %121, 0
br i1 %not_err88, label %after_check89, label %voiderr90
after_check89: ; preds = %loop.exit78
br label %voiderr90
voiderr90: ; preds = %after_check89, %loop.exit78
ret void
}