aboutsummaryrefslogtreecommitdiff
path: root/src/ir.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/ir.cpp')
-rw-r--r--src/ir.cpp21
1 files changed, 20 insertions, 1 deletions
diff --git a/src/ir.cpp b/src/ir.cpp
index 13f2add13..501332347 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -4783,6 +4783,14 @@ irValue *ir_emit_struct_ep(irProcedure *proc, irValue *s, i32 index) {
irValue *ir_emit_struct_ev(irProcedure *proc, irValue *s, i32 index) {
// NOTE(bill): For some weird legacy reason in LLVM, structure elements must be accessed as an i32
+ if (s->kind == irValue_Instr) {
+ if (s->Instr.kind == irInstr_Load) {
+ irValue *addr = s->Instr.Load.address;
+ irValue *ptr = ir_emit_struct_ep(proc, addr, index);
+ return ir_emit_load(proc, ptr);
+ }
+ }
+
gbAllocator a = ir_allocator();
Type *t = base_type(ir_type(s));
Type *result_type = nullptr;
@@ -4889,7 +4897,9 @@ irValue *ir_emit_deep_field_gep(irProcedure *proc, irValue *e, Selection sel) {
}
type = core_type(type);
- if (is_type_raw_union(type)) {
+ if (is_type_quaternion(type)) {
+ e = ir_emit_struct_ep(proc, e, index);
+ } else if (is_type_raw_union(type)) {
type = type->Struct.fields[index]->type;
GB_ASSERT(is_type_pointer(ir_type(e)));
e = ir_emit_bitcast(proc, e, alloc_type_pointer(type));
@@ -4942,6 +4952,15 @@ irValue *ir_emit_deep_field_gep(irProcedure *proc, irValue *e, Selection sel) {
irValue *ir_emit_deep_field_ev(irProcedure *proc, irValue *e, Selection sel) {
GB_ASSERT(sel.index.count > 0);
+
+ if (e->kind == irValue_Instr) {
+ if (e->Instr.kind == irInstr_Load) {
+ irValue *addr = e->Instr.Load.address;
+ irValue *ptr = ir_emit_deep_field_gep(proc, addr, sel);
+ return ir_emit_load(proc, ptr);
+ }
+ }
+
Type *type = ir_type(e);
for_array(i, sel.index) {