This commit is contained in:
agra
2026-03-04 17:12:56 +02:00
parent 67e02a20a5
commit 22bc2439ce
7 changed files with 217 additions and 18 deletions

View File

@@ -706,11 +706,15 @@ pub const LLVMEmitter = struct {
if (ptr_kind == c.LLVMPointerTypeKind and val_kind != c.LLVMVoidTypeKind) {
// Coerce value to match the IR-declared pointer target type.
// E.g. storing i64 to *i8 (from index_gep on string) needs truncation.
//
// Only unwrap .pointer (from index_gep/alloca: *element → element).
// Never unwrap .many_pointer — it only appears as struct_gep field
// value types (e.g., [*]BigNode), where unwrapping to the element
// type gives a wrong store size (stores BigNode-sized instead of ptr).
if (self.getRefIRType(st.ptr)) |ptr_ir_ty| {
const pointee_info = self.ir_mod.types.get(ptr_ir_ty);
const target_ty: ?c.LLVMTypeRef = switch (pointee_info) {
.pointer => |p| self.toLLVMType(p.pointee),
.many_pointer => |p| self.toLLVMType(p.element),
else => null,
};
if (target_ty) |tt| {
@@ -2566,6 +2570,7 @@ pub const LLVMEmitter = struct {
return null;
}
/// Coerce both binary operands to match the instruction's result type.
/// E.g. if result is i64 but one operand is i32, sext it.
fn matchBinOpTypes(self: *LLVMEmitter, lhs: *c.LLVMValueRef, rhs: *c.LLVMValueRef, result_ty: TypeId) void {