mirror of
https://github.com/ziglang/zig.git
synced 2026-02-21 16:54:52 +00:00
stage2 LLVM backend: fix bitcast
Properly handle when the operand type, the result type, or both, are by-ref values.
This commit is contained in:
parent
f890de6294
commit
11a60e8779
@ -3201,14 +3201,23 @@ pub const FuncGen = struct {
|
||||
const operand = try self.resolveInst(ty_op.operand);
|
||||
const operand_ty = self.air.typeOf(ty_op.operand);
|
||||
const inst_ty = self.air.typeOfIndex(inst);
|
||||
const operand_is_ref = isByRef(operand_ty);
|
||||
const result_is_ref = isByRef(inst_ty);
|
||||
const llvm_dest_ty = try self.dg.llvmType(inst_ty);
|
||||
|
||||
if (operand_is_ref and result_is_ref) {
|
||||
// They are both pointers; just do a bitcast on the pointers :)
|
||||
return self.builder.buildBitCast(operand, llvm_dest_ty.pointerType(0), "");
|
||||
}
|
||||
|
||||
if (operand_ty.zigTypeTag() == .Int and inst_ty.zigTypeTag() == .Pointer) {
|
||||
return self.builder.buildIntToPtr(operand, llvm_dest_ty, "");
|
||||
} else if (operand_ty.zigTypeTag() == .Vector and inst_ty.zigTypeTag() == .Array) {
|
||||
}
|
||||
|
||||
if (operand_ty.zigTypeTag() == .Vector and inst_ty.zigTypeTag() == .Array) {
|
||||
const target = self.dg.module.getTarget();
|
||||
const elem_ty = operand_ty.childType();
|
||||
if (!isByRef(inst_ty)) {
|
||||
if (!result_is_ref) {
|
||||
return self.dg.todo("implement bitcast vector to non-ref array", .{});
|
||||
}
|
||||
const array_ptr = self.buildAlloca(llvm_dest_ty);
|
||||
@ -3239,7 +3248,7 @@ pub const FuncGen = struct {
|
||||
const target = self.dg.module.getTarget();
|
||||
const elem_ty = operand_ty.childType();
|
||||
const llvm_vector_ty = try self.dg.llvmType(inst_ty);
|
||||
if (!isByRef(operand_ty)) {
|
||||
if (!operand_is_ref) {
|
||||
return self.dg.todo("implement bitcast non-ref array to vector", .{});
|
||||
}
|
||||
|
||||
@ -3274,6 +3283,21 @@ pub const FuncGen = struct {
|
||||
}
|
||||
}
|
||||
|
||||
if (operand_is_ref) {
|
||||
// Bitcast the operand pointer, then load.
|
||||
const casted_ptr = self.builder.buildBitCast(operand, llvm_dest_ty.pointerType(0), "");
|
||||
return self.builder.buildLoad(casted_ptr, "");
|
||||
}
|
||||
|
||||
if (result_is_ref) {
|
||||
// Bitcast the result pointer, then store.
|
||||
const result_ptr = self.buildAlloca(llvm_dest_ty);
|
||||
const operand_llvm_ty = try self.dg.llvmType(operand_ty);
|
||||
const casted_ptr = self.builder.buildBitCast(result_ptr, operand_llvm_ty.pointerType(0), "");
|
||||
_ = self.builder.buildStore(operand, casted_ptr);
|
||||
return result_ptr;
|
||||
}
|
||||
|
||||
return self.builder.buildBitCast(operand, llvm_dest_ty, "");
|
||||
}
|
||||
|
||||
|
||||
@ -64,3 +64,9 @@ test "bitcast literal [4]u8 param to u32" {
|
||||
const ip = @bitCast(u32, [_]u8{ 255, 255, 255, 255 });
|
||||
try expect(ip == maxInt(u32));
|
||||
}
|
||||
|
||||
test "bitcast generates a temporary value" {
|
||||
var y = @as(u16, 0x55AA);
|
||||
const x = @bitCast(u16, @bitCast([2]u8, y));
|
||||
try expect(y == x);
|
||||
}
|
||||
|
||||
@ -129,9 +129,3 @@ test "triple level result location with bitcast sandwich passed as tuple element
|
||||
};
|
||||
try S.foo(.{@as(f64, @bitCast(f32, @as(u32, 0x414570A4)))});
|
||||
}
|
||||
|
||||
test "bitcast generates a temporary value" {
|
||||
var y = @as(u16, 0x55AA);
|
||||
const x = @bitCast(u16, @bitCast([2]u8, y));
|
||||
try expectEqual(y, x);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user