authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2026-03-23 11:26:23+00:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2026-03-28 16:46:23+00:00
logbd8088bb9826b40be281d5cca89eac7ff7b76241
tree846600b2d3b17ed07d4bbe06fb21befb454ac5af
parent5941c9da08ae0d8ba4add37f0baeafdcd160dbd4
signaturelock-open Commit is signed but in an unrecognized format.

llvm: random enhancements and cleanups


4 files changed, 482 insertions(+), 551 deletions(-)

src/Air.zig+12-5
...@@ -870,13 +870,20 @@ pub const Inst = struct {...@@ -870,13 +870,20 @@ pub const Inst = struct {
870 /// Uses the `pl_op` field, payload represents the index of the target memory.870 /// Uses the `pl_op` field, payload represents the index of the target memory.
871 wasm_memory_grow,871 wasm_memory_grow,
872872
873 /// Returns `true` if and only if the operand, an integer with873 /// Returns `true` if and only if the operand, an integer with the same
874 /// the same size as the error integer type, is less than the874 /// size as the error integer type, is less than *or equal to* the total
875 /// total number of errors in the Module.875 /// number of errors in the Zcu. The "or equal to" is a consequence of
876 /// value 0 being reserved for the "non-error" status in error unions.
877 /// MLUGG TODO: rename this instruction to `cmp_lte_errors_len`
878 ///
879 /// This instruction exists (as opposed to just using `cmp_lte` against
880 /// a constant) because the number of errors in the Zcu is not known
881 /// until `Compilation.flush`. Before then, semantic analysis could
882 /// discover new errors at any time.
883 ///
876 /// Result type is always `bool`.884 /// Result type is always `bool`.
885 ///
877 /// Uses the `un_op` field.886 /// Uses the `un_op` field.
878 /// Note that the number of errors in the Module cannot be considered stable until
879 /// flush().
880 cmp_lt_errors_len,887 cmp_lt_errors_len,
881888
882 /// Returns pointer to current error return trace.889 /// Returns pointer to current error return trace.
src/Compilation.zig+1-1
...@@ -2485,7 +2485,7 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic,...@@ -2485,7 +2485,7 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic,
24852485
2486 if (use_llvm) {2486 if (use_llvm) {
2487 if (opt_zcu) |zcu| {2487 if (opt_zcu) |zcu| {
2488 zcu.llvm_object = try LlvmObject.create(arena, comp);2488 zcu.llvm_object = try LlvmObject.create(arena, zcu);
2489 }2489 }
2490 }2490 }
24912491
src/codegen/llvm.zig+111-96
...@@ -549,7 +549,7 @@ pub const Object = struct {...@@ -549,7 +549,7 @@ pub const Object = struct {
549 /// type from the global error set.549 /// type from the global error set.
550 debug_anyerror_fwd_ref: Builder.Metadata.Optional,550 debug_anyerror_fwd_ref: Builder.Metadata.Optional,
551551
552 target: *const std.Target,552 zcu: *Zcu,
553 /// Ideally we would use `llvm_module.getNamedFunction` to go from *Decl to LLVM function,553 /// Ideally we would use `llvm_module.getNamedFunction` to go from *Decl to LLVM function,
554 /// but that has some downsides:554 /// but that has some downsides:
555 /// * we have to compute the fully qualified name every time we want to do the lookup555 /// * we have to compute the fully qualified name every time we want to do the lookup
...@@ -574,9 +574,12 @@ pub const Object = struct {...@@ -574,9 +574,12 @@ pub const Object = struct {
574 /// Note that the values are not added until `emit`, when all errors in574 /// Note that the values are not added until `emit`, when all errors in
575 /// the compilation are known.575 /// the compilation are known.
576 error_name_table: Builder.Variable.Index,576 error_name_table: Builder.Variable.Index,
577577 /// Constant variable whose value is the number of errors in the Zcu.
578 /// Memoizes a null `?usize` value.578 ///
579 null_opt_usize: Builder.Constant,579 /// Initially `.none`---populated lazily by `getErrorsLen`.
580 ///
581 /// If this is not `.none`, the variable's initializer is set in `emit`.
582 errors_len_variable: Builder.Variable.Index,
580583
581 /// Values for `@llvm.used`.584 /// Values for `@llvm.used`.
582 used: std.ArrayList(Builder.Constant),585 used: std.ArrayList(Builder.Constant),
...@@ -585,10 +588,11 @@ pub const Object = struct {...@@ -585,10 +588,11 @@ pub const Object = struct {
585588
586 const TypeMap = std.AutoHashMapUnmanaged(InternPool.Index, Builder.Type);589 const TypeMap = std.AutoHashMapUnmanaged(InternPool.Index, Builder.Type);
587590
588 pub fn create(arena: Allocator, comp: *Compilation) !Ptr {591 pub fn create(arena: Allocator, zcu: *Zcu) !Ptr {
589 dev.check(.llvm_backend);592 dev.check(.llvm_backend);
593 const comp = zcu.comp;
590 const gpa = comp.gpa;594 const gpa = comp.gpa;
591 const target = &comp.root_mod.resolved_target.result;595 const target = zcu.getTarget();
592 const llvm_target_triple = try targetTriple(arena, target);596 const llvm_target_triple = try targetTriple(arena, target);
593597
594 var builder = try Builder.init(.{598 var builder = try Builder.init(.{
...@@ -616,10 +620,7 @@ pub const Object = struct {...@@ -616,10 +620,7 @@ pub const Object = struct {
616 // way already, but here we throw all that sweet information620 // way already, but here we throw all that sweet information
617 // into the garbage can by converting into absolute paths. What621 // into the garbage can by converting into absolute paths. What
618 // a terrible tragedy.622 // a terrible tragedy.
619 const compile_unit_dir = blk: {623 const compile_unit_dir = try zcu.main_mod.root.toAbsolute(comp.dirs, arena);
620 const zcu = comp.zcu orelse break :blk comp.dirs.cwd;
621 break :blk try zcu.main_mod.root.toAbsolute(comp.dirs, arena);
622 };
623624
624 const debug_file = try builder.debugFile(625 const debug_file = try builder.debugFile(
625 try builder.metadataString(comp.root_name),626 try builder.metadataString(comp.root_name),
...@@ -665,14 +666,14 @@ pub const Object = struct {...@@ -665,14 +666,14 @@ pub const Object = struct {
665 .debug_file_map = .empty,666 .debug_file_map = .empty,
666 .debug_types = .empty,667 .debug_types = .empty,
667 .debug_anyerror_fwd_ref = .none,668 .debug_anyerror_fwd_ref = .none,
668 .target = target,669 .zcu = zcu,
669 .nav_map = .empty,670 .nav_map = .empty,
670 .uav_map = .empty,671 .uav_map = .empty,
671 .enum_tag_name_map = .empty,672 .enum_tag_name_map = .empty,
672 .named_enum_map = .empty,673 .named_enum_map = .empty,
673 .type_map = .empty,674 .type_map = .empty,
674 .error_name_table = .none,675 .error_name_table = .none,
675 .null_opt_usize = .no_init,676 .errors_len_variable = .none,
676 .used = .empty,677 .used = .empty,
677 };678 };
678 return obj;679 return obj;
...@@ -722,7 +723,7 @@ pub const Object = struct {...@@ -722,7 +723,7 @@ pub const Object = struct {
722 name_variable_index.setLinkage(.private, &o.builder);723 name_variable_index.setLinkage(.private, &o.builder);
723 name_variable_index.setMutability(.constant, &o.builder);724 name_variable_index.setMutability(.constant, &o.builder);
724 name_variable_index.setUnnamedAddr(.unnamed_addr, &o.builder);725 name_variable_index.setUnnamedAddr(.unnamed_addr, &o.builder);
725 name_variable_index.setAlignment(comptime Builder.Alignment.fromByteUnits(1), &o.builder);726 name_variable_index.setAlignment(comptime .fromByteUnits(1), &o.builder);
726727
727 llvm_error.* = try o.builder.structConst(llvm_slice_ty, &.{728 llvm_error.* = try o.builder.structConst(llvm_slice_ty, &.{
728 name_variable_index.toConst(&o.builder),729 name_variable_index.toConst(&o.builder),
...@@ -730,52 +731,17 @@ pub const Object = struct {...@@ -730,52 +731,17 @@ pub const Object = struct {
730 });731 });
731 }732 }
732733
733 const table_variable_index = try o.builder.addVariable(.empty, llvm_table_ty, .default);734 try o.error_name_table.setInitializer(
734 try table_variable_index.setInitializer(
735 try o.builder.arrayConst(llvm_table_ty, llvm_errors),735 try o.builder.arrayConst(llvm_table_ty, llvm_errors),
736 &o.builder,736 &o.builder,
737 );737 );
738 table_variable_index.setLinkage(.private, &o.builder);
739 table_variable_index.setMutability(.constant, &o.builder);
740 table_variable_index.setUnnamedAddr(.unnamed_addr, &o.builder);
741 table_variable_index.setAlignment(
742 slice_ty.abiAlignment(zcu).toLlvm(),
743 &o.builder,
744 );
745
746 try o.error_name_table.setInitializer(table_variable_index.toConst(&o.builder), &o.builder);
747 }
748
749 fn genCmpLtErrorsLenFunction(o: *Object, pt: Zcu.PerThread) !void {
750 // If there is no such function in the module, it means the source code does not need it.
751 const name = o.builder.strtabStringIfExists(lt_errors_fn_name) orelse return;
752 const llvm_fn = o.builder.getGlobal(name) orelse return;
753 const errors_len = pt.zcu.intern_pool.global_error_set.getNamesFromMainThread().len;
754
755 var wip = try Builder.WipFunction.init(&o.builder, .{
756 .function = llvm_fn.ptrConst(&o.builder).kind.function,
757 .strip = true,
758 });
759 defer wip.deinit();
760 wip.cursor = .{ .block = try wip.block(0, "Entry") };
761
762 // Example source of the following LLVM IR:
763 // fn __zig_lt_errors_len(index: u16) bool {
764 // return index <= total_errors_len;
765 // }
766
767 const lhs = wip.arg(0);
768 const rhs = try o.builder.intValue(try o.errorIntType(pt), errors_len);
769 const is_lt = try wip.icmp(.ule, lhs, rhs, "");
770 _ = try wip.ret(is_lt);
771 try wip.finish();
772 }738 }
773739
774 fn genModuleLevelAssembly(object: *Object, pt: Zcu.PerThread) Allocator.Error!void {740 fn genModuleLevelAssembly(object: *Object) Allocator.Error!void {
775 const b = &object.builder;741 const b = &object.builder;
776 const gpa = b.gpa;742 const gpa = b.gpa;
777 b.module_asm.clearRetainingCapacity();743 b.module_asm.clearRetainingCapacity();
778 for (pt.zcu.global_assembly.values()) |assembly| {744 for (object.zcu.global_assembly.values()) |assembly| {
779 try b.module_asm.ensureUnusedCapacity(gpa, assembly.len + 1);745 try b.module_asm.ensureUnusedCapacity(gpa, assembly.len + 1);
780 b.module_asm.appendSliceAssumeCapacity(assembly);746 b.module_asm.appendSliceAssumeCapacity(assembly);
781 b.module_asm.appendAssumeCapacity('\n');747 b.module_asm.appendAssumeCapacity('\n');
...@@ -808,9 +774,13 @@ pub const Object = struct {...@@ -808,9 +774,13 @@ pub const Object = struct {
808 const diags = &comp.link_diags;774 const diags = &comp.link_diags;
809775
810 {776 {
777 if (o.errors_len_variable != .none) {
778 const errors_len = zcu.intern_pool.global_error_set.getNamesFromMainThread().len;
779 const init_val = try o.builder.intConst(try o.errorIntType(), errors_len);
780 try o.errors_len_variable.setInitializer(init_val, &o.builder);
781 }
811 try o.genErrorNameTable(pt);782 try o.genErrorNameTable(pt);
812 try o.genCmpLtErrorsLenFunction(pt);783 try o.genModuleLevelAssembly();
813 try o.genModuleLevelAssembly(pt);
814784
815 if (o.used.items.len > 0) {785 if (o.used.items.len > 0) {
816 const array_llvm_ty = try o.builder.arrayType(o.used.items.len, .ptr);786 const array_llvm_ty = try o.builder.arrayType(o.used.items.len, .ptr);
...@@ -827,7 +797,7 @@ pub const Object = struct {...@@ -827,7 +797,7 @@ pub const Object = struct {
827797
828 if (!o.builder.strip) {798 if (!o.builder.strip) {
829 if (o.debug_anyerror_fwd_ref.unwrap()) |fwd_ref| {799 if (o.debug_anyerror_fwd_ref.unwrap()) |fwd_ref| {
830 const debug_anyerror_type = try o.lowerDebugAnyerrorType(pt);800 const debug_anyerror_type = try o.lowerDebugAnyerrorType();
831 o.builder.resolveDebugForwardReference(fwd_ref, debug_anyerror_type);801 o.builder.resolveDebugForwardReference(fwd_ref, debug_anyerror_type);
832 }802 }
833803
...@@ -1454,7 +1424,7 @@ pub const Object = struct {...@@ -1454,7 +1424,7 @@ pub const Object = struct {
1454 }1424 }
14551425
1456 const file, const subprogram = if (!wip.strip) debug_info: {1426 const file, const subprogram = if (!wip.strip) debug_info: {
1457 const file = try o.getDebugFile(pt, file_scope);1427 const file = try o.getDebugFile(file_scope);
14581428
1459 const line_number = zcu.navSrcLine(func.owner_nav) + 1;1429 const line_number = zcu.navSrcLine(func.owner_nav) + 1;
1460 const is_internal_linkage = ip.indexToKey(nav.resolved.?.value) != .@"extern";1430 const is_internal_linkage = ip.indexToKey(nav.resolved.?.value) != .@"extern";
...@@ -1658,7 +1628,7 @@ pub const Object = struct {...@@ -1658,7 +1628,7 @@ pub const Object = struct {
1658 const line_number = zcu.navSrcLine(nav_index) + 1;1628 const line_number = zcu.navSrcLine(nav_index) + 1;
16591629
1660 if (!mod.strip) {1630 if (!mod.strip) {
1661 const debug_file = try o.getDebugFile(pt, file_scope);1631 const debug_file = try o.getDebugFile(file_scope);
16621632
1663 const debug_global_var = try o.builder.debugGlobalVar(1633 const debug_global_var = try o.builder.debugGlobalVar(
1664 try o.builder.metadataString(nav.name.toSlice(ip)), // Name1634 try o.builder.metadataString(nav.name.toSlice(ip)), // Name
...@@ -1796,7 +1766,7 @@ pub const Object = struct {...@@ -1796,7 +1766,7 @@ pub const Object = struct {
1796 try global_index.rename(main_exp_name, &o.builder);1766 try global_index.rename(main_exp_name, &o.builder);
1797 break :i global_index;1767 break :i global_index;
1798 }1768 }
1799 const llvm_addr_space = toLlvmAddressSpace(.generic, o.target);1769 const llvm_addr_space = toLlvmAddressSpace(.generic, zcu.getTarget());
1800 const variable_index = try o.builder.addVariable(1770 const variable_index = try o.builder.addVariable(
1801 main_exp_name,1771 main_exp_name,
1802 try o.lowerType(pt, Type.fromInterned(ip.typeOf(exported_value))),1772 try o.lowerType(pt, Type.fromInterned(ip.typeOf(exported_value))),
...@@ -2002,13 +1972,13 @@ pub const Object = struct {...@@ -2002,13 +1972,13 @@ pub const Object = struct {
2002 }1972 }
2003 }1973 }
20041974
2005 pub fn getDebugFile(o: *Object, pt: Zcu.PerThread, file_index: Zcu.File.Index) Allocator.Error!Builder.Metadata {1975 pub fn getDebugFile(o: *Object, file_index: Zcu.File.Index) Allocator.Error!Builder.Metadata {
2006 const gpa = o.gpa;1976 const gpa = o.gpa;
2007 const gop = try o.debug_file_map.getOrPut(gpa, file_index);1977 const gop = try o.debug_file_map.getOrPut(gpa, file_index);
2008 errdefer assert(o.debug_file_map.remove(file_index));1978 errdefer assert(o.debug_file_map.remove(file_index));
2009 if (gop.found_existing) return gop.value_ptr.*;1979 if (gop.found_existing) return gop.value_ptr.*;
2010 const path = pt.zcu.fileByIndex(file_index).path;1980 const path = o.zcu.fileByIndex(file_index).path;
2011 const abs_path = try path.toAbsolute(pt.zcu.comp.dirs, gpa);1981 const abs_path = try path.toAbsolute(o.zcu.comp.dirs, gpa);
2012 defer gpa.free(abs_path);1982 defer gpa.free(abs_path);
20131983
2014 gop.value_ptr.* = try o.builder.debugFile(1984 gop.value_ptr.* = try o.builder.debugFile(
...@@ -2035,8 +2005,8 @@ pub const Object = struct {...@@ -2035,8 +2005,8 @@ pub const Object = struct {
2035 assert(!o.builder.strip);2005 assert(!o.builder.strip);
20362006
2037 const gpa = o.gpa;2007 const gpa = o.gpa;
2038 const target = o.target;
2039 const zcu = pt.zcu;2008 const zcu = pt.zcu;
2009 const target = zcu.getTarget();
2040 const ip = &zcu.intern_pool;2010 const ip = &zcu.intern_pool;
20412011
2042 const name = try o.builder.metadataStringFmt("{f}", .{ty.fmt(pt)});2012 const name = try o.builder.metadataStringFmt("{f}", .{ty.fmt(pt)});
...@@ -2386,7 +2356,7 @@ pub const Object = struct {...@@ -2386,7 +2356,7 @@ pub const Object = struct {
23862356
2387 const struct_type = zcu.typeToStruct(ty).?;2357 const struct_type = zcu.typeToStruct(ty).?;
23882358
2389 const file = try o.getDebugFile(pt, struct_type.zir_index.resolveFile(ip));2359 const file = try o.getDebugFile(struct_type.zir_index.resolveFile(ip));
2390 const scope = if (ty.getParentNamespace(zcu).unwrap()) |parent_namespace|2360 const scope = if (ty.getParentNamespace(zcu).unwrap()) |parent_namespace|
2391 try o.namespaceToDebugScope(pt, parent_namespace)2361 try o.namespaceToDebugScope(pt, parent_namespace)
2392 else2362 else
...@@ -2453,7 +2423,7 @@ pub const Object = struct {...@@ -2453,7 +2423,7 @@ pub const Object = struct {
2453 .@"union" => {2423 .@"union" => {
2454 const union_type = ip.loadUnionType(ty.toIntern());2424 const union_type = ip.loadUnionType(ty.toIntern());
24552425
2456 const file = try o.getDebugFile(pt, union_type.zir_index.resolveFile(ip));2426 const file = try o.getDebugFile(union_type.zir_index.resolveFile(ip));
2457 const scope = if (ty.getParentNamespace(zcu).unwrap()) |parent_namespace|2427 const scope = if (ty.getParentNamespace(zcu).unwrap()) |parent_namespace|
2458 try o.namespaceToDebugScope(pt, parent_namespace)2428 try o.namespaceToDebugScope(pt, parent_namespace)
2459 else2429 else
...@@ -2611,7 +2581,7 @@ pub const Object = struct {...@@ -2611,7 +2581,7 @@ pub const Object = struct {
2611 );2581 );
2612 },2582 },
2613 .@"enum" => {2583 .@"enum" => {
2614 const file = try o.getDebugFile(pt, ty.typeDeclInstAllowGeneratedTag(zcu).?.resolveFile(ip));2584 const file = try o.getDebugFile(ty.typeDeclInstAllowGeneratedTag(zcu).?.resolveFile(ip));
2615 const scope = if (ty.getParentNamespace(zcu).unwrap()) |parent_namespace|2585 const scope = if (ty.getParentNamespace(zcu).unwrap()) |parent_namespace|
2616 try o.namespaceToDebugScope(pt, parent_namespace)2586 try o.namespaceToDebugScope(pt, parent_namespace)
2617 else2587 else
...@@ -2672,7 +2642,7 @@ pub const Object = struct {...@@ -2672,7 +2642,7 @@ pub const Object = struct {
2672 return o.builder.debugSignedType(name, 0);2642 return o.builder.debugSignedType(name, 0);
2673 }2643 }
26742644
2675 const file = try o.getDebugFile(pt, ty.typeDeclInstAllowGeneratedTag(zcu).?.resolveFile(ip));2645 const file = try o.getDebugFile(ty.typeDeclInstAllowGeneratedTag(zcu).?.resolveFile(ip));
2676 const scope = if (ty.getParentNamespace(zcu).unwrap()) |parent_namespace|2646 const scope = if (ty.getParentNamespace(zcu).unwrap()) |parent_namespace|
2677 try o.namespaceToDebugScope(pt, parent_namespace)2647 try o.namespaceToDebugScope(pt, parent_namespace)
2678 else2648 else
...@@ -2697,8 +2667,8 @@ pub const Object = struct {...@@ -2697,8 +2667,8 @@ pub const Object = struct {
2697 }2667 }
26982668
2699 /// Called in `emit` so that the global error set is fully populated.2669 /// Called in `emit` so that the global error set is fully populated.
2700 fn lowerDebugAnyerrorType(o: *Object, pt: Zcu.PerThread) Allocator.Error!Builder.Metadata {2670 fn lowerDebugAnyerrorType(o: *Object) Allocator.Error!Builder.Metadata {
2701 const zcu = pt.zcu;2671 const zcu = o.zcu;
2702 const ip = &zcu.intern_pool;2672 const ip = &zcu.intern_pool;
2703 const gpa = zcu.comp.gpa;2673 const gpa = zcu.comp.gpa;
27042674
...@@ -2732,7 +2702,7 @@ pub const Object = struct {...@@ -2732,7 +2702,7 @@ pub const Object = struct {
2732 null, // file2702 null, // file
2733 o.debug_compile_unit.unwrap().?, // scope2703 o.debug_compile_unit.unwrap().?, // scope
2734 0, // line2704 0, // line
2735 try o.getDebugType(pt, try pt.intType(.unsigned, error_set_bits)),2705 try o.builder.debugUnsignedType(null, error_set_bits),
2736 Type.anyerror.abiSize(zcu) * 8,2706 Type.anyerror.abiSize(zcu) * 8,
2737 Type.anyerror.abiAlignment(zcu).toByteUnits().? * 8,2707 Type.anyerror.abiAlignment(zcu).toByteUnits().? * 8,
2738 try o.builder.metadataTuple(enumerators),2708 try o.builder.metadataTuple(enumerators),
...@@ -2744,7 +2714,7 @@ pub const Object = struct {...@@ -2744,7 +2714,7 @@ pub const Object = struct {
2744 fn namespaceToDebugScope(o: *Object, pt: Zcu.PerThread, namespace_index: InternPool.NamespaceIndex) !Builder.Metadata {2714 fn namespaceToDebugScope(o: *Object, pt: Zcu.PerThread, namespace_index: InternPool.NamespaceIndex) !Builder.Metadata {
2745 const zcu = pt.zcu;2715 const zcu = pt.zcu;
2746 const namespace = zcu.namespacePtr(namespace_index);2716 const namespace = zcu.namespacePtr(namespace_index);
2747 if (namespace.parent == .none) return try o.getDebugFile(pt, namespace.file_scope);2717 if (namespace.parent == .none) return try o.getDebugFile(namespace.file_scope);
2748 return o.getDebugType(pt, .fromInterned(namespace.owner_type));2718 return o.getDebugType(pt, .fromInterned(namespace.owner_type));
2749 }2719 }
27502720
...@@ -3086,8 +3056,8 @@ pub const Object = struct {...@@ -3086,8 +3056,8 @@ pub const Object = struct {
3086 return variable_index;3056 return variable_index;
3087 }3057 }
30883058
3089 pub fn errorIntType(o: *Object, pt: Zcu.PerThread) Allocator.Error!Builder.Type {3059 pub fn errorIntType(o: *Object) Allocator.Error!Builder.Type {
3090 return o.builder.intType(pt.zcu.errorSetBits());3060 return o.builder.intType(o.zcu.errorSetBits());
3091 }3061 }
30923062
3093 pub fn lowerType(o: *Object, pt: Zcu.PerThread, t: Type) Allocator.Error!Builder.Type {3063 pub fn lowerType(o: *Object, pt: Zcu.PerThread, t: Type) Allocator.Error!Builder.Type {
...@@ -3146,7 +3116,7 @@ pub const Object = struct {...@@ -3146,7 +3116,7 @@ pub const Object = struct {
3146 .bool_type => .i1,3116 .bool_type => .i1,
3147 .void_type => .void,3117 .void_type => .void,
3148 .type_type => unreachable,3118 .type_type => unreachable,
3149 .anyerror_type => try o.errorIntType(pt),3119 .anyerror_type => try o.errorIntType(),
3150 .comptime_int_type,3120 .comptime_int_type,
3151 .comptime_float_type,3121 .comptime_float_type,
3152 .noreturn_type,3122 .noreturn_type,
...@@ -3168,7 +3138,7 @@ pub const Object = struct {...@@ -3168,7 +3138,7 @@ pub const Object = struct {
3168 .optional_noreturn_type => unreachable,3138 .optional_noreturn_type => unreachable,
3169 .anyerror_void_error_union_type,3139 .anyerror_void_error_union_type,
3170 .adhoc_inferred_error_set_type,3140 .adhoc_inferred_error_set_type,
3171 => try o.errorIntType(pt),3141 => try o.errorIntType(),
3172 .generic_poison_type,3142 .generic_poison_type,
3173 .empty_tuple_type,3143 .empty_tuple_type,
3174 => unreachable,3144 => unreachable,
...@@ -3241,7 +3211,7 @@ pub const Object = struct {...@@ -3241,7 +3211,7 @@ pub const Object = struct {
3241 .error_union_type => |error_union_type| {3211 .error_union_type => |error_union_type| {
3242 // Must stay in sync with `codegen.errUnionPayloadOffset`.3212 // Must stay in sync with `codegen.errUnionPayloadOffset`.
3243 // See logic in `lowerPtr`.3213 // See logic in `lowerPtr`.
3244 const error_type = try o.errorIntType(pt);3214 const error_type = try o.errorIntType();
3245 if (!Type.fromInterned(error_union_type.payload_type).hasRuntimeBits(zcu))3215 if (!Type.fromInterned(error_union_type.payload_type).hasRuntimeBits(zcu))
3246 return error_type;3216 return error_type;
3247 const payload_type = try o.lowerType(pt, Type.fromInterned(error_union_type.payload_type));3217 const payload_type = try o.lowerType(pt, Type.fromInterned(error_union_type.payload_type));
...@@ -3474,7 +3444,7 @@ pub const Object = struct {...@@ -3474,7 +3444,7 @@ pub const Object = struct {
3474 },3444 },
3475 .enum_type => try o.lowerType(pt, t.intTagType(zcu)),3445 .enum_type => try o.lowerType(pt, t.intTagType(zcu)),
3476 .func_type => |func_type| try o.lowerFnType(pt, func_type),3446 .func_type => |func_type| try o.lowerFnType(pt, func_type),
3477 .error_set_type, .inferred_error_set_type => try o.errorIntType(pt),3447 .error_set_type, .inferred_error_set_type => try o.errorIntType(),
3478 // values, not types3448 // values, not types
3479 .undef,3449 .undef,
3480 .simple_value,3450 .simple_value,
...@@ -3624,7 +3594,7 @@ pub const Object = struct {...@@ -3624,7 +3594,7 @@ pub const Object = struct {
3624 },3594 },
3625 .err => |err| {3595 .err => |err| {
3626 const int = try pt.getErrorValue(err.name);3596 const int = try pt.getErrorValue(err.name);
3627 const llvm_int = try o.builder.intConst(try o.errorIntType(pt), int);3597 const llvm_int = try o.builder.intConst(try o.errorIntType(), int);
3628 return llvm_int;3598 return llvm_int;
3629 },3599 },
3630 .error_union => |error_union| {3600 .error_union => |error_union| {
...@@ -4288,29 +4258,40 @@ pub const Object = struct {...@@ -4288,29 +4258,40 @@ pub const Object = struct {
4288 if (byval) try attributes.addParamAttr(llvm_arg_i, .{ .byval = param_llvm_ty }, &o.builder);4258 if (byval) try attributes.addParamAttr(llvm_arg_i, .{ .byval = param_llvm_ty }, &o.builder);
4289 }4259 }
42904260
4291 /// MLUGG TODO: this is super dumb4261 pub fn getErrorNameTable(o: *Object) Allocator.Error!Builder.Variable.Index {
4292 pub fn getCmpLtErrorsLenFunction(o: *Object, pt: Zcu.PerThread) !Builder.Function.Index {4262 if (o.error_name_table != .none) return o.error_name_table;
4293 const name = try o.builder.strtabString(lt_errors_fn_name);
4294 if (o.builder.getGlobal(name)) |llvm_fn| return llvm_fn.ptrConst(&o.builder).kind.function;
42954263
4296 const zcu = pt.zcu;4264 const name = try o.builder.strtabString("__zig_error_name_table");
4297 const target = &zcu.root_mod.resolved_target.result;4265 // TODO: Address space
4298 const function_index = try o.builder.addFunction(4266 const variable_index = try o.builder.addVariable(name, .ptr, .default);
4299 try o.builder.fnType(.i1, &.{try o.errorIntType(pt)}, .normal),4267 variable_index.setLinkage(.private, &o.builder);
4300 name,4268 variable_index.setMutability(.constant, &o.builder);
4301 toLlvmAddressSpace(.generic, target),4269 variable_index.setUnnamedAddr(.unnamed_addr, &o.builder);
4270 variable_index.setAlignment(
4271 Type.slice_const_u8_sentinel_0.abiAlignment(o.zcu).toLlvm(),
4272 &o.builder,
4302 );4273 );
43034274
4304 var attributes: Builder.FunctionAttributes.Wip = .{};4275 o.error_name_table = variable_index;
4305 defer attributes.deinit(&o.builder);4276 return variable_index;
4306 try o.addCommonFnAttributes(&attributes, zcu.root_mod, zcu.root_mod.omit_frame_pointer);4277 }
43074278
4308 function_index.setLinkage(if (o.builder.strip) .private else .internal, &o.builder);4279 pub fn getErrorsLen(o: *Object) Allocator.Error!Builder.Variable.Index {
4309 function_index.setCallConv(.fastcc, &o.builder);4280 const builder = &o.builder;
4310 function_index.setAttributes(try attributes.finish(&o.builder), &o.builder);4281 if (o.errors_len_variable == .none) {
4311 return function_index;4282 const llvm_err_int_ty = try o.errorIntType();
4283 const name = try builder.strtabString("__zig_errors_len");
4284 const variable_index = try builder.addVariable(name, llvm_err_int_ty, .default);
4285 variable_index.setLinkage(.private, builder);
4286 variable_index.setMutability(.constant, builder);
4287 variable_index.setUnnamedAddr(.unnamed_addr, builder);
4288 variable_index.setAlignment(Type.errorAbiAlignment(o.zcu).toLlvm(), builder);
4289 o.errors_len_variable = variable_index;
4290 }
4291 return o.errors_len_variable;
4312 }4292 }
43134293
4294 /// MLUGG TODO: this also needs incremental updates dumbass
4314 pub fn getEnumTagNameFunction(o: *Object, pt: Zcu.PerThread, enum_ty: Type) !Builder.Function.Index {4295 pub fn getEnumTagNameFunction(o: *Object, pt: Zcu.PerThread, enum_ty: Type) !Builder.Function.Index {
4315 const zcu = pt.zcu;4296 const zcu = pt.zcu;
4316 const ip = &zcu.intern_pool;4297 const ip = &zcu.intern_pool;
...@@ -4394,7 +4375,25 @@ pub const Object = struct {...@@ -4394,7 +4375,25 @@ pub const Object = struct {
4394 return o.lazy_abi_aligns.items[@intFromEnum(index)];4375 return o.lazy_abi_aligns.items[@intFromEnum(index)];
4395 }4376 }
43964377
4397 pub fn updateIsNamedEnumValueFunction(4378 pub fn getIsNamedEnumValueFunction(o: *Object, pt: Zcu.PerThread, enum_ty: Type) !Builder.Function.Index {
4379 const zcu = pt.zcu;
4380 const ip = &zcu.intern_pool;
4381
4382 const gop = try o.named_enum_map.getOrPut(o.gpa, enum_ty.toIntern());
4383 if (gop.found_existing) return gop.value_ptr.*;
4384 errdefer assert(o.named_enum_map.remove(enum_ty.toIntern()));
4385 const function_index = try o.builder.addFunction(
4386 // Dummy function type; `updateIsNamedEnumValue` will replace it with the correct type.
4387 // TODO: change the builder API so we don't need to do this.
4388 try o.builder.fnType(.void, &.{}, .normal),
4389 try o.builder.strtabStringFmt("__zig_is_named_enum_value_{f}", .{enum_ty.containerTypeName(ip).fmt(ip)}),
4390 toLlvmAddressSpace(.generic, zcu.getTarget()),
4391 );
4392 gop.value_ptr.* = function_index;
4393 try o.updateIsNamedEnumValueFunction(pt, enum_ty, function_index);
4394 return function_index;
4395 }
4396 fn updateIsNamedEnumValueFunction(
4398 o: *Object,4397 o: *Object,
4399 pt: Zcu.PerThread,4398 pt: Zcu.PerThread,
4400 enum_ty: Type,4399 enum_ty: Type,
...@@ -4445,6 +4444,24 @@ pub const Object = struct {...@@ -4445,6 +4444,24 @@ pub const Object = struct {
44454444
4446 try wip.finish();4445 try wip.finish();
4447 }4446 }
4447
4448 pub fn getLibcFunction(
4449 o: *Object,
4450 fn_name: Builder.StrtabString,
4451 param_types: []const Builder.Type,
4452 return_type: Builder.Type,
4453 ) Allocator.Error!Builder.Function.Index {
4454 if (o.builder.getGlobal(fn_name)) |global| return switch (global.ptrConst(&o.builder).kind) {
4455 .alias => |alias| alias.getAliasee(&o.builder).ptrConst(&o.builder).kind.function,
4456 .function => |function| function,
4457 .variable, .replaced => unreachable,
4458 };
4459 return o.builder.addFunction(
4460 try o.builder.fnType(return_type, param_types, .normal),
4461 fn_name,
4462 toLlvmAddressSpace(.generic, o.zcu.getTarget()),
4463 );
4464 }
4448};4465};
44494466
4450const CallingConventionInfo = struct {4467const CallingConventionInfo = struct {
...@@ -4796,8 +4813,6 @@ const struct_layout_version = 2;...@@ -4796,8 +4813,6 @@ const struct_layout_version = 2;
4796// https://github.com/llvm/llvm-project/issues/56585/ is fixed4813// https://github.com/llvm/llvm-project/issues/56585/ is fixed
4797pub const optional_layout_version = 3;4814pub const optional_layout_version = 3;
47984815
4799const lt_errors_fn_name = "__zig_lt_errors_len";
4800
4801pub fn initializeLLVMTarget(arch: std.Target.Cpu.Arch) void {4816pub fn initializeLLVMTarget(arch: std.Target.Cpu.Arch) void {
4802 switch (arch) {4817 switch (arch) {
4803 .aarch64, .aarch64_be => {4818 .aarch64, .aarch64_be => {
src/codegen/llvm/FuncGen.zig+358-449
...@@ -1,7 +1,5 @@...@@ -1,7 +1,5 @@
1const FuncGen = @This();1const FuncGen = @This();
22
3pub const Error = Zcu.CodegenFailError;
4
5object: *Object,3object: *Object,
6nav_index: InternPool.Nav.Index,4nav_index: InternPool.Nav.Index,
7pt: Zcu.PerThread,5pt: Zcu.PerThread,
...@@ -63,7 +61,17 @@ disable_intrinsics: bool,...@@ -63,7 +61,17 @@ disable_intrinsics: bool,
63/// Have we seen loads or stores involving `allowzero` pointers?61/// Have we seen loads or stores involving `allowzero` pointers?
64allowzero_access: bool,62allowzero_access: bool,
6563
66fn todo(fg: *FuncGen, comptime format: []const u8, args: anytype) Error {64/// In general, codegen should never emit errors; we cannot report useful source locations for them
65/// and they don't really play nicely with incremental compilation. The LLVM backend mostly obeys
66/// this rule. Where it does not, it calls `todo` to emit an error, and results in this error set
67/// being used for the function
68///
69/// Please avoid using this error set in new code. Ideally, every fallible function in this file
70/// should have the error set `Allocator.Error`.
71const TodoError = Zcu.CodegenFailError;
72
73/// Avoid introducing new calls to this function---see documentation comment on `TodoError`.
74fn todo(fg: *FuncGen, comptime format: []const u8, args: anytype) TodoError {
67 @branchHint(.cold);75 @branchHint(.cold);
68 return fg.pt.zcu.codegenFail(76 return fg.pt.zcu.codegenFail(
69 fg.nav_index,77 fg.nav_index,
...@@ -167,7 +175,11 @@ fn resolveValue(self: *FuncGen, val: Value) Allocator.Error!Builder.Constant {...@@ -167,7 +175,11 @@ fn resolveValue(self: *FuncGen, val: Value) Allocator.Error!Builder.Constant {
167 }175 }
168}176}
169177
170pub fn genBody(self: *FuncGen, body: []const Air.Inst.Index, coverage_point: Air.CoveragePoint) Error!void {178fn lowerType(fg: *const FuncGen, ty: Type) Allocator.Error!Builder.Type {
179 return fg.object.lowerType(fg.pt, ty);
180}
181
182pub fn genBody(self: *FuncGen, body: []const Air.Inst.Index, coverage_point: Air.CoveragePoint) TodoError!void {
171 const o = self.object;183 const o = self.object;
172 const zcu = self.pt.zcu;184 const zcu = self.pt.zcu;
173 const ip = &zcu.intern_pool;185 const ip = &zcu.intern_pool;
...@@ -443,13 +455,16 @@ pub fn genBody(self: *FuncGen, body: []const Air.Inst.Index, coverage_point: Air...@@ -443,13 +455,16 @@ pub fn genBody(self: *FuncGen, body: []const Air.Inst.Index, coverage_point: Air
443455
444 // Instructions which may be `noreturn`.456 // Instructions which may be `noreturn`.
445 .block => res: {457 .block => res: {
446 const res = try self.airBlock(inst);458 const block = self.air.unwrapBlock(inst);
447 if (self.typeOfIndex(inst).isNoReturn(zcu)) return;459 const res = try self.lowerBlock(inst, null, block.body);
460 if (block.ty.isNoReturn(zcu)) return;
448 break :res res;461 break :res res;
449 },462 },
450 .dbg_inline_block => res: {463 .dbg_inline_block => res: {
451 const res = try self.airDbgInlineBlock(inst);464 const block = self.air.unwrapDbgBlock(inst);
452 if (self.typeOfIndex(inst).isNoReturn(zcu)) return;465 self.arg_inline_index = 0;
466 const res = try self.lowerBlock(inst, block.func, block.body);
467 if (block.ty.isNoReturn(zcu)) return;
453 break :res res;468 break :res res;
454 },469 },
455 .call, .call_always_tail, .call_never_tail, .call_never_inline => |tag| res: {470 .call, .call_always_tail, .call_never_tail, .call_never_inline => |tag| res: {
...@@ -479,7 +494,7 @@ fn genBodyDebugScope(...@@ -479,7 +494,7 @@ fn genBodyDebugScope(
479 maybe_inline_func: ?InternPool.Index,494 maybe_inline_func: ?InternPool.Index,
480 body: []const Air.Inst.Index,495 body: []const Air.Inst.Index,
481 coverage_point: Air.CoveragePoint,496 coverage_point: Air.CoveragePoint,
482) Error!void {497) TodoError!void {
483 const o = self.object;498 const o = self.object;
484499
485 if (self.wip.strip) return self.genBody(body, coverage_point);500 if (self.wip.strip) return self.genBody(body, coverage_point);
...@@ -508,7 +523,7 @@ fn genBodyDebugScope(...@@ -508,7 +523,7 @@ fn genBodyDebugScope(
508 const file_scope = zcu.navFileScopeIndex(func.owner_nav);523 const file_scope = zcu.navFileScopeIndex(func.owner_nav);
509 const mod = zcu.fileByIndex(file_scope).mod.?;524 const mod = zcu.fileByIndex(file_scope).mod.?;
510525
511 self.file = try o.getDebugFile(pt, file_scope);526 self.file = try o.getDebugFile(file_scope);
512527
513 self.base_line = zcu.navSrcLine(func.owner_nav);528 self.base_line = zcu.navSrcLine(func.owner_nav);
514 const line_number = self.base_line + 1;529 const line_number = self.base_line + 1;
...@@ -562,7 +577,7 @@ const CallAttr = enum {...@@ -562,7 +577,7 @@ const CallAttr = enum {
562 AlwaysInline,577 AlwaysInline,
563};578};
564579
565fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.builtin.CallModifier) !Builder.Value {580fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.builtin.CallModifier) Allocator.Error!Builder.Value {
566 const air_call = self.air.unwrapCall(inst);581 const air_call = self.air.unwrapCall(inst);
567 const args = air_call.args;582 const args = air_call.args;
568 const o = self.object;583 const o = self.object;
...@@ -598,7 +613,7 @@ fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif...@@ -598,7 +613,7 @@ fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif
598 }613 }
599614
600 const ret_ptr = if (!sret) null else blk: {615 const ret_ptr = if (!sret) null else blk: {
601 const llvm_ret_ty = try o.lowerType(pt, return_type);616 const llvm_ret_ty = try self.lowerType(return_type);
602 try attributes.addParamAttr(0, .{ .sret = llvm_ret_ty }, &o.builder);617 try attributes.addParamAttr(0, .{ .sret = llvm_ret_ty }, &o.builder);
603618
604 const alignment = return_type.abiAlignment(zcu).toLlvm();619 const alignment = return_type.abiAlignment(zcu).toLlvm();
...@@ -620,7 +635,7 @@ fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif...@@ -620,7 +635,7 @@ fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif
620 const arg = args[it.zig_index - 1];635 const arg = args[it.zig_index - 1];
621 const param_ty = self.typeOf(arg);636 const param_ty = self.typeOf(arg);
622 const llvm_arg = try self.resolveInst(arg);637 const llvm_arg = try self.resolveInst(arg);
623 const llvm_param_ty = try o.lowerType(pt, param_ty);638 const llvm_param_ty = try self.lowerType(param_ty);
624 if (isByRef(param_ty, zcu)) {639 if (isByRef(param_ty, zcu)) {
625 const alignment = param_ty.abiAlignment(zcu).toLlvm();640 const alignment = param_ty.abiAlignment(zcu).toLlvm();
626 const loaded = try self.wip.load(.normal, llvm_param_ty, llvm_arg, alignment, "");641 const loaded = try self.wip.load(.normal, llvm_param_ty, llvm_arg, alignment, "");
...@@ -649,7 +664,7 @@ fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif...@@ -649,7 +664,7 @@ fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif
649 const llvm_arg = try self.resolveInst(arg);664 const llvm_arg = try self.resolveInst(arg);
650665
651 const alignment = param_ty.abiAlignment(zcu).toLlvm();666 const alignment = param_ty.abiAlignment(zcu).toLlvm();
652 const param_llvm_ty = try o.lowerType(pt, param_ty);667 const param_llvm_ty = try self.lowerType(param_ty);
653 const arg_ptr = try self.buildAlloca(param_llvm_ty, alignment);668 const arg_ptr = try self.buildAlloca(param_llvm_ty, alignment);
654 if (isByRef(param_ty, zcu)) {669 if (isByRef(param_ty, zcu)) {
655 const loaded = try self.wip.load(.normal, param_llvm_ty, llvm_arg, alignment, "");670 const loaded = try self.wip.load(.normal, param_llvm_ty, llvm_arg, alignment, "");
...@@ -719,7 +734,7 @@ fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif...@@ -719,7 +734,7 @@ fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif
719 llvm_arg = ptr;734 llvm_arg = ptr;
720 }735 }
721736
722 const float_ty = try o.lowerType(pt, aarch64_c_abi.getFloatArrayType(arg_ty, zcu).?);737 const float_ty = try self.lowerType(aarch64_c_abi.getFloatArrayType(arg_ty, zcu).?);
723 const array_ty = try o.builder.arrayType(count, float_ty);738 const array_ty = try o.builder.arrayType(count, float_ty);
724739
725 const loaded = try self.wip.load(.normal, array_ty, llvm_arg, alignment, "");740 const loaded = try self.wip.load(.normal, array_ty, llvm_arg, alignment, "");
...@@ -760,7 +775,7 @@ fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif...@@ -760,7 +775,7 @@ fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif
760 .byref => {775 .byref => {
761 const param_index = it.zig_index - 1;776 const param_index = it.zig_index - 1;
762 const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[param_index]);777 const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[param_index]);
763 const param_llvm_ty = try o.lowerType(pt, param_ty);778 const param_llvm_ty = try self.lowerType(param_ty);
764 const alignment = param_ty.abiAlignment(zcu).toLlvm();779 const alignment = param_ty.abiAlignment(zcu).toLlvm();
765 try o.addByRefParamAttrs(&attributes, it.llvm_index - 1, alignment, it.byval_attr, param_llvm_ty);780 try o.addByRefParamAttrs(&attributes, it.llvm_index - 1, alignment, it.byval_attr, param_llvm_ty);
766 },781 },
...@@ -812,7 +827,7 @@ fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif...@@ -812,7 +827,7 @@ fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif
812 },827 },
813 toLlvmCallConvTag(fn_info.cc, target).?,828 toLlvmCallConvTag(fn_info.cc, target).?,
814 try attributes.finish(&o.builder),829 try attributes.finish(&o.builder),
815 try o.lowerType(pt, zig_fn_ty),830 try self.lowerType(zig_fn_ty),
816 llvm_fn,831 llvm_fn,
817 llvm_args.items,832 llvm_args.items,
818 "",833 "",
...@@ -826,7 +841,7 @@ fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif...@@ -826,7 +841,7 @@ fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif
826 return .none;841 return .none;
827 }842 }
828843
829 const llvm_ret_ty = try o.lowerType(pt, return_type);844 const llvm_ret_ty = try self.lowerType(return_type);
830 if (ret_ptr) |rp| {845 if (ret_ptr) |rp| {
831 if (isByRef(return_type, zcu)) {846 if (isByRef(return_type, zcu)) {
832 return rp;847 return rp;
...@@ -864,7 +879,7 @@ fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif...@@ -864,7 +879,7 @@ fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif
864 }879 }
865}880}
866881
867fn buildSimplePanic(fg: *FuncGen, panic_id: Zcu.SimplePanicId) !void {882fn buildSimplePanic(fg: *FuncGen, panic_id: Zcu.SimplePanicId) Allocator.Error!void {
868 const o = fg.object;883 const o = fg.object;
869 const pt = fg.pt;884 const pt = fg.pt;
870 const zcu = pt.zcu;885 const zcu = pt.zcu;
...@@ -888,7 +903,7 @@ fn buildSimplePanic(fg: *FuncGen, panic_id: Zcu.SimplePanicId) !void {...@@ -888,7 +903,7 @@ fn buildSimplePanic(fg: *FuncGen, panic_id: Zcu.SimplePanicId) !void {
888 _ = try fg.wip.@"unreachable"();903 _ = try fg.wip.@"unreachable"();
889}904}
890905
891fn airRet(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !void {906fn airRet(self: *FuncGen, inst: Air.Inst.Index, safety: bool) Allocator.Error!void {
892 const o = self.object;907 const o = self.object;
893 const pt = self.pt;908 const pt = self.pt;
894 const zcu = pt.zcu;909 const zcu = pt.zcu;
...@@ -910,7 +925,7 @@ fn airRet(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !void {...@@ -910,7 +925,7 @@ fn airRet(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !void {
910 // https://github.com/ziglang/zig/issues/15337925 // https://github.com/ziglang/zig/issues/15337
911 break :undef;926 break :undef;
912 }927 }
913 const len = try o.builder.intValue(try o.lowerType(pt, Type.usize), ret_ty.abiSize(zcu));928 const len = try o.builder.intValue(try self.lowerType(.usize), ret_ty.abiSize(zcu));
914 _ = try self.wip.callMemSet(929 _ = try self.wip.callMemSet(
915 self.ret_ptr,930 self.ret_ptr,
916 ptr_ty.ptrAlignment(zcu).toLlvm(),931 ptr_ty.ptrAlignment(zcu).toLlvm(),
...@@ -946,7 +961,7 @@ fn airRet(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !void {...@@ -946,7 +961,7 @@ fn airRet(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !void {
946 // Functions with an empty error set are emitted with an error code961 // Functions with an empty error set are emitted with an error code
947 // return type and return zero so they can be function pointers coerced962 // return type and return zero so they can be function pointers coerced
948 // to functions that return anyerror.963 // to functions that return anyerror.
949 _ = try self.wip.ret(try o.builder.intValue(try o.errorIntType(pt), 0));964 _ = try self.wip.ret(try o.builder.intValue(try o.errorIntType(), 0));
950 } else {965 } else {
951 _ = try self.wip.retVoid();966 _ = try self.wip.retVoid();
952 }967 }
...@@ -961,7 +976,7 @@ fn airRet(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !void {...@@ -961,7 +976,7 @@ fn airRet(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !void {
961 if (val_is_undef and safety) {976 if (val_is_undef and safety) {
962 const llvm_ret_ty = operand.typeOfWip(&self.wip);977 const llvm_ret_ty = operand.typeOfWip(&self.wip);
963 const rp = try self.buildAlloca(llvm_ret_ty, alignment);978 const rp = try self.buildAlloca(llvm_ret_ty, alignment);
964 const len = try o.builder.intValue(try o.lowerType(pt, Type.usize), ret_ty.abiSize(zcu));979 const len = try o.builder.intValue(try self.lowerType(Type.usize), ret_ty.abiSize(zcu));
965 _ = try self.wip.callMemSet(980 _ = try self.wip.callMemSet(
966 rp,981 rp,
967 alignment,982 alignment,
...@@ -997,7 +1012,7 @@ fn airRet(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !void {...@@ -997,7 +1012,7 @@ fn airRet(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !void {
997 return;1012 return;
998}1013}
9991014
1000fn airRetLoad(self: *FuncGen, inst: Air.Inst.Index) !void {1015fn airRetLoad(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!void {
1001 const o = self.object;1016 const o = self.object;
1002 const pt = self.pt;1017 const pt = self.pt;
1003 const zcu = pt.zcu;1018 const zcu = pt.zcu;
...@@ -1011,7 +1026,7 @@ fn airRetLoad(self: *FuncGen, inst: Air.Inst.Index) !void {...@@ -1011,7 +1026,7 @@ fn airRetLoad(self: *FuncGen, inst: Air.Inst.Index) !void {
1011 // Functions with an empty error set are emitted with an error code1026 // Functions with an empty error set are emitted with an error code
1012 // return type and return zero so they can be function pointers coerced1027 // return type and return zero so they can be function pointers coerced
1013 // to functions that return anyerror.1028 // to functions that return anyerror.
1014 _ = try self.wip.ret(try o.builder.intValue(try o.errorIntType(pt), 0));1029 _ = try self.wip.ret(try o.builder.intValue(try o.errorIntType(), 0));
1015 } else {1030 } else {
1016 _ = try self.wip.retVoid();1031 _ = try self.wip.retVoid();
1017 }1032 }
...@@ -1028,25 +1043,22 @@ fn airRetLoad(self: *FuncGen, inst: Air.Inst.Index) !void {...@@ -1028,25 +1043,22 @@ fn airRetLoad(self: *FuncGen, inst: Air.Inst.Index) !void {
1028 return;1043 return;
1029}1044}
10301045
1031fn airCVaArg(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {1046fn airCVaArg(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
1032 const o = self.object;
1033 const pt = self.pt;
1034 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;1047 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
1035 const list = try self.resolveInst(ty_op.operand);1048 const list = try self.resolveInst(ty_op.operand);
1036 const arg_ty = ty_op.ty.toType();1049 const arg_ty = ty_op.ty.toType();
1037 const llvm_arg_ty = try o.lowerType(pt, arg_ty);1050 const llvm_arg_ty = try self.lowerType(arg_ty);
10381051
1039 return self.wip.vaArg(list, llvm_arg_ty, "");1052 return self.wip.vaArg(list, llvm_arg_ty, "");
1040}1053}
10411054
1042fn airCVaCopy(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {1055fn airCVaCopy(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
1043 const o = self.object;
1044 const pt = self.pt;1056 const pt = self.pt;
1045 const zcu = pt.zcu;1057 const zcu = pt.zcu;
1046 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;1058 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
1047 const src_list = try self.resolveInst(ty_op.operand);1059 const src_list = try self.resolveInst(ty_op.operand);
1048 const va_list_ty = ty_op.ty.toType();1060 const va_list_ty = ty_op.ty.toType();
1049 const llvm_va_list_ty = try o.lowerType(pt, va_list_ty);1061 const llvm_va_list_ty = try self.lowerType(va_list_ty);
10501062
1051 const result_alignment = va_list_ty.abiAlignment(pt.zcu).toLlvm();1063 const result_alignment = va_list_ty.abiAlignment(pt.zcu).toLlvm();
1052 const dest_list = try self.buildAlloca(llvm_va_list_ty, result_alignment);1064 const dest_list = try self.buildAlloca(llvm_va_list_ty, result_alignment);
...@@ -1058,7 +1070,7 @@ fn airCVaCopy(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -1058,7 +1070,7 @@ fn airCVaCopy(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
1058 try self.wip.load(.normal, llvm_va_list_ty, dest_list, result_alignment, "");1070 try self.wip.load(.normal, llvm_va_list_ty, dest_list, result_alignment, "");
1059}1071}
10601072
1061fn airCVaEnd(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {1073fn airCVaEnd(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
1062 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;1074 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
1063 const src_list = try self.resolveInst(un_op);1075 const src_list = try self.resolveInst(un_op);
10641076
...@@ -1066,12 +1078,11 @@ fn airCVaEnd(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -1066,12 +1078,11 @@ fn airCVaEnd(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
1066 return .none;1078 return .none;
1067}1079}
10681080
1069fn airCVaStart(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {1081fn airCVaStart(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
1070 const o = self.object;
1071 const pt = self.pt;1082 const pt = self.pt;
1072 const zcu = pt.zcu;1083 const zcu = pt.zcu;
1073 const va_list_ty = self.typeOfIndex(inst);1084 const va_list_ty = self.typeOfIndex(inst);
1074 const llvm_va_list_ty = try o.lowerType(pt, va_list_ty);1085 const llvm_va_list_ty = try self.lowerType(va_list_ty);
10751086
1076 const result_alignment = va_list_ty.abiAlignment(pt.zcu).toLlvm();1087 const result_alignment = va_list_ty.abiAlignment(pt.zcu).toLlvm();
1077 const dest_list = try self.buildAlloca(llvm_va_list_ty, result_alignment);1088 const dest_list = try self.buildAlloca(llvm_va_list_ty, result_alignment);
...@@ -1088,7 +1099,7 @@ fn airCmp(...@@ -1088,7 +1099,7 @@ fn airCmp(
1088 inst: Air.Inst.Index,1099 inst: Air.Inst.Index,
1089 op: math.CompareOperator,1100 op: math.CompareOperator,
1090 fast: Builder.FastMathKind,1101 fast: Builder.FastMathKind,
1091) !Builder.Value {1102) Allocator.Error!Builder.Value {
1092 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;1103 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
1093 const lhs = try self.resolveInst(bin_op.lhs);1104 const lhs = try self.resolveInst(bin_op.lhs);
1094 const rhs = try self.resolveInst(bin_op.rhs);1105 const rhs = try self.resolveInst(bin_op.rhs);
...@@ -1097,7 +1108,7 @@ fn airCmp(...@@ -1097,7 +1108,7 @@ fn airCmp(
1097 return self.cmp(fast, op, operand_ty, lhs, rhs);1108 return self.cmp(fast, op, operand_ty, lhs, rhs);
1098}1109}
10991110
1100fn airCmpVector(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value {1111fn airCmpVector(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) Allocator.Error!Builder.Value {
1101 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;1112 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
1102 const extra = self.air.extraData(Air.VectorCmp, ty_pl.payload).data;1113 const extra = self.air.extraData(Air.VectorCmp, ty_pl.payload).data;
11031114
...@@ -1109,21 +1120,20 @@ fn airCmpVector(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind...@@ -1109,21 +1120,20 @@ fn airCmpVector(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind
1109 return self.cmp(fast, cmp_op, vec_ty, lhs, rhs);1120 return self.cmp(fast, cmp_op, vec_ty, lhs, rhs);
1110}1121}
11111122
1112fn airCmpLtErrorsLen(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {1123fn airCmpLtErrorsLen(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
1113 const o = self.object;1124 const o = self.object;
1114 const pt = self.pt;
1115 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;1125 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
1116 const operand = try self.resolveInst(un_op);1126 const operand = try self.resolveInst(un_op);
1117 const llvm_fn = try o.getCmpLtErrorsLenFunction(pt);1127 const errors_len_ptr = try o.getErrorsLen();
1118 return self.wip.call(1128 const errors_len_val = try self.wip.load(
1119 .normal,1129 .normal,
1120 .fastcc,1130 try o.errorIntType(),
1121 .none,1131 errors_len_ptr.toValue(&o.builder),
1122 llvm_fn.typeOf(&o.builder),1132 Type.errorAbiAlignment(o.zcu).toLlvm(),
1123 llvm_fn.toValue(&o.builder),
1124 &.{operand},
1125 "",1133 "",
1126 );1134 );
1135 // Despite the name, this instruction is actually lte. MLUGG TODO RENAME
1136 return self.wip.icmp(.ule, operand, errors_len_val, "");
1127}1137}
11281138
1129fn cmp(1139fn cmp(
...@@ -1228,18 +1238,12 @@ fn cmp(...@@ -1228,18 +1238,12 @@ fn cmp(
1228 return self.wip.icmp(cond, lhs, rhs, "");1238 return self.wip.icmp(cond, lhs, rhs, "");
1229}1239}
12301240
1231fn airBlock(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
1232 const block = self.air.unwrapBlock(inst);
1233 return self.lowerBlock(inst, null, block.body);
1234}
1235
1236fn lowerBlock(1241fn lowerBlock(
1237 self: *FuncGen,1242 self: *FuncGen,
1238 inst: Air.Inst.Index,1243 inst: Air.Inst.Index,
1239 maybe_inline_func: ?InternPool.Index,1244 maybe_inline_func: ?InternPool.Index,
1240 body: []const Air.Inst.Index,1245 body: []const Air.Inst.Index,
1241) !Builder.Value {1246) TodoError!Builder.Value {
1242 const o = self.object;
1243 const pt = self.pt;1247 const pt = self.pt;
1244 const zcu = pt.zcu;1248 const zcu = pt.zcu;
1245 const inst_ty = self.typeOfIndex(inst);1249 const inst_ty = self.typeOfIndex(inst);
...@@ -1267,7 +1271,7 @@ fn lowerBlock(...@@ -1267,7 +1271,7 @@ fn lowerBlock(
12671271
1268 // Create a phi node only if the block returns a value.1272 // Create a phi node only if the block returns a value.
1269 if (have_block_result) {1273 if (have_block_result) {
1270 const raw_llvm_ty = try o.lowerType(pt, inst_ty);1274 const raw_llvm_ty = try self.lowerType(inst_ty);
1271 const llvm_ty: Builder.Type = ty: {1275 const llvm_ty: Builder.Type = ty: {
1272 // If the zig tag type is a function, this represents an actual function body; not1276 // If the zig tag type is a function, this represents an actual function body; not
1273 // a pointer to it. LLVM IR allows the call instruction to use function bodies instead1277 // a pointer to it. LLVM IR allows the call instruction to use function bodies instead
...@@ -1289,7 +1293,7 @@ fn lowerBlock(...@@ -1289,7 +1293,7 @@ fn lowerBlock(
1289 }1293 }
1290}1294}
12911295
1292fn airBr(self: *FuncGen, inst: Air.Inst.Index) !void {1296fn airBr(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!void {
1293 const zcu = self.pt.zcu;1297 const zcu = self.pt.zcu;
1294 const branch = self.air.instructions.items(.data)[@intFromEnum(inst)].br;1298 const branch = self.air.instructions.items(.data)[@intFromEnum(inst)].br;
1295 const block = self.blocks.get(branch.block_inst).?;1299 const block = self.blocks.get(branch.block_inst).?;
...@@ -1306,7 +1310,7 @@ fn airBr(self: *FuncGen, inst: Air.Inst.Index) !void {...@@ -1306,7 +1310,7 @@ fn airBr(self: *FuncGen, inst: Air.Inst.Index) !void {
1306 _ = try self.wip.br(block.parent_bb);1310 _ = try self.wip.br(block.parent_bb);
1307}1311}
13081312
1309fn airRepeat(self: *FuncGen, inst: Air.Inst.Index) !void {1313fn airRepeat(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!void {
1310 const repeat = self.air.instructions.items(.data)[@intFromEnum(inst)].repeat;1314 const repeat = self.air.instructions.items(.data)[@intFromEnum(inst)].repeat;
1311 const loop_bb = self.loops.get(repeat.loop_inst).?;1315 const loop_bb = self.loops.get(repeat.loop_inst).?;
1312 loop_bb.ptr(&self.wip).incoming += 1;1316 loop_bb.ptr(&self.wip).incoming += 1;
...@@ -1318,7 +1322,7 @@ fn lowerSwitchDispatch(...@@ -1318,7 +1322,7 @@ fn lowerSwitchDispatch(
1318 switch_inst: Air.Inst.Index,1322 switch_inst: Air.Inst.Index,
1319 cond_ref: Air.Inst.Ref,1323 cond_ref: Air.Inst.Ref,
1320 dispatch_info: SwitchDispatchInfo,1324 dispatch_info: SwitchDispatchInfo,
1321) !void {1325) Allocator.Error!void {
1322 const o = self.object;1326 const o = self.object;
1323 const pt = self.pt;1327 const pt = self.pt;
1324 const zcu = pt.zcu;1328 const zcu = pt.zcu;
...@@ -1384,7 +1388,7 @@ fn lowerSwitchDispatch(...@@ -1384,7 +1388,7 @@ fn lowerSwitchDispatch(
1384 const table_index = try self.wip.conv(1388 const table_index = try self.wip.conv(
1385 .unsigned,1389 .unsigned,
1386 try self.wip.bin(.@"sub nuw", cond, jmp_table.min.toValue(), ""),1390 try self.wip.bin(.@"sub nuw", cond, jmp_table.min.toValue(), ""),
1387 try o.lowerType(pt, .usize),1391 try self.lowerType(.usize),
1388 "",1392 "",
1389 );1393 );
1390 const target_ptr_ptr = try self.ptraddScaled(1394 const target_ptr_ptr = try self.ptraddScaled(
...@@ -1409,7 +1413,7 @@ fn lowerSwitchDispatch(...@@ -1409,7 +1413,7 @@ fn lowerSwitchDispatch(
1409 // The switch prongs will correspond to our scalar cases. Ranges will1413 // The switch prongs will correspond to our scalar cases. Ranges will
1410 // be handled by conditional branches in the `else` prong.1414 // be handled by conditional branches in the `else` prong.
14111415
1412 const llvm_usize = try o.lowerType(pt, Type.usize);1416 const llvm_usize = try self.lowerType(Type.usize);
1413 const cond_int = if (cond.typeOfWip(&self.wip).isPointer(&o.builder))1417 const cond_int = if (cond.typeOfWip(&self.wip).isPointer(&o.builder))
1414 try self.wip.cast(.ptrtoint, cond, llvm_usize, "")1418 try self.wip.cast(.ptrtoint, cond, llvm_usize, "")
1415 else1419 else
...@@ -1501,13 +1505,13 @@ fn lowerSwitchDispatch(...@@ -1501,13 +1505,13 @@ fn lowerSwitchDispatch(
1501 }1505 }
1502}1506}
15031507
1504fn airSwitchDispatch(self: *FuncGen, inst: Air.Inst.Index) !void {1508fn airSwitchDispatch(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!void {
1505 const br = self.air.instructions.items(.data)[@intFromEnum(inst)].br;1509 const br = self.air.instructions.items(.data)[@intFromEnum(inst)].br;
1506 const dispatch_info = self.switch_dispatch_info.get(br.block_inst).?;1510 const dispatch_info = self.switch_dispatch_info.get(br.block_inst).?;
1507 return self.lowerSwitchDispatch(br.block_inst, br.operand, dispatch_info);1511 return self.lowerSwitchDispatch(br.block_inst, br.operand, dispatch_info);
1508}1512}
15091513
1510fn airCondBr(self: *FuncGen, inst: Air.Inst.Index) !void {1514fn airCondBr(self: *FuncGen, inst: Air.Inst.Index) TodoError!void {
1511 const cond_br = self.air.unwrapCondBr(inst);1515 const cond_br = self.air.unwrapCondBr(inst);
1512 const cond = try self.resolveInst(cond_br.condition);1516 const cond = try self.resolveInst(cond_br.condition);
1513 const then_body = cond_br.then_body;1517 const then_body = cond_br.then_body;
...@@ -1567,7 +1571,7 @@ fn airCondBr(self: *FuncGen, inst: Air.Inst.Index) !void {...@@ -1567,7 +1571,7 @@ fn airCondBr(self: *FuncGen, inst: Air.Inst.Index) !void {
1567 // No need to reset the insert cursor since this instruction is noreturn.1571 // No need to reset the insert cursor since this instruction is noreturn.
1568}1572}
15691573
1570fn airTry(self: *FuncGen, inst: Air.Inst.Index, err_cold: bool) !Builder.Value {1574fn airTry(self: *FuncGen, inst: Air.Inst.Index, err_cold: bool) TodoError!Builder.Value {
1571 const unwrapped_try = self.air.unwrapTry(inst);1575 const unwrapped_try = self.air.unwrapTry(inst);
1572 const err_union = try self.resolveInst(unwrapped_try.error_union);1576 const err_union = try self.resolveInst(unwrapped_try.error_union);
1573 const body = unwrapped_try.else_body;1577 const body = unwrapped_try.else_body;
...@@ -1576,7 +1580,7 @@ fn airTry(self: *FuncGen, inst: Air.Inst.Index, err_cold: bool) !Builder.Value {...@@ -1576,7 +1580,7 @@ fn airTry(self: *FuncGen, inst: Air.Inst.Index, err_cold: bool) !Builder.Value {
1576 return lowerTry(self, err_union, body, err_union_ty, false, .none, is_unused, err_cold);1580 return lowerTry(self, err_union, body, err_union_ty, false, .none, is_unused, err_cold);
1577}1581}
15781582
1579fn airTryPtr(self: *FuncGen, inst: Air.Inst.Index, err_cold: bool) !Builder.Value {1583fn airTryPtr(self: *FuncGen, inst: Air.Inst.Index, err_cold: bool) TodoError!Builder.Value {
1580 const zcu = self.pt.zcu;1584 const zcu = self.pt.zcu;
1581 const unwrapped_try = self.air.unwrapTryPtr(inst);1585 const unwrapped_try = self.air.unwrapTryPtr(inst);
1582 const err_union_ptr = try self.resolveInst(unwrapped_try.error_union_ptr);1586 const err_union_ptr = try self.resolveInst(unwrapped_try.error_union_ptr);
...@@ -1599,13 +1603,13 @@ fn lowerTry(...@@ -1599,13 +1603,13 @@ fn lowerTry(
1599 operand_ptr_align: InternPool.Alignment,1603 operand_ptr_align: InternPool.Alignment,
1600 is_unused: bool,1604 is_unused: bool,
1601 err_cold: bool,1605 err_cold: bool,
1602) !Builder.Value {1606) TodoError!Builder.Value {
1603 const o = fg.object;1607 const o = fg.object;
1604 const pt = fg.pt;1608 const pt = fg.pt;
1605 const zcu = pt.zcu;1609 const zcu = pt.zcu;
1606 const payload_ty = err_union_ty.errorUnionPayload(zcu);1610 const payload_ty = err_union_ty.errorUnionPayload(zcu);
1607 const payload_has_bits = payload_ty.hasRuntimeBits(zcu);1611 const payload_has_bits = payload_ty.hasRuntimeBits(zcu);
1608 const error_type = try o.errorIntType(pt);1612 const error_type = try o.errorIntType();
16091613
1610 const err_set_align: InternPool.Alignment, const payload_align: InternPool.Alignment = if (operand_is_ptr) .{1614 const err_set_align: InternPool.Alignment, const payload_align: InternPool.Alignment = if (operand_is_ptr) .{
1611 operand_ptr_align.minStrict(Type.anyerror.abiAlignment(zcu)),1615 operand_ptr_align.minStrict(Type.anyerror.abiAlignment(zcu)),
...@@ -1657,11 +1661,11 @@ fn lowerTry(...@@ -1657,11 +1661,11 @@ fn lowerTry(
1657 } else if (isByRef(payload_ty, zcu)) {1661 } else if (isByRef(payload_ty, zcu)) {
1658 return fg.loadByRef(payload_ptr, payload_ty, payload_align.toLlvm(), .normal);1662 return fg.loadByRef(payload_ptr, payload_ty, payload_align.toLlvm(), .normal);
1659 } else {1663 } else {
1660 return fg.wip.load(.normal, try o.lowerType(pt, payload_ty), payload_ptr, payload_align.toLlvm(), "");1664 return fg.wip.load(.normal, try fg.lowerType(payload_ty), payload_ptr, payload_align.toLlvm(), "");
1661 }1665 }
1662}1666}
16631667
1664fn airSwitchBr(self: *FuncGen, inst: Air.Inst.Index, is_dispatch_loop: bool) !void {1668fn airSwitchBr(self: *FuncGen, inst: Air.Inst.Index, is_dispatch_loop: bool) TodoError!void {
1665 const o = self.object;1669 const o = self.object;
1666 const pt = self.pt;1670 const pt = self.pt;
1667 const zcu = pt.zcu;1671 const zcu = pt.zcu;
...@@ -1909,7 +1913,7 @@ fn switchCaseItemRange(self: *FuncGen, switch_br: Air.UnwrappedSwitch) ?[2]Value...@@ -1909,7 +1913,7 @@ fn switchCaseItemRange(self: *FuncGen, switch_br: Air.UnwrappedSwitch) ?[2]Value
1909 return .{ min.?, max.? };1913 return .{ min.?, max.? };
1910}1914}
19111915
1912fn airLoop(self: *FuncGen, inst: Air.Inst.Index) !void {1916fn airLoop(self: *FuncGen, inst: Air.Inst.Index) TodoError!void {
1913 const block = self.air.unwrapBlock(inst);1917 const block = self.air.unwrapBlock(inst);
1914 const body = block.body;1918 const body = block.body;
1915 const loop_block = try self.wip.block(1, "Loop"); // `airRepeat` will increment incoming each time1919 const loop_block = try self.wip.block(1, "Loop"); // `airRepeat` will increment incoming each time
...@@ -1922,21 +1926,21 @@ fn airLoop(self: *FuncGen, inst: Air.Inst.Index) !void {...@@ -1922,21 +1926,21 @@ fn airLoop(self: *FuncGen, inst: Air.Inst.Index) !void {
1922 try self.genBodyDebugScope(null, body, .none);1926 try self.genBodyDebugScope(null, body, .none);
1923}1927}
19241928
1925fn airArrayToSlice(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {1929fn airArrayToSlice(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
1926 const o = self.object;1930 const o = self.object;
1927 const pt = self.pt;1931 const pt = self.pt;
1928 const zcu = pt.zcu;1932 const zcu = pt.zcu;
1929 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;1933 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
1930 const operand_ty = self.typeOf(ty_op.operand);1934 const operand_ty = self.typeOf(ty_op.operand);
1931 const array_ty = operand_ty.childType(zcu);1935 const array_ty = operand_ty.childType(zcu);
1932 const llvm_usize = try o.lowerType(pt, Type.usize);1936 const llvm_usize = try self.lowerType(.usize);
1933 const len = try o.builder.intValue(llvm_usize, array_ty.arrayLen(zcu));1937 const len = try o.builder.intValue(llvm_usize, array_ty.arrayLen(zcu));
1934 const slice_llvm_ty = try o.lowerType(pt, self.typeOfIndex(inst));1938 const slice_llvm_ty = try self.lowerType(self.typeOfIndex(inst));
1935 const operand = try self.resolveInst(ty_op.operand);1939 const operand = try self.resolveInst(ty_op.operand);
1936 return self.wip.buildAggregate(slice_llvm_ty, &.{ operand, len }, "");1940 return self.wip.buildAggregate(slice_llvm_ty, &.{ operand, len }, "");
1937}1941}
19381942
1939fn airFloatFromInt(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {1943fn airFloatFromInt(self: *FuncGen, inst: Air.Inst.Index) TodoError!Builder.Value {
1940 const o = self.object;1944 const o = self.object;
1941 const pt = self.pt;1945 const pt = self.pt;
1942 const zcu = pt.zcu;1946 const zcu = pt.zcu;
...@@ -1949,7 +1953,7 @@ fn airFloatFromInt(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -1949,7 +1953,7 @@ fn airFloatFromInt(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
19491953
1950 const dest_ty = self.typeOfIndex(inst);1954 const dest_ty = self.typeOfIndex(inst);
1951 const dest_scalar_ty = dest_ty.scalarType(zcu);1955 const dest_scalar_ty = dest_ty.scalarType(zcu);
1952 const dest_llvm_ty = try o.lowerType(pt, dest_ty);1956 const dest_llvm_ty = try self.lowerType(dest_ty);
1953 const target = zcu.getTarget();1957 const target = zcu.getTarget();
19541958
1955 if (intrinsicsAllowed(dest_scalar_ty, target)) return self.wip.conv(1959 if (intrinsicsAllowed(dest_scalar_ty, target)) return self.wip.conv(
...@@ -1987,7 +1991,7 @@ fn airFloatFromInt(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -1987,7 +1991,7 @@ fn airFloatFromInt(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
1987 extended = try self.wip.cast(.bitcast, extended, param_type, "");1991 extended = try self.wip.cast(.bitcast, extended, param_type, "");
1988 }1992 }
19891993
1990 const libc_fn = try self.getLibcFunction(fn_name, &.{param_type}, dest_llvm_ty);1994 const libc_fn = try o.getLibcFunction(fn_name, &.{param_type}, dest_llvm_ty);
1991 return self.wip.call(1995 return self.wip.call(
1992 .normal,1996 .normal,
1993 .ccc,1997 .ccc,
...@@ -2003,7 +2007,7 @@ fn airIntFromFloat(...@@ -2003,7 +2007,7 @@ fn airIntFromFloat(
2003 self: *FuncGen,2007 self: *FuncGen,
2004 inst: Air.Inst.Index,2008 inst: Air.Inst.Index,
2005 fast: Builder.FastMathKind,2009 fast: Builder.FastMathKind,
2006) !Builder.Value {2010) TodoError!Builder.Value {
2007 _ = fast;2011 _ = fast;
20082012
2009 const o = self.object;2013 const o = self.object;
...@@ -2018,7 +2022,7 @@ fn airIntFromFloat(...@@ -2018,7 +2022,7 @@ fn airIntFromFloat(
20182022
2019 const dest_ty = self.typeOfIndex(inst);2023 const dest_ty = self.typeOfIndex(inst);
2020 const dest_scalar_ty = dest_ty.scalarType(zcu);2024 const dest_scalar_ty = dest_ty.scalarType(zcu);
2021 const dest_llvm_ty = try o.lowerType(pt, dest_ty);2025 const dest_llvm_ty = try self.lowerType(dest_ty);
20222026
2023 if (intrinsicsAllowed(operand_scalar_ty, target)) {2027 if (intrinsicsAllowed(operand_scalar_ty, target)) {
2024 // TODO set fast math flag2028 // TODO set fast math flag
...@@ -2052,8 +2056,8 @@ fn airIntFromFloat(...@@ -2052,8 +2056,8 @@ fn airIntFromFloat(
2052 compiler_rt_dest_abbrev,2056 compiler_rt_dest_abbrev,
2053 });2057 });
20542058
2055 const operand_llvm_ty = try o.lowerType(pt, operand_ty);2059 const operand_llvm_ty = try self.lowerType(operand_ty);
2056 const libc_fn = try self.getLibcFunction(fn_name, &.{operand_llvm_ty}, libc_ret_ty);2060 const libc_fn = try o.getLibcFunction(fn_name, &.{operand_llvm_ty}, libc_ret_ty);
2057 var result = try self.wip.call(2061 var result = try self.wip.call(
2058 .normal,2062 .normal,
2059 .ccc,2063 .ccc,
...@@ -2078,7 +2082,7 @@ fn sliceOrArrayLenInBytes(fg: *FuncGen, ptr: Builder.Value, ty: Type) Allocator....@@ -2078,7 +2082,7 @@ fn sliceOrArrayLenInBytes(fg: *FuncGen, ptr: Builder.Value, ty: Type) Allocator.
2078 const o = fg.object;2082 const o = fg.object;
2079 const pt = fg.pt;2083 const pt = fg.pt;
2080 const zcu = pt.zcu;2084 const zcu = pt.zcu;
2081 const llvm_usize = try o.lowerType(pt, Type.usize);2085 const llvm_usize = try fg.lowerType(.usize);
2082 switch (ty.ptrSize(zcu)) {2086 switch (ty.ptrSize(zcu)) {
2083 .slice => {2087 .slice => {
2084 const len = try fg.wip.extractValue(ptr, &.{1}, "");2088 const len = try fg.wip.extractValue(ptr, &.{1}, "");
...@@ -2098,20 +2102,20 @@ fn sliceOrArrayLenInBytes(fg: *FuncGen, ptr: Builder.Value, ty: Type) Allocator....@@ -2098,20 +2102,20 @@ fn sliceOrArrayLenInBytes(fg: *FuncGen, ptr: Builder.Value, ty: Type) Allocator.
2098 }2102 }
2099}2103}
21002104
2101fn airSliceField(self: *FuncGen, inst: Air.Inst.Index, index: u32) !Builder.Value {2105fn airSliceField(self: *FuncGen, inst: Air.Inst.Index, index: u32) Allocator.Error!Builder.Value {
2102 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;2106 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
2103 const operand = try self.resolveInst(ty_op.operand);2107 const operand = try self.resolveInst(ty_op.operand);
2104 return self.wip.extractValue(operand, &.{index}, "");2108 return self.wip.extractValue(operand, &.{index}, "");
2105}2109}
21062110
2107fn airPtrSliceFieldPtr(self: *FuncGen, inst: Air.Inst.Index, index: u1) !Builder.Value {2111fn airPtrSliceFieldPtr(self: *FuncGen, inst: Air.Inst.Index, index: u1) Allocator.Error!Builder.Value {
2108 const zcu = self.pt.zcu;2112 const zcu = self.pt.zcu;
2109 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;2113 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
2110 const slice_ptr = try self.resolveInst(ty_op.operand);2114 const slice_ptr = try self.resolveInst(ty_op.operand);
2111 return self.ptraddConst(slice_ptr, index * Type.usize.abiSize(zcu));2115 return self.ptraddConst(slice_ptr, index * Type.usize.abiSize(zcu));
2112}2116}
21132117
2114fn airSliceElemVal(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {2118fn airSliceElemVal(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
2115 const pt = self.pt;2119 const pt = self.pt;
2116 const zcu = pt.zcu;2120 const zcu = pt.zcu;
2117 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;2121 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
...@@ -2133,7 +2137,7 @@ fn airSliceElemVal(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -2133,7 +2137,7 @@ fn airSliceElemVal(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
2133 }2137 }
2134}2138}
21352139
2136fn airSliceElemPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {2140fn airSliceElemPtr(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
2137 const pt = self.pt;2141 const pt = self.pt;
2138 const zcu = pt.zcu;2142 const zcu = pt.zcu;
2139 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;2143 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
...@@ -2146,7 +2150,7 @@ fn airSliceElemPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -2146,7 +2150,7 @@ fn airSliceElemPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
2146 return self.ptraddScaled(base_ptr, index, slice_ty.childType(zcu).abiSize(zcu));2150 return self.ptraddScaled(base_ptr, index, slice_ty.childType(zcu).abiSize(zcu));
2147}2151}
21482152
2149fn airArrayElemVal(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {2153fn airArrayElemVal(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
2150 const pt = self.pt;2154 const pt = self.pt;
2151 const zcu = pt.zcu;2155 const zcu = pt.zcu;
21522156
...@@ -2169,7 +2173,7 @@ fn airArrayElemVal(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -2169,7 +2173,7 @@ fn airArrayElemVal(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
2169 return self.wip.extractElement(array_llvm_val, rhs, "");2173 return self.wip.extractElement(array_llvm_val, rhs, "");
2170}2174}
21712175
2172fn airPtrElemVal(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {2176fn airPtrElemVal(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
2173 const pt = self.pt;2177 const pt = self.pt;
2174 const zcu = pt.zcu;2178 const zcu = pt.zcu;
2175 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;2179 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
...@@ -2189,7 +2193,7 @@ fn airPtrElemVal(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -2189,7 +2193,7 @@ fn airPtrElemVal(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
2189 return self.load(ptr, ptr_ty);2193 return self.load(ptr, ptr_ty);
2190}2194}
21912195
2192fn airPtrElemPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {2196fn airPtrElemPtr(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
2193 const pt = self.pt;2197 const pt = self.pt;
2194 const zcu = pt.zcu;2198 const zcu = pt.zcu;
2195 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;2199 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
...@@ -2207,7 +2211,7 @@ fn airPtrElemPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -2207,7 +2211,7 @@ fn airPtrElemPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
2207 return self.ptraddScaled(base_ptr, rhs, elem_ty.abiSize(zcu));2211 return self.ptraddScaled(base_ptr, rhs, elem_ty.abiSize(zcu));
2208}2212}
22092213
2210fn airStructFieldPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {2214fn airStructFieldPtr(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
2211 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;2215 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
2212 const struct_field = self.air.extraData(Air.StructField, ty_pl.payload).data;2216 const struct_field = self.air.extraData(Air.StructField, ty_pl.payload).data;
2213 const struct_ptr = try self.resolveInst(struct_field.struct_operand);2217 const struct_ptr = try self.resolveInst(struct_field.struct_operand);
...@@ -2219,14 +2223,14 @@ fn airStructFieldPtrIndex(...@@ -2219,14 +2223,14 @@ fn airStructFieldPtrIndex(
2219 self: *FuncGen,2223 self: *FuncGen,
2220 inst: Air.Inst.Index,2224 inst: Air.Inst.Index,
2221 field_index: u32,2225 field_index: u32,
2222) !Builder.Value {2226) Allocator.Error!Builder.Value {
2223 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;2227 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
2224 const struct_ptr = try self.resolveInst(ty_op.operand);2228 const struct_ptr = try self.resolveInst(ty_op.operand);
2225 const struct_ptr_ty = self.typeOf(ty_op.operand);2229 const struct_ptr_ty = self.typeOf(ty_op.operand);
2226 return self.fieldPtr(struct_ptr, struct_ptr_ty, field_index);2230 return self.fieldPtr(struct_ptr, struct_ptr_ty, field_index);
2227}2231}
22282232
2229fn airStructFieldVal(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {2233fn airStructFieldVal(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
2230 const o = self.object;2234 const o = self.object;
2231 const pt = self.pt;2235 const pt = self.pt;
2232 const zcu = pt.zcu;2236 const zcu = pt.zcu;
...@@ -2267,7 +2271,7 @@ fn airStructFieldVal(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -2267,7 +2271,7 @@ fn airStructFieldVal(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
2267 },2271 },
2268 .float => {2272 .float => {
2269 // bitcast int->float2273 // bitcast int->float
2270 return self.wip.cast(.bitcast, field_int_val, try o.lowerType(pt, field_ty), "");2274 return self.wip.cast(.bitcast, field_int_val, try self.lowerType(field_ty), "");
2271 },2275 },
2272 }2276 }
2273 }2277 }
...@@ -2292,7 +2296,7 @@ fn airStructFieldVal(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -2292,7 +2296,7 @@ fn airStructFieldVal(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
2292 }2296 }
2293}2297}
22942298
2295fn airFieldParentPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {2299fn airFieldParentPtr(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
2296 const o = self.object;2300 const o = self.object;
2297 const pt = self.pt;2301 const pt = self.pt;
2298 const zcu = pt.zcu;2302 const zcu = pt.zcu;
...@@ -2305,8 +2309,8 @@ fn airFieldParentPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -2305,8 +2309,8 @@ fn airFieldParentPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
2305 const field_offset = parent_ty.structFieldOffset(extra.field_index, zcu);2309 const field_offset = parent_ty.structFieldOffset(extra.field_index, zcu);
2306 if (field_offset == 0) return field_ptr;2310 if (field_offset == 0) return field_ptr;
23072311
2308 const res_ty = try o.lowerType(pt, ty_pl.ty.toType());2312 const res_ty = try self.lowerType(ty_pl.ty.toType());
2309 const llvm_usize = try o.lowerType(pt, Type.usize);2313 const llvm_usize = try self.lowerType(Type.usize);
23102314
2311 const field_ptr_int = try self.wip.cast(.ptrtoint, field_ptr, llvm_usize, "");2315 const field_ptr_int = try self.wip.cast(.ptrtoint, field_ptr, llvm_usize, "");
2312 const base_ptr_int = try self.wip.bin(2316 const base_ptr_int = try self.wip.bin(
...@@ -2318,19 +2322,19 @@ fn airFieldParentPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -2318,19 +2322,19 @@ fn airFieldParentPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
2318 return self.wip.cast(.inttoptr, base_ptr_int, res_ty, "");2322 return self.wip.cast(.inttoptr, base_ptr_int, res_ty, "");
2319}2323}
23202324
2321fn airNot(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {2325fn airNot(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
2322 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;2326 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
2323 const operand = try self.resolveInst(ty_op.operand);2327 const operand = try self.resolveInst(ty_op.operand);
23242328
2325 return self.wip.not(operand, "");2329 return self.wip.not(operand, "");
2326}2330}
23272331
2328fn airUnreach(self: *FuncGen, inst: Air.Inst.Index) !void {2332fn airUnreach(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!void {
2329 _ = inst;2333 _ = inst;
2330 _ = try self.wip.@"unreachable"();2334 _ = try self.wip.@"unreachable"();
2331}2335}
23322336
2333fn airDbgStmt(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {2337fn airDbgStmt(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
2334 const dbg_stmt = self.air.instructions.items(.data)[@intFromEnum(inst)].dbg_stmt;2338 const dbg_stmt = self.air.instructions.items(.data)[@intFromEnum(inst)].dbg_stmt;
2335 self.prev_dbg_line = @intCast(self.base_line + dbg_stmt.line + 1);2339 self.prev_dbg_line = @intCast(self.base_line + dbg_stmt.line + 1);
2336 self.prev_dbg_column = @intCast(dbg_stmt.column + 1);2340 self.prev_dbg_column = @intCast(dbg_stmt.column + 1);
...@@ -2345,19 +2349,13 @@ fn airDbgStmt(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -2345,19 +2349,13 @@ fn airDbgStmt(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
2345 return .none;2349 return .none;
2346}2350}
23472351
2348fn airDbgEmptyStmt(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {2352fn airDbgEmptyStmt(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
2349 _ = self;2353 _ = self;
2350 _ = inst;2354 _ = inst;
2351 return .none;2355 return .none;
2352}2356}
23532357
2354fn airDbgInlineBlock(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {2358fn airDbgVarPtr(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
2355 const block = self.air.unwrapDbgBlock(inst);
2356 self.arg_inline_index = 0;
2357 return self.lowerBlock(inst, block.func, block.body);
2358}
2359
2360fn airDbgVarPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
2361 const o = self.object;2359 const o = self.object;
2362 const pt = self.pt;2360 const pt = self.pt;
2363 const zcu = pt.zcu;2361 const zcu = pt.zcu;
...@@ -2390,7 +2388,7 @@ fn airDbgVarPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -2390,7 +2388,7 @@ fn airDbgVarPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
2390 return .none;2388 return .none;
2391}2389}
23922390
2393fn airDbgVarVal(self: *FuncGen, inst: Air.Inst.Index, is_arg: bool) !Builder.Value {2391fn airDbgVarVal(self: *FuncGen, inst: Air.Inst.Index, is_arg: bool) Allocator.Error!Builder.Value {
2394 const o = self.object;2392 const o = self.object;
2395 const pt = self.pt;2393 const pt = self.pt;
2396 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;2394 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
...@@ -2468,7 +2466,7 @@ fn airDbgVarVal(self: *FuncGen, inst: Air.Inst.Index, is_arg: bool) !Builder.Val...@@ -2468,7 +2466,7 @@ fn airDbgVarVal(self: *FuncGen, inst: Air.Inst.Index, is_arg: bool) !Builder.Val
2468 return .none;2466 return .none;
2469}2467}
24702468
2471fn airAssembly(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {2469fn airAssembly(self: *FuncGen, inst: Air.Inst.Index) TodoError!Builder.Value {
2472 // Eventually, the Zig compiler needs to be reworked to have inline2470 // Eventually, the Zig compiler needs to be reworked to have inline
2473 // assembly go through the same parsing code regardless of backend, and2471 // assembly go through the same parsing code regardless of backend, and
2474 // have LLVM-flavored inline assembly be *output* from that assembler.2472 // have LLVM-flavored inline assembly be *output* from that assembler.
...@@ -2530,7 +2528,7 @@ fn airAssembly(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -2530,7 +2528,7 @@ fn airAssembly(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
2530 const output_inst = try self.resolveInst(output.operand);2528 const output_inst = try self.resolveInst(output.operand);
2531 const output_ty = self.typeOf(output.operand);2529 const output_ty = self.typeOf(output.operand);
2532 assert(output_ty.zigTypeTag(zcu) == .pointer);2530 assert(output_ty.zigTypeTag(zcu) == .pointer);
2533 const elem_llvm_ty = try o.lowerType(pt, output_ty.childType(zcu));2531 const elem_llvm_ty = try self.lowerType(output_ty.childType(zcu));
25342532
2535 switch (constraint[0]) {2533 switch (constraint[0]) {
2536 '=' => {},2534 '=' => {},
...@@ -2568,7 +2566,7 @@ fn airAssembly(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -2568,7 +2566,7 @@ fn airAssembly(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
2568 llvm_ret_indirect[output.index] = false;2566 llvm_ret_indirect[output.index] = false;
25692567
2570 const ret_ty = self.typeOfIndex(inst);2568 const ret_ty = self.typeOfIndex(inst);
2571 llvm_ret_types[llvm_ret_i] = try o.lowerType(pt, ret_ty);2569 llvm_ret_types[llvm_ret_i] = try self.lowerType(ret_ty);
2572 llvm_ret_i += 1;2570 llvm_ret_i += 1;
2573 }2571 }
25742572
...@@ -2607,7 +2605,7 @@ fn airAssembly(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -2607,7 +2605,7 @@ fn airAssembly(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
2607 llvm_param_types[llvm_param_i] = arg_llvm_value.typeOfWip(&self.wip);2605 llvm_param_types[llvm_param_i] = arg_llvm_value.typeOfWip(&self.wip);
2608 } else {2606 } else {
2609 const alignment = arg_ty.abiAlignment(zcu).toLlvm();2607 const alignment = arg_ty.abiAlignment(zcu).toLlvm();
2610 const arg_llvm_ty = try o.lowerType(pt, arg_ty);2608 const arg_llvm_ty = try self.lowerType(arg_ty);
2611 const load_inst =2609 const load_inst =
2612 try self.wip.load(.normal, arg_llvm_ty, arg_llvm_value, alignment, "");2610 try self.wip.load(.normal, arg_llvm_ty, arg_llvm_value, alignment, "");
2613 llvm_param_values[llvm_param_i] = load_inst;2611 llvm_param_values[llvm_param_i] = load_inst;
...@@ -2648,7 +2646,7 @@ fn airAssembly(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -2648,7 +2646,7 @@ fn airAssembly(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
2648 llvm_param_attrs[llvm_param_i] = if (constraint[0] == '*') blk: {2646 llvm_param_attrs[llvm_param_i] = if (constraint[0] == '*') blk: {
2649 if (!is_by_ref) self.maybeMarkAllowZeroAccess(arg_ty.ptrInfo(zcu));2647 if (!is_by_ref) self.maybeMarkAllowZeroAccess(arg_ty.ptrInfo(zcu));
26502648
2651 break :blk try o.lowerType(pt, if (is_by_ref) arg_ty else arg_ty.childType(zcu));2649 break :blk try self.lowerType(if (is_by_ref) arg_ty else arg_ty.childType(zcu));
2652 } else .none;2650 } else .none;
26532651
2654 llvm_param_i += 1;2652 llvm_param_i += 1;
...@@ -2662,7 +2660,7 @@ fn airAssembly(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -2662,7 +2660,7 @@ fn airAssembly(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
2662 if (constraint[0] != '+') continue;2660 if (constraint[0] != '+') continue;
26632661
2664 const rw_ty = self.typeOf(output.operand);2662 const rw_ty = self.typeOf(output.operand);
2665 const llvm_elem_ty = try o.lowerType(pt, rw_ty.childType(zcu));2663 const llvm_elem_ty = try self.lowerType(rw_ty.childType(zcu));
2666 if (llvm_ret_indirect[output.index]) {2664 if (llvm_ret_indirect[output.index]) {
2667 llvm_param_values[llvm_param_i] = llvm_rw_vals[output.index];2665 llvm_param_values[llvm_param_i] = llvm_rw_vals[output.index];
2668 llvm_param_types[llvm_param_i] = llvm_rw_vals[output.index].typeOfWip(&self.wip);2666 llvm_param_types[llvm_param_i] = llvm_rw_vals[output.index].typeOfWip(&self.wip);
...@@ -2855,7 +2853,7 @@ fn airIsNonNull(...@@ -2855,7 +2853,7 @@ fn airIsNonNull(
2855 inst: Air.Inst.Index,2853 inst: Air.Inst.Index,
2856 operand_is_ptr: bool,2854 operand_is_ptr: bool,
2857 cond: Builder.IntegerCondition,2855 cond: Builder.IntegerCondition,
2858) !Builder.Value {2856) Allocator.Error!Builder.Value {
2859 const o = self.object;2857 const o = self.object;
2860 const pt = self.pt;2858 const pt = self.pt;
2861 const zcu = pt.zcu;2859 const zcu = pt.zcu;
...@@ -2863,7 +2861,7 @@ fn airIsNonNull(...@@ -2863,7 +2861,7 @@ fn airIsNonNull(
2863 const operand = try self.resolveInst(un_op);2861 const operand = try self.resolveInst(un_op);
2864 const operand_ty = self.typeOf(un_op);2862 const operand_ty = self.typeOf(un_op);
2865 const optional_ty = if (operand_is_ptr) operand_ty.childType(zcu) else operand_ty;2863 const optional_ty = if (operand_is_ptr) operand_ty.childType(zcu) else operand_ty;
2866 const optional_llvm_ty = try o.lowerType(pt, optional_ty);2864 const optional_llvm_ty = try self.lowerType(optional_ty);
2867 const payload_ty = optional_ty.optionalChild(zcu);2865 const payload_ty = optional_ty.optionalChild(zcu);
28682866
2869 const access_kind: Builder.MemoryAccessKind =2867 const access_kind: Builder.MemoryAccessKind =
...@@ -2905,7 +2903,7 @@ fn airIsErr(...@@ -2905,7 +2903,7 @@ fn airIsErr(
2905 inst: Air.Inst.Index,2903 inst: Air.Inst.Index,
2906 cond: Builder.IntegerCondition,2904 cond: Builder.IntegerCondition,
2907 operand_is_ptr: bool,2905 operand_is_ptr: bool,
2908) !Builder.Value {2906) Allocator.Error!Builder.Value {
2909 const o = self.object;2907 const o = self.object;
2910 const pt = self.pt;2908 const pt = self.pt;
2911 const zcu = pt.zcu;2909 const zcu = pt.zcu;
...@@ -2914,7 +2912,7 @@ fn airIsErr(...@@ -2914,7 +2912,7 @@ fn airIsErr(
2914 const operand_ty = self.typeOf(un_op);2912 const operand_ty = self.typeOf(un_op);
2915 const err_union_ty = if (operand_is_ptr) operand_ty.childType(zcu) else operand_ty;2913 const err_union_ty = if (operand_is_ptr) operand_ty.childType(zcu) else operand_ty;
2916 const payload_ty = err_union_ty.errorUnionPayload(zcu);2914 const payload_ty = err_union_ty.errorUnionPayload(zcu);
2917 const error_type = try o.errorIntType(pt);2915 const error_type = try o.errorIntType();
2918 const zero = try o.builder.intValue(error_type, 0);2916 const zero = try o.builder.intValue(error_type, 0);
29192917
2920 const access_kind: Builder.MemoryAccessKind =2918 const access_kind: Builder.MemoryAccessKind =
...@@ -2933,7 +2931,7 @@ fn airIsErr(...@@ -2933,7 +2931,7 @@ fn airIsErr(
29332931
2934 if (!payload_ty.hasRuntimeBits(zcu)) {2932 if (!payload_ty.hasRuntimeBits(zcu)) {
2935 const loaded = if (operand_is_ptr)2933 const loaded = if (operand_is_ptr)
2936 try self.wip.load(access_kind, try o.lowerType(pt, err_union_ty), operand, operand_ty.ptrAlignment(zcu).toLlvm(), "")2934 try self.wip.load(access_kind, try self.lowerType(err_union_ty), operand, operand_ty.ptrAlignment(zcu).toLlvm(), "")
2937 else2935 else
2938 operand;2936 operand;
2939 return self.wip.icmp(cond, loaded, zero, "");2937 return self.wip.icmp(cond, loaded, zero, "");
...@@ -2957,7 +2955,7 @@ fn airOptionalPayloadPtr(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!B...@@ -2957,7 +2955,7 @@ fn airOptionalPayloadPtr(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!B
2957 return operand;2955 return operand;
2958}2956}
29592957
2960fn airOptionalPayloadPtrSet(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {2958fn airOptionalPayloadPtrSet(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
2961 comptime assert(optional_layout_version == 3);2959 comptime assert(optional_layout_version == 3);
29622960
2963 const o = self.object;2961 const o = self.object;
...@@ -3002,7 +3000,7 @@ fn airOptionalPayloadPtrSet(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value...@@ -3002,7 +3000,7 @@ fn airOptionalPayloadPtrSet(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value
3002 return operand; // payload is at offset 03000 return operand; // payload is at offset 0
3003}3001}
30043002
3005fn airOptionalPayload(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {3003fn airOptionalPayload(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
3006 const pt = self.pt;3004 const pt = self.pt;
3007 const zcu = pt.zcu;3005 const zcu = pt.zcu;
3008 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;3006 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
...@@ -3019,8 +3017,7 @@ fn airOptionalPayload(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -3019,8 +3017,7 @@ fn airOptionalPayload(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
3019 return self.optPayloadHandle(operand, optional_ty, false);3017 return self.optPayloadHandle(operand, optional_ty, false);
3020}3018}
30213019
3022fn airErrUnionPayload(self: *FuncGen, inst: Air.Inst.Index, operand_is_ptr: bool) !Builder.Value {3020fn airErrUnionPayload(self: *FuncGen, inst: Air.Inst.Index, operand_is_ptr: bool) Allocator.Error!Builder.Value {
3023 const o = self.object;
3024 const pt = self.pt;3021 const pt = self.pt;
3025 const zcu = pt.zcu;3022 const zcu = pt.zcu;
3026 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;3023 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
...@@ -3042,7 +3039,7 @@ fn airErrUnionPayload(self: *FuncGen, inst: Air.Inst.Index, operand_is_ptr: bool...@@ -3042,7 +3039,7 @@ fn airErrUnionPayload(self: *FuncGen, inst: Air.Inst.Index, operand_is_ptr: bool
3042 if (isByRef(payload_ty, zcu)) {3039 if (isByRef(payload_ty, zcu)) {
3043 return self.loadByRef(payload_ptr, payload_ty, payload_alignment, .normal);3040 return self.loadByRef(payload_ptr, payload_ty, payload_alignment, .normal);
3044 } else {3041 } else {
3045 const payload_llvm_ty = try o.lowerType(pt, payload_ty);3042 const payload_llvm_ty = try self.lowerType(payload_ty);
3046 return self.wip.load(.normal, payload_llvm_ty, payload_ptr, payload_alignment, "");3043 return self.wip.load(.normal, payload_llvm_ty, payload_ptr, payload_alignment, "");
3047 }3044 }
3048}3045}
...@@ -3051,14 +3048,14 @@ fn airErrUnionErr(...@@ -3051,14 +3048,14 @@ fn airErrUnionErr(
3051 self: *FuncGen,3048 self: *FuncGen,
3052 inst: Air.Inst.Index,3049 inst: Air.Inst.Index,
3053 operand_is_ptr: bool,3050 operand_is_ptr: bool,
3054) !Builder.Value {3051) Allocator.Error!Builder.Value {
3055 const o = self.object;3052 const o = self.object;
3056 const pt = self.pt;3053 const pt = self.pt;
3057 const zcu = pt.zcu;3054 const zcu = pt.zcu;
3058 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;3055 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
3059 const operand = try self.resolveInst(ty_op.operand);3056 const operand = try self.resolveInst(ty_op.operand);
3060 const operand_ty = self.typeOf(ty_op.operand);3057 const operand_ty = self.typeOf(ty_op.operand);
3061 const error_type = try o.errorIntType(pt);3058 const error_type = try o.errorIntType();
3062 const err_union_ty = if (operand_is_ptr) operand_ty.childType(zcu) else operand_ty;3059 const err_union_ty = if (operand_is_ptr) operand_ty.childType(zcu) else operand_ty;
3063 if (err_union_ty.errorUnionSet(zcu).errorSetIsEmpty(zcu)) {3060 if (err_union_ty.errorUnionSet(zcu).errorSetIsEmpty(zcu)) {
3064 if (operand_is_ptr) {3061 if (operand_is_ptr) {
...@@ -3094,7 +3091,7 @@ fn airErrUnionErr(...@@ -3094,7 +3091,7 @@ fn airErrUnionErr(
3094 return self.wip.load(access_kind, error_type, err_field_ptr, err_align.toLlvm(), "");3091 return self.wip.load(access_kind, error_type, err_field_ptr, err_align.toLlvm(), "");
3095}3092}
30963093
3097fn airErrUnionPayloadPtrSet(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {3094fn airErrUnionPayloadPtrSet(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
3098 const o = self.object;3095 const o = self.object;
3099 const pt = self.pt;3096 const pt = self.pt;
3100 const zcu = pt.zcu;3097 const zcu = pt.zcu;
...@@ -3105,7 +3102,7 @@ fn airErrUnionPayloadPtrSet(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value...@@ -3105,7 +3102,7 @@ fn airErrUnionPayloadPtrSet(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value
3105 const err_union_ptr_align = err_union_ptr_ty.ptrAlignment(zcu);3102 const err_union_ptr_align = err_union_ptr_ty.ptrAlignment(zcu);
31063103
3107 const payload_ty = err_union_ty.errorUnionPayload(zcu);3104 const payload_ty = err_union_ty.errorUnionPayload(zcu);
3108 const non_error_val = try o.builder.intValue(try o.errorIntType(pt), 0);3105 const non_error_val = try o.builder.intValue(try o.errorIntType(), 0);
31093106
3110 const access_kind: Builder.MemoryAccessKind =3107 const access_kind: Builder.MemoryAccessKind =
3111 if (err_union_ptr_ty.isVolatilePtr(zcu)) .@"volatile" else .normal;3108 if (err_union_ptr_ty.isVolatilePtr(zcu)) .@"volatile" else .normal;
...@@ -3124,18 +3121,18 @@ fn airErrUnionPayloadPtrSet(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value...@@ -3124,18 +3121,18 @@ fn airErrUnionPayloadPtrSet(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value
3124 return self.ptraddConst(operand, codegen.errUnionPayloadOffset(payload_ty, zcu));3121 return self.ptraddConst(operand, codegen.errUnionPayloadOffset(payload_ty, zcu));
3125}3122}
31263123
3127fn airErrReturnTrace(self: *FuncGen, _: Air.Inst.Index) !Builder.Value {3124fn airErrReturnTrace(self: *FuncGen, _: Air.Inst.Index) Allocator.Error!Builder.Value {
3128 assert(self.err_ret_trace != .none);3125 assert(self.err_ret_trace != .none);
3129 return self.err_ret_trace;3126 return self.err_ret_trace;
3130}3127}
31313128
3132fn airSetErrReturnTrace(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {3129fn airSetErrReturnTrace(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
3133 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;3130 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
3134 self.err_ret_trace = try self.resolveInst(un_op);3131 self.err_ret_trace = try self.resolveInst(un_op);
3135 return .none;3132 return .none;
3136}3133}
31373134
3138fn airSaveErrReturnTraceIndex(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {3135fn airSaveErrReturnTraceIndex(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
3139 const pt = self.pt;3136 const pt = self.pt;
3140 const zcu = pt.zcu;3137 const zcu = pt.zcu;
31413138
...@@ -3184,7 +3181,7 @@ fn isNextRet(...@@ -3184,7 +3181,7 @@ fn isNextRet(
3184 return false;3181 return false;
3185}3182}
31863183
3187fn airWrapOptional(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value {3184fn airWrapOptional(self: *FuncGen, body_tail: []const Air.Inst.Index) Allocator.Error!Builder.Value {
3188 const o = self.object;3185 const o = self.object;
3189 const pt = self.pt;3186 const pt = self.pt;
3190 const zcu = pt.zcu;3187 const zcu = pt.zcu;
...@@ -3198,7 +3195,7 @@ fn airWrapOptional(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.V...@@ -3198,7 +3195,7 @@ fn airWrapOptional(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.V
3198 const optional_ty = self.typeOfIndex(inst);3195 const optional_ty = self.typeOfIndex(inst);
3199 if (optional_ty.optionalReprIsPayload(zcu)) return operand;3196 if (optional_ty.optionalReprIsPayload(zcu)) return operand;
3200 assert(isByRef(optional_ty, zcu)); // optionals with runtime bits are by-ref unless `optionalReprIsPayload`3197 assert(isByRef(optional_ty, zcu)); // optionals with runtime bits are by-ref unless `optionalReprIsPayload`
3201 const llvm_optional_ty = try o.lowerType(pt, optional_ty);3198 const llvm_optional_ty = try self.lowerType(optional_ty);
3202 const optional_ptr = if (self.isNextRet(body_tail))3199 const optional_ptr = if (self.isNextRet(body_tail))
3203 self.ret_ptr3200 self.ret_ptr
3204 else brk: {3201 else brk: {
...@@ -3216,7 +3213,7 @@ fn airWrapOptional(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.V...@@ -3216,7 +3213,7 @@ fn airWrapOptional(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.V
3216 return optional_ptr;3213 return optional_ptr;
3217}3214}
32183215
3219fn airWrapErrUnionPayload(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value {3216fn airWrapErrUnionPayload(self: *FuncGen, body_tail: []const Air.Inst.Index) Allocator.Error!Builder.Value {
3220 const o = self.object;3217 const o = self.object;
3221 const pt = self.pt;3218 const pt = self.pt;
3222 const zcu = pt.zcu;3219 const zcu = pt.zcu;
...@@ -3227,8 +3224,8 @@ fn airWrapErrUnionPayload(self: *FuncGen, body_tail: []const Air.Inst.Index) !Bu...@@ -3227,8 +3224,8 @@ fn airWrapErrUnionPayload(self: *FuncGen, body_tail: []const Air.Inst.Index) !Bu
3227 const payload_ty = self.typeOf(ty_op.operand);3224 const payload_ty = self.typeOf(ty_op.operand);
3228 assert(payload_ty.hasRuntimeBits(zcu));3225 assert(payload_ty.hasRuntimeBits(zcu));
3229 assert(isByRef(err_un_ty, zcu)); // error unions with runtime bits are always by-ref3226 assert(isByRef(err_un_ty, zcu)); // error unions with runtime bits are always by-ref
3230 const ok_err_code = try o.builder.intValue(try o.errorIntType(pt), 0);3227 const ok_err_code = try o.builder.intValue(try o.errorIntType(), 0);
3231 const err_un_llvm_ty = try o.lowerType(pt, err_un_ty);3228 const err_un_llvm_ty = try self.lowerType(err_un_ty);
32323229
3233 const result_ptr = if (self.isNextRet(body_tail))3230 const result_ptr = if (self.isNextRet(body_tail))
3234 self.ret_ptr3231 self.ret_ptr
...@@ -3247,8 +3244,7 @@ fn airWrapErrUnionPayload(self: *FuncGen, body_tail: []const Air.Inst.Index) !Bu...@@ -3247,8 +3244,7 @@ fn airWrapErrUnionPayload(self: *FuncGen, body_tail: []const Air.Inst.Index) !Bu
3247 return result_ptr;3244 return result_ptr;
3248}3245}
32493246
3250fn airWrapErrUnionErr(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value {3247fn airWrapErrUnionErr(self: *FuncGen, body_tail: []const Air.Inst.Index) Allocator.Error!Builder.Value {
3251 const o = self.object;
3252 const pt = self.pt;3248 const pt = self.pt;
3253 const zcu = pt.zcu;3249 const zcu = pt.zcu;
3254 const inst = body_tail[0];3250 const inst = body_tail[0];
...@@ -3258,7 +3254,7 @@ fn airWrapErrUnionErr(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builde...@@ -3258,7 +3254,7 @@ fn airWrapErrUnionErr(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builde
3258 const operand = try self.resolveInst(ty_op.operand);3254 const operand = try self.resolveInst(ty_op.operand);
3259 if (!payload_ty.hasRuntimeBits(zcu)) return operand;3255 if (!payload_ty.hasRuntimeBits(zcu)) return operand;
3260 assert(isByRef(err_un_ty, zcu)); // error unions with runtime bits are always by-ref3256 assert(isByRef(err_un_ty, zcu)); // error unions with runtime bits are always by-ref
3261 const err_un_llvm_ty = try o.lowerType(pt, err_un_ty);3257 const err_un_llvm_ty = try self.lowerType(err_un_ty);
32623258
3263 const result_ptr = if (self.isNextRet(body_tail))3259 const result_ptr = if (self.isNextRet(body_tail))
3264 self.ret_ptr3260 self.ret_ptr
...@@ -3279,29 +3275,27 @@ fn airWrapErrUnionErr(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builde...@@ -3279,29 +3275,27 @@ fn airWrapErrUnionErr(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builde
3279 return result_ptr;3275 return result_ptr;
3280}3276}
32813277
3282fn airWasmMemorySize(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {3278fn airWasmMemorySize(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
3283 const o = self.object;3279 const o = self.object;
3284 const pt = self.pt;
3285 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;3280 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
3286 const index = pl_op.payload;3281 const index = pl_op.payload;
3287 const llvm_usize = try o.lowerType(pt, Type.usize);3282 const llvm_usize = try self.lowerType(Type.usize);
3288 return self.wip.callIntrinsic(.normal, .none, .@"wasm.memory.size", &.{llvm_usize}, &.{3283 return self.wip.callIntrinsic(.normal, .none, .@"wasm.memory.size", &.{llvm_usize}, &.{
3289 try o.builder.intValue(.i32, index),3284 try o.builder.intValue(.i32, index),
3290 }, "");3285 }, "");
3291}3286}
32923287
3293fn airWasmMemoryGrow(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {3288fn airWasmMemoryGrow(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
3294 const o = self.object;3289 const o = self.object;
3295 const pt = self.pt;
3296 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;3290 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
3297 const index = pl_op.payload;3291 const index = pl_op.payload;
3298 const llvm_isize = try o.lowerType(pt, Type.isize);3292 const llvm_isize = try self.lowerType(Type.isize);
3299 return self.wip.callIntrinsic(.normal, .none, .@"wasm.memory.grow", &.{llvm_isize}, &.{3293 return self.wip.callIntrinsic(.normal, .none, .@"wasm.memory.grow", &.{llvm_isize}, &.{
3300 try o.builder.intValue(.i32, index), try self.resolveInst(pl_op.operand),3294 try o.builder.intValue(.i32, index), try self.resolveInst(pl_op.operand),
3301 }, "");3295 }, "");
3302}3296}
33033297
3304fn airRuntimeNavPtr(fg: *FuncGen, inst: Air.Inst.Index) !Builder.Value {3298fn airRuntimeNavPtr(fg: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
3305 const o = fg.object;3299 const o = fg.object;
3306 const pt = fg.pt;3300 const pt = fg.pt;
3307 const ty_nav = fg.air.instructions.items(.data)[@intFromEnum(inst)].ty_nav;3301 const ty_nav = fg.air.instructions.items(.data)[@intFromEnum(inst)].ty_nav;
...@@ -3309,8 +3303,7 @@ fn airRuntimeNavPtr(fg: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -3309,8 +3303,7 @@ fn airRuntimeNavPtr(fg: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
3309 return llvm_ptr_const.toValue();3303 return llvm_ptr_const.toValue();
3310}3304}
33113305
3312fn airMin(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {3306fn airMin(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
3313 const o = self.object;
3314 const pt = self.pt;3307 const pt = self.pt;
3315 const zcu = pt.zcu;3308 const zcu = pt.zcu;
3316 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;3309 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
...@@ -3324,14 +3317,13 @@ fn airMin(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -3324,14 +3317,13 @@ fn airMin(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
3324 .normal,3317 .normal,
3325 .none,3318 .none,
3326 if (scalar_ty.isSignedInt(zcu)) .smin else .umin,3319 if (scalar_ty.isSignedInt(zcu)) .smin else .umin,
3327 &.{try o.lowerType(pt, inst_ty)},3320 &.{try self.lowerType(inst_ty)},
3328 &.{ lhs, rhs },3321 &.{ lhs, rhs },
3329 "",3322 "",
3330 );3323 );
3331}3324}
33323325
3333fn airMax(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {3326fn airMax(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
3334 const o = self.object;
3335 const pt = self.pt;3327 const pt = self.pt;
3336 const zcu = pt.zcu;3328 const zcu = pt.zcu;
3337 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;3329 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
...@@ -3345,24 +3337,22 @@ fn airMax(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -3345,24 +3337,22 @@ fn airMax(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
3345 .normal,3337 .normal,
3346 .none,3338 .none,
3347 if (scalar_ty.isSignedInt(zcu)) .smax else .umax,3339 if (scalar_ty.isSignedInt(zcu)) .smax else .umax,
3348 &.{try o.lowerType(pt, inst_ty)},3340 &.{try self.lowerType(inst_ty)},
3349 &.{ lhs, rhs },3341 &.{ lhs, rhs },
3350 "",3342 "",
3351 );3343 );
3352}3344}
33533345
3354fn airSlice(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {3346fn airSlice(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
3355 const o = self.object;
3356 const pt = self.pt;
3357 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;3347 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
3358 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;3348 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
3359 const ptr = try self.resolveInst(bin_op.lhs);3349 const ptr = try self.resolveInst(bin_op.lhs);
3360 const len = try self.resolveInst(bin_op.rhs);3350 const len = try self.resolveInst(bin_op.rhs);
3361 const inst_ty = self.typeOfIndex(inst);3351 const inst_ty = self.typeOfIndex(inst);
3362 return self.wip.buildAggregate(try o.lowerType(pt, inst_ty), &.{ ptr, len }, "");3352 return self.wip.buildAggregate(try self.lowerType(inst_ty), &.{ ptr, len }, "");
3363}3353}
33643354
3365fn airAdd(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value {3355fn airAdd(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) Allocator.Error!Builder.Value {
3366 const zcu = self.pt.zcu;3356 const zcu = self.pt.zcu;
3367 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;3357 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
3368 const lhs = try self.resolveInst(bin_op.lhs);3358 const lhs = try self.resolveInst(bin_op.lhs);
...@@ -3379,7 +3369,7 @@ fn airSafeArithmetic(...@@ -3379,7 +3369,7 @@ fn airSafeArithmetic(
3379 inst: Air.Inst.Index,3369 inst: Air.Inst.Index,
3380 signed_intrinsic: Builder.Intrinsic,3370 signed_intrinsic: Builder.Intrinsic,
3381 unsigned_intrinsic: Builder.Intrinsic,3371 unsigned_intrinsic: Builder.Intrinsic,
3382) !Builder.Value {3372) Allocator.Error!Builder.Value {
3383 const o = fg.object;3373 const o = fg.object;
3384 const pt = fg.pt;3374 const pt = fg.pt;
3385 const zcu = pt.zcu;3375 const zcu = pt.zcu;
...@@ -3391,7 +3381,7 @@ fn airSafeArithmetic(...@@ -3391,7 +3381,7 @@ fn airSafeArithmetic(
3391 const scalar_ty = inst_ty.scalarType(zcu);3381 const scalar_ty = inst_ty.scalarType(zcu);
33923382
3393 const intrinsic = if (scalar_ty.isSignedInt(zcu)) signed_intrinsic else unsigned_intrinsic;3383 const intrinsic = if (scalar_ty.isSignedInt(zcu)) signed_intrinsic else unsigned_intrinsic;
3394 const llvm_inst_ty = try o.lowerType(pt, inst_ty);3384 const llvm_inst_ty = try fg.lowerType(inst_ty);
3395 const results =3385 const results =
3396 try fg.wip.callIntrinsic(.normal, .none, intrinsic, &.{llvm_inst_ty}, &.{ lhs, rhs }, "");3386 try fg.wip.callIntrinsic(.normal, .none, intrinsic, &.{llvm_inst_ty}, &.{ lhs, rhs }, "");
33973387
...@@ -3420,7 +3410,7 @@ fn airSafeArithmetic(...@@ -3420,7 +3410,7 @@ fn airSafeArithmetic(
3420 return fg.wip.extractValue(results, &.{0}, "");3410 return fg.wip.extractValue(results, &.{0}, "");
3421}3411}
34223412
3423fn airAddWrap(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {3413fn airAddWrap(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
3424 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;3414 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
3425 const lhs = try self.resolveInst(bin_op.lhs);3415 const lhs = try self.resolveInst(bin_op.lhs);
3426 const rhs = try self.resolveInst(bin_op.rhs);3416 const rhs = try self.resolveInst(bin_op.rhs);
...@@ -3428,8 +3418,7 @@ fn airAddWrap(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -3428,8 +3418,7 @@ fn airAddWrap(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
3428 return self.wip.bin(.add, lhs, rhs, "");3418 return self.wip.bin(.add, lhs, rhs, "");
3429}3419}
34303420
3431fn airAddSat(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {3421fn airAddSat(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
3432 const o = self.object;
3433 const pt = self.pt;3422 const pt = self.pt;
3434 const zcu = pt.zcu;3423 const zcu = pt.zcu;
3435 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;3424 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
...@@ -3442,13 +3431,13 @@ fn airAddSat(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -3442,13 +3431,13 @@ fn airAddSat(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
3442 .normal,3431 .normal,
3443 .none,3432 .none,
3444 if (scalar_ty.isSignedInt(zcu)) .@"sadd.sat" else .@"uadd.sat",3433 if (scalar_ty.isSignedInt(zcu)) .@"sadd.sat" else .@"uadd.sat",
3445 &.{try o.lowerType(pt, inst_ty)},3434 &.{try self.lowerType(inst_ty)},
3446 &.{ lhs, rhs },3435 &.{ lhs, rhs },
3447 "",3436 "",
3448 );3437 );
3449}3438}
34503439
3451fn airSub(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value {3440fn airSub(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) Allocator.Error!Builder.Value {
3452 const zcu = self.pt.zcu;3441 const zcu = self.pt.zcu;
3453 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;3442 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
3454 const lhs = try self.resolveInst(bin_op.lhs);3443 const lhs = try self.resolveInst(bin_op.lhs);
...@@ -3460,7 +3449,7 @@ fn airSub(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Bui...@@ -3460,7 +3449,7 @@ fn airSub(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Bui
3460 return self.wip.bin(if (scalar_ty.isSignedInt(zcu)) .@"sub nsw" else .@"sub nuw", lhs, rhs, "");3449 return self.wip.bin(if (scalar_ty.isSignedInt(zcu)) .@"sub nsw" else .@"sub nuw", lhs, rhs, "");
3461}3450}
34623451
3463fn airSubWrap(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {3452fn airSubWrap(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
3464 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;3453 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
3465 const lhs = try self.resolveInst(bin_op.lhs);3454 const lhs = try self.resolveInst(bin_op.lhs);
3466 const rhs = try self.resolveInst(bin_op.rhs);3455 const rhs = try self.resolveInst(bin_op.rhs);
...@@ -3468,8 +3457,7 @@ fn airSubWrap(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -3468,8 +3457,7 @@ fn airSubWrap(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
3468 return self.wip.bin(.sub, lhs, rhs, "");3457 return self.wip.bin(.sub, lhs, rhs, "");
3469}3458}
34703459
3471fn airSubSat(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {3460fn airSubSat(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
3472 const o = self.object;
3473 const pt = self.pt;3461 const pt = self.pt;
3474 const zcu = pt.zcu;3462 const zcu = pt.zcu;
3475 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;3463 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
...@@ -3482,13 +3470,13 @@ fn airSubSat(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -3482,13 +3470,13 @@ fn airSubSat(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
3482 .normal,3470 .normal,
3483 .none,3471 .none,
3484 if (scalar_ty.isSignedInt(zcu)) .@"ssub.sat" else .@"usub.sat",3472 if (scalar_ty.isSignedInt(zcu)) .@"ssub.sat" else .@"usub.sat",
3485 &.{try o.lowerType(pt, inst_ty)},3473 &.{try self.lowerType(inst_ty)},
3486 &.{ lhs, rhs },3474 &.{ lhs, rhs },
3487 "",3475 "",
3488 );3476 );
3489}3477}
34903478
3491fn airMul(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value {3479fn airMul(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) Allocator.Error!Builder.Value {
3492 const zcu = self.pt.zcu;3480 const zcu = self.pt.zcu;
3493 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;3481 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
3494 const lhs = try self.resolveInst(bin_op.lhs);3482 const lhs = try self.resolveInst(bin_op.lhs);
...@@ -3500,7 +3488,7 @@ fn airMul(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Bui...@@ -3500,7 +3488,7 @@ fn airMul(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Bui
3500 return self.wip.bin(if (scalar_ty.isSignedInt(zcu)) .@"mul nsw" else .@"mul nuw", lhs, rhs, "");3488 return self.wip.bin(if (scalar_ty.isSignedInt(zcu)) .@"mul nsw" else .@"mul nuw", lhs, rhs, "");
3501}3489}
35023490
3503fn airMulWrap(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {3491fn airMulWrap(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
3504 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;3492 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
3505 const lhs = try self.resolveInst(bin_op.lhs);3493 const lhs = try self.resolveInst(bin_op.lhs);
3506 const rhs = try self.resolveInst(bin_op.rhs);3494 const rhs = try self.resolveInst(bin_op.rhs);
...@@ -3508,8 +3496,7 @@ fn airMulWrap(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -3508,8 +3496,7 @@ fn airMulWrap(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
3508 return self.wip.bin(.mul, lhs, rhs, "");3496 return self.wip.bin(.mul, lhs, rhs, "");
3509}3497}
35103498
3511fn airMulSat(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {3499fn airMulSat(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
3512 const o = self.object;
3513 const pt = self.pt;3500 const pt = self.pt;
3514 const zcu = pt.zcu;3501 const zcu = pt.zcu;
3515 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;3502 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
...@@ -3522,13 +3509,13 @@ fn airMulSat(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -3522,13 +3509,13 @@ fn airMulSat(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
3522 .normal,3509 .normal,
3523 .none,3510 .none,
3524 if (scalar_ty.isSignedInt(zcu)) .@"smul.fix.sat" else .@"umul.fix.sat",3511 if (scalar_ty.isSignedInt(zcu)) .@"smul.fix.sat" else .@"umul.fix.sat",
3525 &.{try o.lowerType(pt, inst_ty)},3512 &.{try self.lowerType(inst_ty)},
3526 &.{ lhs, rhs, .@"0" },3513 &.{ lhs, rhs, .@"0" },
3527 "",3514 "",
3528 );3515 );
3529}3516}
35303517
3531fn airDivFloat(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value {3518fn airDivFloat(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) Allocator.Error!Builder.Value {
3532 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;3519 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
3533 const lhs = try self.resolveInst(bin_op.lhs);3520 const lhs = try self.resolveInst(bin_op.lhs);
3534 const rhs = try self.resolveInst(bin_op.rhs);3521 const rhs = try self.resolveInst(bin_op.rhs);
...@@ -3537,7 +3524,7 @@ fn airDivFloat(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind)...@@ -3537,7 +3524,7 @@ fn airDivFloat(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind)
3537 return self.buildFloatOp(.div, fast, inst_ty, 2, .{ lhs, rhs });3524 return self.buildFloatOp(.div, fast, inst_ty, 2, .{ lhs, rhs });
3538}3525}
35393526
3540fn airDivTrunc(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value {3527fn airDivTrunc(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) Allocator.Error!Builder.Value {
3541 const zcu = self.pt.zcu;3528 const zcu = self.pt.zcu;
3542 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;3529 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
3543 const lhs = try self.resolveInst(bin_op.lhs);3530 const lhs = try self.resolveInst(bin_op.lhs);
...@@ -3552,7 +3539,7 @@ fn airDivTrunc(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind)...@@ -3552,7 +3539,7 @@ fn airDivTrunc(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind)
3552 return self.wip.bin(if (scalar_ty.isSignedInt(zcu)) .sdiv else .udiv, lhs, rhs, "");3539 return self.wip.bin(if (scalar_ty.isSignedInt(zcu)) .sdiv else .udiv, lhs, rhs, "");
3553}3540}
35543541
3555fn airDivFloor(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value {3542fn airDivFloor(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) Allocator.Error!Builder.Value {
3556 const o = self.object;3543 const o = self.object;
3557 const pt = self.pt;3544 const pt = self.pt;
3558 const zcu = pt.zcu;3545 const zcu = pt.zcu;
...@@ -3567,7 +3554,7 @@ fn airDivFloor(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind)...@@ -3567,7 +3554,7 @@ fn airDivFloor(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind)
3567 return self.buildFloatOp(.floor, fast, inst_ty, 1, .{result});3554 return self.buildFloatOp(.floor, fast, inst_ty, 1, .{result});
3568 }3555 }
3569 if (scalar_ty.isSignedInt(zcu)) {3556 if (scalar_ty.isSignedInt(zcu)) {
3570 const inst_llvm_ty = try o.lowerType(pt, inst_ty);3557 const inst_llvm_ty = try self.lowerType(inst_ty);
35713558
3572 const ExpectedContents = [std.math.big.int.calcTwosCompLimbCount(256)]std.math.big.Limb;3559 const ExpectedContents = [std.math.big.int.calcTwosCompLimbCount(256)]std.math.big.Limb;
3573 var stack align(@max(3560 var stack align(@max(
...@@ -3603,7 +3590,7 @@ fn airDivFloor(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind)...@@ -3603,7 +3590,7 @@ fn airDivFloor(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind)
3603 return self.wip.bin(.udiv, lhs, rhs, "");3590 return self.wip.bin(.udiv, lhs, rhs, "");
3604}3591}
36053592
3606fn airDivExact(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value {3593fn airDivExact(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) Allocator.Error!Builder.Value {
3607 const zcu = self.pt.zcu;3594 const zcu = self.pt.zcu;
3608 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;3595 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
3609 const lhs = try self.resolveInst(bin_op.lhs);3596 const lhs = try self.resolveInst(bin_op.lhs);
...@@ -3620,7 +3607,7 @@ fn airDivExact(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind)...@@ -3620,7 +3607,7 @@ fn airDivExact(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind)
3620 );3607 );
3621}3608}
36223609
3623fn airRem(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value {3610fn airRem(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) Allocator.Error!Builder.Value {
3624 const zcu = self.pt.zcu;3611 const zcu = self.pt.zcu;
3625 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;3612 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
3626 const lhs = try self.resolveInst(bin_op.lhs);3613 const lhs = try self.resolveInst(bin_op.lhs);
...@@ -3636,7 +3623,7 @@ fn airRem(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Bui...@@ -3636,7 +3623,7 @@ fn airRem(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Bui
3636 .urem, lhs, rhs, "");3623 .urem, lhs, rhs, "");
3637}3624}
36383625
3639fn airMod(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value {3626fn airMod(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) Allocator.Error!Builder.Value {
3640 const o = self.object;3627 const o = self.object;
3641 const pt = self.pt;3628 const pt = self.pt;
3642 const zcu = pt.zcu;3629 const zcu = pt.zcu;
...@@ -3644,7 +3631,7 @@ fn airMod(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Bui...@@ -3644,7 +3631,7 @@ fn airMod(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Bui
3644 const lhs = try self.resolveInst(bin_op.lhs);3631 const lhs = try self.resolveInst(bin_op.lhs);
3645 const rhs = try self.resolveInst(bin_op.rhs);3632 const rhs = try self.resolveInst(bin_op.rhs);
3646 const inst_ty = self.typeOfIndex(inst);3633 const inst_ty = self.typeOfIndex(inst);
3647 const inst_llvm_ty = try o.lowerType(pt, inst_ty);3634 const inst_llvm_ty = try self.lowerType(inst_ty);
3648 const scalar_ty = inst_ty.scalarType(zcu);3635 const scalar_ty = inst_ty.scalarType(zcu);
36493636
3650 if (scalar_ty.isRuntimeFloat()) {3637 if (scalar_ty.isRuntimeFloat()) {
...@@ -3690,7 +3677,7 @@ fn airMod(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Bui...@@ -3690,7 +3677,7 @@ fn airMod(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Bui
3690 return self.wip.bin(.urem, lhs, rhs, "");3677 return self.wip.bin(.urem, lhs, rhs, "");
3691}3678}
36923679
3693fn airPtrAdd(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {3680fn airPtrAdd(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
3694 const zcu = self.pt.zcu;3681 const zcu = self.pt.zcu;
3695 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;3682 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
3696 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;3683 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
...@@ -3705,14 +3692,14 @@ fn airPtrAdd(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -3705,14 +3692,14 @@ fn airPtrAdd(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
3705 return self.ptraddScaled(ptr, index, elem_ty.abiSize(zcu));3692 return self.ptraddScaled(ptr, index, elem_ty.abiSize(zcu));
3706}3693}
37073694
3708fn airPtrSub(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {3695fn airPtrSub(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
3709 const o = self.object;3696 const o = self.object;
3710 const pt = self.pt;3697 const pt = self.pt;
3711 const zcu = pt.zcu;3698 const zcu = pt.zcu;
3712 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;3699 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
3713 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;3700 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
3714 const ptr_or_slice = try self.resolveInst(bin_op.lhs);3701 const ptr_or_slice = try self.resolveInst(bin_op.lhs);
3715 const llvm_usize_ty = try o.lowerType(pt, .usize);3702 const llvm_usize_ty = try self.lowerType(.usize);
3716 const ptr_ty = self.typeOf(bin_op.lhs);3703 const ptr_ty = self.typeOf(bin_op.lhs);
3717 const elem_ty = ptr_ty.indexableElem(zcu);3704 const elem_ty = ptr_ty.indexableElem(zcu);
3718 const ptr = switch (ptr_ty.ptrSize(zcu)) {3705 const ptr = switch (ptr_ty.ptrSize(zcu)) {
...@@ -3722,7 +3709,7 @@ fn airPtrSub(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -3722,7 +3709,7 @@ fn airPtrSub(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
3722 const scale_val = try o.builder.intValue(llvm_usize_ty, -@as(i65, elem_ty.abiSize(zcu)));3709 const scale_val = try o.builder.intValue(llvm_usize_ty, -@as(i65, elem_ty.abiSize(zcu)));
3723 const positive_index = try self.resolveInst(bin_op.rhs);3710 const positive_index = try self.resolveInst(bin_op.rhs);
3724 const negative_offset = try self.wip.bin(.@"mul nsw", positive_index, scale_val, "");3711 const negative_offset = try self.wip.bin(.@"mul nsw", positive_index, scale_val, "");
3725 return self.ptradd(ptr, negative_offset);3712 return self.wip.gep(.inbounds, .i8, ptr, &.{negative_offset}, "");
3726}3713}
37273714
3728fn airOverflow(3715fn airOverflow(
...@@ -3730,8 +3717,7 @@ fn airOverflow(...@@ -3730,8 +3717,7 @@ fn airOverflow(
3730 inst: Air.Inst.Index,3717 inst: Air.Inst.Index,
3731 signed_intrinsic: Builder.Intrinsic,3718 signed_intrinsic: Builder.Intrinsic,
3732 unsigned_intrinsic: Builder.Intrinsic,3719 unsigned_intrinsic: Builder.Intrinsic,
3733) !Builder.Value {3720) Allocator.Error!Builder.Value {
3734 const o = self.object;
3735 const pt = self.pt;3721 const pt = self.pt;
3736 const zcu = pt.zcu;3722 const zcu = pt.zcu;
3737 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;3723 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
...@@ -3746,8 +3732,8 @@ fn airOverflow(...@@ -3746,8 +3732,8 @@ fn airOverflow(
3746 assert(isByRef(inst_ty, zcu)); // auto structs are by-ref3732 assert(isByRef(inst_ty, zcu)); // auto structs are by-ref
37473733
3748 const intrinsic = if (scalar_ty.isSignedInt(zcu)) signed_intrinsic else unsigned_intrinsic;3734 const intrinsic = if (scalar_ty.isSignedInt(zcu)) signed_intrinsic else unsigned_intrinsic;
3749 const llvm_inst_ty = try o.lowerType(pt, inst_ty);3735 const llvm_inst_ty = try self.lowerType(inst_ty);
3750 const llvm_lhs_ty = try o.lowerType(pt, lhs_ty);3736 const llvm_lhs_ty = try self.lowerType(lhs_ty);
3751 const results =3737 const results =
3752 try self.wip.callIntrinsic(.normal, .none, intrinsic, &.{llvm_lhs_ty}, &.{ lhs, rhs }, "");3738 try self.wip.callIntrinsic(.normal, .none, intrinsic, &.{llvm_lhs_ty}, &.{ lhs, rhs }, "");
37533739
...@@ -3778,7 +3764,7 @@ fn buildElementwiseCall(...@@ -3778,7 +3764,7 @@ fn buildElementwiseCall(
3778 args_vectors: []const Builder.Value,3764 args_vectors: []const Builder.Value,
3779 result_vector: Builder.Value,3765 result_vector: Builder.Value,
3780 vector_len: usize,3766 vector_len: usize,
3781) !Builder.Value {3767) Allocator.Error!Builder.Value {
3782 const o = self.object;3768 const o = self.object;
3783 assert(args_vectors.len <= 3);3769 assert(args_vectors.len <= 3);
37843770
...@@ -3805,25 +3791,6 @@ fn buildElementwiseCall(...@@ -3805,25 +3791,6 @@ fn buildElementwiseCall(
3805 return result;3791 return result;
3806}3792}
38073793
3808fn getLibcFunction(
3809 self: *FuncGen,
3810 fn_name: Builder.StrtabString,
3811 param_types: []const Builder.Type,
3812 return_type: Builder.Type,
3813) Allocator.Error!Builder.Function.Index {
3814 const o = self.object;
3815 if (o.builder.getGlobal(fn_name)) |global| return switch (global.ptrConst(&o.builder).kind) {
3816 .alias => |alias| alias.getAliasee(&o.builder).ptrConst(&o.builder).kind.function,
3817 .function => |function| function,
3818 .variable, .replaced => unreachable,
3819 };
3820 return o.builder.addFunction(
3821 try o.builder.fnType(return_type, param_types, .normal),
3822 fn_name,
3823 toLlvmAddressSpace(.generic, self.pt.zcu.getTarget()),
3824 );
3825}
3826
3827/// Creates a floating point comparison by lowering to the appropriate3794/// Creates a floating point comparison by lowering to the appropriate
3828/// hardware instruction or softfloat routine for the target3795/// hardware instruction or softfloat routine for the target
3829fn buildFloatCmp(3796fn buildFloatCmp(
...@@ -3832,13 +3799,13 @@ fn buildFloatCmp(...@@ -3832,13 +3799,13 @@ fn buildFloatCmp(
3832 pred: math.CompareOperator,3799 pred: math.CompareOperator,
3833 ty: Type,3800 ty: Type,
3834 params: [2]Builder.Value,3801 params: [2]Builder.Value,
3835) !Builder.Value {3802) Allocator.Error!Builder.Value {
3836 const o = self.object;3803 const o = self.object;
3837 const pt = self.pt;3804 const pt = self.pt;
3838 const zcu = pt.zcu;3805 const zcu = pt.zcu;
3839 const target = zcu.getTarget();3806 const target = zcu.getTarget();
3840 const scalar_ty = ty.scalarType(zcu);3807 const scalar_ty = ty.scalarType(zcu);
3841 const scalar_llvm_ty = try o.lowerType(pt, scalar_ty);3808 const scalar_llvm_ty = try self.lowerType(scalar_ty);
38423809
3843 if (intrinsicsAllowed(scalar_ty, target)) {3810 if (intrinsicsAllowed(scalar_ty, target)) {
3844 const cond: Builder.FloatCondition = switch (pred) {3811 const cond: Builder.FloatCondition = switch (pred) {
...@@ -3864,7 +3831,7 @@ fn buildFloatCmp(...@@ -3864,7 +3831,7 @@ fn buildFloatCmp(
3864 };3831 };
3865 const fn_name = try o.builder.strtabStringFmt("__{s}{s}f2", .{ fn_base_name, compiler_rt_float_abbrev });3832 const fn_name = try o.builder.strtabStringFmt("__{s}{s}f2", .{ fn_base_name, compiler_rt_float_abbrev });
38663833
3867 const libc_fn = try self.getLibcFunction(fn_name, &.{ scalar_llvm_ty, scalar_llvm_ty }, .i32);3834 const libc_fn = try o.getLibcFunction(fn_name, &.{ scalar_llvm_ty, scalar_llvm_ty }, .i32);
38683835
3869 const int_cond: Builder.IntegerCondition = switch (pred) {3836 const int_cond: Builder.IntegerCondition = switch (pred) {
3870 .eq => .eq,3837 .eq => .eq,
...@@ -3939,13 +3906,13 @@ fn buildFloatOp(...@@ -3939,13 +3906,13 @@ fn buildFloatOp(
3939 ty: Type,3906 ty: Type,
3940 comptime params_len: usize,3907 comptime params_len: usize,
3941 params: [params_len]Builder.Value,3908 params: [params_len]Builder.Value,
3942) !Builder.Value {3909) Allocator.Error!Builder.Value {
3943 const o = self.object;3910 const o = self.object;
3944 const pt = self.pt;3911 const pt = self.pt;
3945 const zcu = pt.zcu;3912 const zcu = pt.zcu;
3946 const target = zcu.getTarget();3913 const target = zcu.getTarget();
3947 const scalar_ty = ty.scalarType(zcu);3914 const scalar_ty = ty.scalarType(zcu);
3948 const llvm_ty = try o.lowerType(pt, ty);3915 const llvm_ty = try self.lowerType(ty);
39493916
3950 if (op != .tan and intrinsicsAllowed(scalar_ty, target)) switch (op) {3917 if (op != .tan and intrinsicsAllowed(scalar_ty, target)) switch (op) {
3951 // Some operations are dedicated LLVM instructions, not available as intrinsics3918 // Some operations are dedicated LLVM instructions, not available as intrinsics
...@@ -4048,7 +4015,7 @@ fn buildFloatOp(...@@ -4048,7 +4015,7 @@ fn buildFloatOp(
4048 };4015 };
40494016
4050 const scalar_llvm_ty = llvm_ty.scalarType(&o.builder);4017 const scalar_llvm_ty = llvm_ty.scalarType(&o.builder);
4051 const libc_fn = try self.getLibcFunction(4018 const libc_fn = try o.getLibcFunction(
4052 fn_name,4019 fn_name,
4053 ([1]Builder.Type{scalar_llvm_ty} ** 3)[0..params.len],4020 ([1]Builder.Type{scalar_llvm_ty} ** 3)[0..params.len],
4054 scalar_llvm_ty,4021 scalar_llvm_ty,
...@@ -4069,7 +4036,7 @@ fn buildFloatOp(...@@ -4069,7 +4036,7 @@ fn buildFloatOp(
4069 );4036 );
4070}4037}
40714038
4072fn airMulAdd(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {4039fn airMulAdd(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
4073 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;4040 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
4074 const extra = self.air.extraData(Air.Bin, pl_op.payload).data;4041 const extra = self.air.extraData(Air.Bin, pl_op.payload).data;
40754042
...@@ -4081,8 +4048,7 @@ fn airMulAdd(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -4081,8 +4048,7 @@ fn airMulAdd(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
4081 return self.buildFloatOp(.fma, .normal, ty, 3, .{ mulend1, mulend2, addend });4048 return self.buildFloatOp(.fma, .normal, ty, 3, .{ mulend1, mulend2, addend });
4082}4049}
40834050
4084fn airShlWithOverflow(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {4051fn airShlWithOverflow(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
4085 const o = self.object;
4086 const pt = self.pt;4052 const pt = self.pt;
4087 const zcu = pt.zcu;4053 const zcu = pt.zcu;
4088 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;4054 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
...@@ -4092,15 +4058,19 @@ fn airShlWithOverflow(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -4092,15 +4058,19 @@ fn airShlWithOverflow(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
4092 const rhs = try self.resolveInst(extra.rhs);4058 const rhs = try self.resolveInst(extra.rhs);
40934059
4094 const lhs_ty = self.typeOf(extra.lhs);4060 const lhs_ty = self.typeOf(extra.lhs);
4095 if (lhs_ty.isVector(zcu) and !self.typeOf(extra.rhs).isVector(zcu))4061 if (lhs_ty.isVector(zcu) and !self.typeOf(extra.rhs).isVector(zcu)) {
4096 return self.todo("implement vector shifts with scalar rhs", .{});4062 // `Sema` does not currently emit this pattern---instead it is specific to `Air.Legalize`
4063 // features which we do not use. Therefore this branch is currently impossible.
4064 unreachable;
4065 }
4066
4097 const lhs_scalar_ty = lhs_ty.scalarType(zcu);4067 const lhs_scalar_ty = lhs_ty.scalarType(zcu);
40984068
4099 const dest_ty = self.typeOfIndex(inst);4069 const dest_ty = self.typeOfIndex(inst);
4100 assert(isByRef(dest_ty, zcu)); // auto structs are by-ref4070 assert(isByRef(dest_ty, zcu)); // auto structs are by-ref
4101 const llvm_dest_ty = try o.lowerType(pt, dest_ty);4071 const llvm_dest_ty = try self.lowerType(dest_ty);
41024072
4103 const casted_rhs = try self.wip.conv(.unsigned, rhs, try o.lowerType(pt, lhs_ty), "");4073 const casted_rhs = try self.wip.conv(.unsigned, rhs, try self.lowerType(lhs_ty), "");
41044074
4105 const result = try self.wip.bin(.shl, lhs, casted_rhs, "");4075 const result = try self.wip.bin(.shl, lhs, casted_rhs, "");
4106 const reconstructed = try self.wip.bin(if (lhs_scalar_ty.isSignedInt(zcu))4076 const reconstructed = try self.wip.bin(if (lhs_scalar_ty.isSignedInt(zcu))
...@@ -4128,29 +4098,28 @@ fn airShlWithOverflow(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -4128,29 +4098,28 @@ fn airShlWithOverflow(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
4128 return alloca_inst;4098 return alloca_inst;
4129}4099}
41304100
4131fn airAnd(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {4101fn airAnd(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
4132 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;4102 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
4133 const lhs = try self.resolveInst(bin_op.lhs);4103 const lhs = try self.resolveInst(bin_op.lhs);
4134 const rhs = try self.resolveInst(bin_op.rhs);4104 const rhs = try self.resolveInst(bin_op.rhs);
4135 return self.wip.bin(.@"and", lhs, rhs, "");4105 return self.wip.bin(.@"and", lhs, rhs, "");
4136}4106}
41374107
4138fn airOr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {4108fn airOr(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
4139 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;4109 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
4140 const lhs = try self.resolveInst(bin_op.lhs);4110 const lhs = try self.resolveInst(bin_op.lhs);
4141 const rhs = try self.resolveInst(bin_op.rhs);4111 const rhs = try self.resolveInst(bin_op.rhs);
4142 return self.wip.bin(.@"or", lhs, rhs, "");4112 return self.wip.bin(.@"or", lhs, rhs, "");
4143}4113}
41444114
4145fn airXor(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {4115fn airXor(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
4146 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;4116 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
4147 const lhs = try self.resolveInst(bin_op.lhs);4117 const lhs = try self.resolveInst(bin_op.lhs);
4148 const rhs = try self.resolveInst(bin_op.rhs);4118 const rhs = try self.resolveInst(bin_op.rhs);
4149 return self.wip.bin(.xor, lhs, rhs, "");4119 return self.wip.bin(.xor, lhs, rhs, "");
4150}4120}
41514121
4152fn airShlExact(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {4122fn airShlExact(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
4153 const o = self.object;
4154 const pt = self.pt;4123 const pt = self.pt;
4155 const zcu = pt.zcu;4124 const zcu = pt.zcu;
4156 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;4125 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
...@@ -4159,19 +4128,21 @@ fn airShlExact(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -4159,19 +4128,21 @@ fn airShlExact(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
4159 const rhs = try self.resolveInst(bin_op.rhs);4128 const rhs = try self.resolveInst(bin_op.rhs);
41604129
4161 const lhs_ty = self.typeOf(bin_op.lhs);4130 const lhs_ty = self.typeOf(bin_op.lhs);
4162 if (lhs_ty.isVector(zcu) and !self.typeOf(bin_op.rhs).isVector(zcu))4131 if (lhs_ty.isVector(zcu) and !self.typeOf(bin_op.rhs).isVector(zcu)) {
4163 return self.todo("implement vector shifts with scalar rhs", .{});4132 // `Sema` does not currently emit this pattern---instead it is specific to `Air.Legalize`
4133 // features which we do not use. Therefore this branch is currently impossible.
4134 unreachable;
4135 }
4164 const lhs_scalar_ty = lhs_ty.scalarType(zcu);4136 const lhs_scalar_ty = lhs_ty.scalarType(zcu);
41654137
4166 const casted_rhs = try self.wip.conv(.unsigned, rhs, try o.lowerType(pt, lhs_ty), "");4138 const casted_rhs = try self.wip.conv(.unsigned, rhs, try self.lowerType(lhs_ty), "");
4167 return self.wip.bin(if (lhs_scalar_ty.isSignedInt(zcu))4139 return self.wip.bin(if (lhs_scalar_ty.isSignedInt(zcu))
4168 .@"shl nsw"4140 .@"shl nsw"
4169 else4141 else
4170 .@"shl nuw", lhs, casted_rhs, "");4142 .@"shl nuw", lhs, casted_rhs, "");
4171}4143}
41724144
4173fn airShl(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {4145fn airShl(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
4174 const o = self.object;
4175 const pt = self.pt;4146 const pt = self.pt;
4176 const zcu = pt.zcu;4147 const zcu = pt.zcu;
4177 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;4148 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
...@@ -4180,14 +4151,16 @@ fn airShl(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -4180,14 +4151,16 @@ fn airShl(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
4180 const rhs = try self.resolveInst(bin_op.rhs);4151 const rhs = try self.resolveInst(bin_op.rhs);
41814152
4182 const lhs_ty = self.typeOf(bin_op.lhs);4153 const lhs_ty = self.typeOf(bin_op.lhs);
4183 if (lhs_ty.isVector(zcu) and !self.typeOf(bin_op.rhs).isVector(zcu))4154 if (lhs_ty.isVector(zcu) and !self.typeOf(bin_op.rhs).isVector(zcu)) {
4184 return self.todo("implement vector shifts with scalar rhs", .{});4155 // `Sema` does not currently emit this pattern---instead it is specific to `Air.Legalize`
41854156 // features which we do not use. Therefore this branch is currently impossible.
4186 const casted_rhs = try self.wip.conv(.unsigned, rhs, try o.lowerType(pt, lhs_ty), "");4157 unreachable;
4158 }
4159 const casted_rhs = try self.wip.conv(.unsigned, rhs, try self.lowerType(lhs_ty), "");
4187 return self.wip.bin(.shl, lhs, casted_rhs, "");4160 return self.wip.bin(.shl, lhs, casted_rhs, "");
4188}4161}
41894162
4190fn airShlSat(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {4163fn airShlSat(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
4191 const o = self.object;4164 const o = self.object;
4192 const pt = self.pt;4165 const pt = self.pt;
4193 const zcu = pt.zcu;4166 const zcu = pt.zcu;
...@@ -4198,15 +4171,18 @@ fn airShlSat(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -4198,15 +4171,18 @@ fn airShlSat(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
41984171
4199 const lhs_ty = self.typeOf(bin_op.lhs);4172 const lhs_ty = self.typeOf(bin_op.lhs);
4200 const lhs_info = lhs_ty.intInfo(zcu);4173 const lhs_info = lhs_ty.intInfo(zcu);
4201 const llvm_lhs_ty = try o.lowerType(pt, lhs_ty);4174 const llvm_lhs_ty = try self.lowerType(lhs_ty);
4202 const llvm_lhs_scalar_ty = llvm_lhs_ty.scalarType(&o.builder);4175 const llvm_lhs_scalar_ty = llvm_lhs_ty.scalarType(&o.builder);
42034176
4204 const rhs_ty = self.typeOf(bin_op.rhs);4177 const rhs_ty = self.typeOf(bin_op.rhs);
4205 if (lhs_ty.isVector(zcu) and !rhs_ty.isVector(zcu))4178 if (lhs_ty.isVector(zcu) and !rhs_ty.isVector(zcu)) {
4206 return self.todo("implement vector shifts with scalar rhs", .{});4179 // `Sema` does not currently emit this pattern---instead it is specific to `Air.Legalize`
4180 // features which we do not use. Therefore this branch is currently impossible.
4181 unreachable;
4182 }
4207 const rhs_info = rhs_ty.intInfo(zcu);4183 const rhs_info = rhs_ty.intInfo(zcu);
4208 assert(rhs_info.signedness == .unsigned);4184 assert(rhs_info.signedness == .unsigned);
4209 const llvm_rhs_ty = try o.lowerType(pt, rhs_ty);4185 const llvm_rhs_ty = try self.lowerType(rhs_ty);
4210 const llvm_rhs_scalar_ty = llvm_rhs_ty.scalarType(&o.builder);4186 const llvm_rhs_scalar_ty = llvm_rhs_ty.scalarType(&o.builder);
42114187
4212 const result = try self.wip.callIntrinsic(4188 const result = try self.wip.callIntrinsic(
...@@ -4267,8 +4243,7 @@ fn airShlSat(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -4267,8 +4243,7 @@ fn airShlSat(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
4267 return self.wip.select(.normal, in_range, result, lhs_sat, "");4243 return self.wip.select(.normal, in_range, result, lhs_sat, "");
4268}4244}
42694245
4270fn airShr(self: *FuncGen, inst: Air.Inst.Index, is_exact: bool) !Builder.Value {4246fn airShr(self: *FuncGen, inst: Air.Inst.Index, is_exact: bool) Allocator.Error!Builder.Value {
4271 const o = self.object;
4272 const pt = self.pt;4247 const pt = self.pt;
4273 const zcu = pt.zcu;4248 const zcu = pt.zcu;
4274 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;4249 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
...@@ -4277,11 +4252,14 @@ fn airShr(self: *FuncGen, inst: Air.Inst.Index, is_exact: bool) !Builder.Value {...@@ -4277,11 +4252,14 @@ fn airShr(self: *FuncGen, inst: Air.Inst.Index, is_exact: bool) !Builder.Value {
4277 const rhs = try self.resolveInst(bin_op.rhs);4252 const rhs = try self.resolveInst(bin_op.rhs);
42784253
4279 const lhs_ty = self.typeOf(bin_op.lhs);4254 const lhs_ty = self.typeOf(bin_op.lhs);
4280 if (lhs_ty.isVector(zcu) and !self.typeOf(bin_op.rhs).isVector(zcu))4255 if (lhs_ty.isVector(zcu) and !self.typeOf(bin_op.rhs).isVector(zcu)) {
4281 return self.todo("implement vector shifts with scalar rhs", .{});4256 // `Sema` does not currently emit this pattern---instead it is specific to `Air.Legalize`
4257 // features which we do not use. Therefore this branch is currently impossible.
4258 unreachable;
4259 }
4282 const lhs_scalar_ty = lhs_ty.scalarType(zcu);4260 const lhs_scalar_ty = lhs_ty.scalarType(zcu);
42834261
4284 const casted_rhs = try self.wip.conv(.unsigned, rhs, try o.lowerType(pt, lhs_ty), "");4262 const casted_rhs = try self.wip.conv(.unsigned, rhs, try self.lowerType(lhs_ty), "");
4285 const is_signed_int = lhs_scalar_ty.isSignedInt(zcu);4263 const is_signed_int = lhs_scalar_ty.isSignedInt(zcu);
42864264
4287 return self.wip.bin(if (is_exact)4265 return self.wip.bin(if (is_exact)
...@@ -4289,7 +4267,7 @@ fn airShr(self: *FuncGen, inst: Air.Inst.Index, is_exact: bool) !Builder.Value {...@@ -4289,7 +4267,7 @@ fn airShr(self: *FuncGen, inst: Air.Inst.Index, is_exact: bool) !Builder.Value {
4289 else if (is_signed_int) .ashr else .lshr, lhs, casted_rhs, "");4267 else if (is_signed_int) .ashr else .lshr, lhs, casted_rhs, "");
4290}4268}
42914269
4292fn airAbs(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {4270fn airAbs(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
4293 const o = self.object;4271 const o = self.object;
4294 const pt = self.pt;4272 const pt = self.pt;
4295 const zcu = pt.zcu;4273 const zcu = pt.zcu;
...@@ -4303,7 +4281,7 @@ fn airAbs(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -4303,7 +4281,7 @@ fn airAbs(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
4303 .normal,4281 .normal,
4304 .none,4282 .none,
4305 .abs,4283 .abs,
4306 &.{try o.lowerType(pt, operand_ty)},4284 &.{try self.lowerType(operand_ty)},
4307 &.{ operand, try o.builder.intValue(.i1, 0) },4285 &.{ operand, try o.builder.intValue(.i1, 0) },
4308 "",4286 "",
4309 ),4287 ),
...@@ -4312,13 +4290,13 @@ fn airAbs(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -4312,13 +4290,13 @@ fn airAbs(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
4312 }4290 }
4313}4291}
43144292
4315fn airIntCast(fg: *FuncGen, inst: Air.Inst.Index, safety: bool) !Builder.Value {4293fn airIntCast(fg: *FuncGen, inst: Air.Inst.Index, safety: bool) Allocator.Error!Builder.Value {
4316 const o = fg.object;4294 const o = fg.object;
4317 const pt = fg.pt;4295 const pt = fg.pt;
4318 const zcu = pt.zcu;4296 const zcu = pt.zcu;
4319 const ty_op = fg.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;4297 const ty_op = fg.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
4320 const dest_ty = fg.typeOfIndex(inst);4298 const dest_ty = fg.typeOfIndex(inst);
4321 const dest_llvm_ty = try o.lowerType(pt, dest_ty);4299 const dest_llvm_ty = try fg.lowerType(dest_ty);
4322 const operand = try fg.resolveInst(ty_op.operand);4300 const operand = try fg.resolveInst(ty_op.operand);
4323 const operand_ty = fg.typeOf(ty_op.operand);4301 const operand_ty = fg.typeOf(ty_op.operand);
4324 const operand_info = operand_ty.intInfo(zcu);4302 const operand_info = operand_ty.intInfo(zcu);
...@@ -4346,8 +4324,8 @@ fn airIntCast(fg: *FuncGen, inst: Air.Inst.Index, safety: bool) !Builder.Value {...@@ -4346,8 +4324,8 @@ fn airIntCast(fg: *FuncGen, inst: Air.Inst.Index, safety: bool) !Builder.Value {
43464324
4347 if (!have_min_check and !have_max_check) break :bounds_check;4325 if (!have_min_check and !have_max_check) break :bounds_check;
43484326
4349 const operand_llvm_ty = try o.lowerType(pt, operand_ty);4327 const operand_llvm_ty = try fg.lowerType(operand_ty);
4350 const operand_scalar_llvm_ty = try o.lowerType(pt, operand_scalar);4328 const operand_scalar_llvm_ty = try fg.lowerType(operand_scalar);
43514329
4352 const is_vector = operand_ty.zigTypeTag(zcu) == .vector;4330 const is_vector = operand_ty.zigTypeTag(zcu) == .vector;
4353 assert(is_vector == (dest_ty.zigTypeTag(zcu) == .vector));4331 assert(is_vector == (dest_ty.zigTypeTag(zcu) == .vector));
...@@ -4401,7 +4379,7 @@ fn airIntCast(fg: *FuncGen, inst: Air.Inst.Index, safety: bool) !Builder.Value {...@@ -4401,7 +4379,7 @@ fn airIntCast(fg: *FuncGen, inst: Air.Inst.Index, safety: bool) !Builder.Value {
4401 }, operand, dest_llvm_ty, "");4379 }, operand, dest_llvm_ty, "");
44024380
4403 if (safety and dest_is_enum and !dest_ty.isNonexhaustiveEnum(zcu)) {4381 if (safety and dest_is_enum and !dest_ty.isNonexhaustiveEnum(zcu)) {
4404 const llvm_fn = try fg.getIsNamedEnumValueFunction(dest_ty);4382 const llvm_fn = try o.getIsNamedEnumValueFunction(pt, dest_ty);
4405 const is_valid_enum_val = try fg.wip.call(4383 const is_valid_enum_val = try fg.wip.call(
4406 .normal,4384 .normal,
4407 .fastcc,4385 .fastcc,
...@@ -4422,16 +4400,14 @@ fn airIntCast(fg: *FuncGen, inst: Air.Inst.Index, safety: bool) !Builder.Value {...@@ -4422,16 +4400,14 @@ fn airIntCast(fg: *FuncGen, inst: Air.Inst.Index, safety: bool) !Builder.Value {
4422 return result;4400 return result;
4423}4401}
44244402
4425fn airTrunc(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {4403fn airTrunc(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
4426 const o = self.object;
4427 const pt = self.pt;
4428 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;4404 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
4429 const operand = try self.resolveInst(ty_op.operand);4405 const operand = try self.resolveInst(ty_op.operand);
4430 const dest_llvm_ty = try o.lowerType(pt, self.typeOfIndex(inst));4406 const dest_llvm_ty = try self.lowerType(self.typeOfIndex(inst));
4431 return self.wip.cast(.trunc, operand, dest_llvm_ty, "");4407 return self.wip.cast(.trunc, operand, dest_llvm_ty, "");
4432}4408}
44334409
4434fn airFptrunc(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {4410fn airFptrunc(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
4435 const o = self.object;4411 const o = self.object;
4436 const pt = self.pt;4412 const pt = self.pt;
4437 const zcu = pt.zcu;4413 const zcu = pt.zcu;
...@@ -4442,10 +4418,10 @@ fn airFptrunc(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -4442,10 +4418,10 @@ fn airFptrunc(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
4442 const target = zcu.getTarget();4418 const target = zcu.getTarget();
44434419
4444 if (intrinsicsAllowed(dest_ty, target) and intrinsicsAllowed(operand_ty, target)) {4420 if (intrinsicsAllowed(dest_ty, target) and intrinsicsAllowed(operand_ty, target)) {
4445 return self.wip.cast(.fptrunc, operand, try o.lowerType(pt, dest_ty), "");4421 return self.wip.cast(.fptrunc, operand, try self.lowerType(dest_ty), "");
4446 } else {4422 } else {
4447 const operand_llvm_ty = try o.lowerType(pt, operand_ty);4423 const operand_llvm_ty = try self.lowerType(operand_ty);
4448 const dest_llvm_ty = try o.lowerType(pt, dest_ty);4424 const dest_llvm_ty = try self.lowerType(dest_ty);
44494425
4450 const dest_bits = dest_ty.floatBits(target);4426 const dest_bits = dest_ty.floatBits(target);
4451 const src_bits = operand_ty.floatBits(target);4427 const src_bits = operand_ty.floatBits(target);
...@@ -4453,7 +4429,7 @@ fn airFptrunc(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -4453,7 +4429,7 @@ fn airFptrunc(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
4453 compilerRtFloatAbbrev(src_bits), compilerRtFloatAbbrev(dest_bits),4429 compilerRtFloatAbbrev(src_bits), compilerRtFloatAbbrev(dest_bits),
4454 });4430 });
44554431
4456 const libc_fn = try self.getLibcFunction(fn_name, &.{operand_llvm_ty}, dest_llvm_ty);4432 const libc_fn = try o.getLibcFunction(fn_name, &.{operand_llvm_ty}, dest_llvm_ty);
4457 return self.wip.call(4433 return self.wip.call(
4458 .normal,4434 .normal,
4459 .ccc,4435 .ccc,
...@@ -4466,7 +4442,7 @@ fn airFptrunc(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -4466,7 +4442,7 @@ fn airFptrunc(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
4466 }4442 }
4467}4443}
44684444
4469fn airFpext(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {4445fn airFpext(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
4470 const o = self.object;4446 const o = self.object;
4471 const pt = self.pt;4447 const pt = self.pt;
4472 const zcu = pt.zcu;4448 const zcu = pt.zcu;
...@@ -4477,10 +4453,10 @@ fn airFpext(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -4477,10 +4453,10 @@ fn airFpext(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
4477 const target = zcu.getTarget();4453 const target = zcu.getTarget();
44784454
4479 if (intrinsicsAllowed(dest_ty, target) and intrinsicsAllowed(operand_ty, target)) {4455 if (intrinsicsAllowed(dest_ty, target) and intrinsicsAllowed(operand_ty, target)) {
4480 return self.wip.cast(.fpext, operand, try o.lowerType(pt, dest_ty), "");4456 return self.wip.cast(.fpext, operand, try self.lowerType(dest_ty), "");
4481 } else {4457 } else {
4482 const operand_llvm_ty = try o.lowerType(pt, operand_ty);4458 const operand_llvm_ty = try self.lowerType(operand_ty);
4483 const dest_llvm_ty = try o.lowerType(pt, dest_ty);4459 const dest_llvm_ty = try self.lowerType(dest_ty);
44844460
4485 const dest_bits = dest_ty.scalarType(zcu).floatBits(target);4461 const dest_bits = dest_ty.scalarType(zcu).floatBits(target);
4486 const src_bits = operand_ty.scalarType(zcu).floatBits(target);4462 const src_bits = operand_ty.scalarType(zcu).floatBits(target);
...@@ -4488,7 +4464,7 @@ fn airFpext(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -4488,7 +4464,7 @@ fn airFpext(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
4488 compilerRtFloatAbbrev(src_bits), compilerRtFloatAbbrev(dest_bits),4464 compilerRtFloatAbbrev(src_bits), compilerRtFloatAbbrev(dest_bits),
4489 });4465 });
44904466
4491 const libc_fn = try self.getLibcFunction(fn_name, &.{operand_llvm_ty}, dest_llvm_ty);4467 const libc_fn = try o.getLibcFunction(fn_name, &.{operand_llvm_ty}, dest_llvm_ty);
4492 if (dest_ty.isVector(zcu)) return self.buildElementwiseCall(4468 if (dest_ty.isVector(zcu)) return self.buildElementwiseCall(
4493 libc_fn,4469 libc_fn,
4494 &.{operand},4470 &.{operand},
...@@ -4507,7 +4483,7 @@ fn airFpext(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -4507,7 +4483,7 @@ fn airFpext(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
4507 }4483 }
4508}4484}
45094485
4510fn airBitCast(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {4486fn airBitCast(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
4511 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;4487 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
4512 const operand_ty = self.typeOf(ty_op.operand);4488 const operand_ty = self.typeOf(ty_op.operand);
4513 const inst_ty = self.typeOfIndex(inst);4489 const inst_ty = self.typeOfIndex(inst);
...@@ -4515,13 +4491,13 @@ fn airBitCast(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -4515,13 +4491,13 @@ fn airBitCast(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
4515 return self.bitCast(operand, operand_ty, inst_ty);4491 return self.bitCast(operand, operand_ty, inst_ty);
4516}4492}
45174493
4518fn bitCast(self: *FuncGen, operand: Builder.Value, operand_ty: Type, inst_ty: Type) !Builder.Value {4494fn bitCast(self: *FuncGen, operand: Builder.Value, operand_ty: Type, inst_ty: Type) Allocator.Error!Builder.Value {
4519 const o = self.object;4495 const o = self.object;
4520 const pt = self.pt;4496 const pt = self.pt;
4521 const zcu = pt.zcu;4497 const zcu = pt.zcu;
4522 const operand_is_ref = isByRef(operand_ty, zcu);4498 const operand_is_ref = isByRef(operand_ty, zcu);
4523 const result_is_ref = isByRef(inst_ty, zcu);4499 const result_is_ref = isByRef(inst_ty, zcu);
4524 const llvm_dest_ty = try o.lowerType(pt, inst_ty);4500 const llvm_dest_ty = try self.lowerType(inst_ty);
45254501
4526 if (operand_is_ref and result_is_ref) {4502 if (operand_is_ref and result_is_ref) {
4527 // They are both pointers, so just return the same opaque pointer :)4503 // They are both pointers, so just return the same opaque pointer :)
...@@ -4544,11 +4520,8 @@ fn bitCast(self: *FuncGen, operand: Builder.Value, operand_ty: Type, inst_ty: Ty...@@ -4544,11 +4520,8 @@ fn bitCast(self: *FuncGen, operand: Builder.Value, operand_ty: Type, inst_ty: Ty
4544 }4520 }
45454521
4546 if (operand_ty.zigTypeTag(zcu) == .vector and inst_ty.zigTypeTag(zcu) == .array) {4522 if (operand_ty.zigTypeTag(zcu) == .vector and inst_ty.zigTypeTag(zcu) == .array) {
4547 const elem_ty = inst_ty.childType(zcu);4523 const elem_ty = operand_scalar_ty;
4548 assert(elem_ty.toIntern() == operand_scalar_ty.toIntern());4524 assert(result_is_ref); // arrays are always by-ref provided they have runtime bits
4549 if (!result_is_ref) {
4550 return self.todo("implement bitcast vector to non-ref array", .{});
4551 }
4552 const alignment = inst_ty.abiAlignment(zcu).toLlvm();4525 const alignment = inst_ty.abiAlignment(zcu).toLlvm();
4553 const array_ptr = try self.buildAlloca(llvm_dest_ty, alignment);4526 const array_ptr = try self.buildAlloca(llvm_dest_ty, alignment);
4554 const bitcast_ok = elem_ty.bitSize(zcu) == elem_ty.abiSize(zcu) * 8;4527 const bitcast_ok = elem_ty.bitSize(zcu) == elem_ty.abiSize(zcu) * 8;
...@@ -4569,9 +4542,8 @@ fn bitCast(self: *FuncGen, operand: Builder.Value, operand_ty: Type, inst_ty: Ty...@@ -4569,9 +4542,8 @@ fn bitCast(self: *FuncGen, operand: Builder.Value, operand_ty: Type, inst_ty: Ty
4569 return array_ptr;4542 return array_ptr;
4570 } else if (operand_ty.zigTypeTag(zcu) == .array and inst_ty.zigTypeTag(zcu) == .vector) {4543 } else if (operand_ty.zigTypeTag(zcu) == .array and inst_ty.zigTypeTag(zcu) == .vector) {
4571 const elem_ty = operand_ty.childType(zcu);4544 const elem_ty = operand_ty.childType(zcu);
4572 assert(elem_ty.toIntern() == inst_scalar_ty.toIntern());4545 assert(operand_is_ref); // arrays are always by-ref provided they have runtime bits
4573 const llvm_vector_ty = try o.lowerType(pt, inst_ty);4546 const llvm_vector_ty = try self.lowerType(inst_ty);
4574 if (!operand_is_ref) return self.todo("implement bitcast non-ref array to vector", .{});
45754547
4576 const bitcast_ok = elem_ty.bitSize(zcu) == elem_ty.abiSize(zcu) * 8;4548 const bitcast_ok = elem_ty.bitSize(zcu) == elem_ty.abiSize(zcu) * 8;
4577 if (bitcast_ok) {4549 if (bitcast_ok) {
...@@ -4582,7 +4554,7 @@ fn bitCast(self: *FuncGen, operand: Builder.Value, operand_ty: Type, inst_ty: Ty...@@ -4582,7 +4554,7 @@ fn bitCast(self: *FuncGen, operand: Builder.Value, operand_ty: Type, inst_ty: Ty
4582 } else {4554 } else {
4583 // If the ABI size of the element type is not evenly divisible by size in bits;4555 // If the ABI size of the element type is not evenly divisible by size in bits;
4584 // a simple bitcast will not work, and we fall back to extractelement.4556 // a simple bitcast will not work, and we fall back to extractelement.
4585 const elem_llvm_ty = try o.lowerType(pt, elem_ty);4557 const elem_llvm_ty = try self.lowerType(elem_ty);
4586 const elem_size = elem_ty.abiSize(zcu);4558 const elem_size = elem_ty.abiSize(zcu);
4587 const vector_len = operand_ty.arrayLen(zcu);4559 const vector_len = operand_ty.arrayLen(zcu);
4588 var vector = try o.builder.poisonValue(llvm_vector_ty);4560 var vector = try o.builder.poisonValue(llvm_vector_ty);
...@@ -4624,7 +4596,7 @@ fn bitCast(self: *FuncGen, operand: Builder.Value, operand_ty: Type, inst_ty: Ty...@@ -4624,7 +4596,7 @@ fn bitCast(self: *FuncGen, operand: Builder.Value, operand_ty: Type, inst_ty: Ty
4624 return self.wip.cast(.bitcast, operand, llvm_dest_ty, "");4596 return self.wip.cast(.bitcast, operand, llvm_dest_ty, "");
4625}4597}
46264598
4627fn airArg(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {4599fn airArg(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
4628 const o = self.object;4600 const o = self.object;
4629 const pt = self.pt;4601 const pt = self.pt;
4630 const zcu = pt.zcu;4602 const zcu = pt.zcu;
...@@ -4714,7 +4686,7 @@ fn airArg(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -4714,7 +4686,7 @@ fn airArg(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
4714 return arg_val;4686 return arg_val;
4715}4687}
47164688
4717fn airAlloc(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {4689fn airAlloc(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
4718 const o = self.object;4690 const o = self.object;
4719 const pt = self.pt;4691 const pt = self.pt;
4720 const zcu = pt.zcu;4692 const zcu = pt.zcu;
...@@ -4723,12 +4695,12 @@ fn airAlloc(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -4723,12 +4695,12 @@ fn airAlloc(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
4723 if (!pointee_type.hasRuntimeBits(zcu))4695 if (!pointee_type.hasRuntimeBits(zcu))
4724 return (try o.lowerPtrToVoid(pt, ptr_ty)).toValue();4696 return (try o.lowerPtrToVoid(pt, ptr_ty)).toValue();
47254697
4726 const pointee_llvm_ty = try o.lowerType(pt, pointee_type);4698 const pointee_llvm_ty = try self.lowerType(pointee_type);
4727 const alignment = ptr_ty.ptrAlignment(zcu).toLlvm();4699 const alignment = ptr_ty.ptrAlignment(zcu).toLlvm();
4728 return self.buildAlloca(pointee_llvm_ty, alignment);4700 return self.buildAlloca(pointee_llvm_ty, alignment);
4729}4701}
47304702
4731fn airRetPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {4703fn airRetPtr(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
4732 const o = self.object;4704 const o = self.object;
4733 const pt = self.pt;4705 const pt = self.pt;
4734 const zcu = pt.zcu;4706 const zcu = pt.zcu;
...@@ -4737,7 +4709,7 @@ fn airRetPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -4737,7 +4709,7 @@ fn airRetPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
4737 if (!ret_ty.hasRuntimeBits(zcu))4709 if (!ret_ty.hasRuntimeBits(zcu))
4738 return (try o.lowerPtrToVoid(pt, ptr_ty)).toValue();4710 return (try o.lowerPtrToVoid(pt, ptr_ty)).toValue();
4739 if (self.ret_ptr != .none) return self.ret_ptr;4711 if (self.ret_ptr != .none) return self.ret_ptr;
4740 const ret_llvm_ty = try o.lowerType(pt, ret_ty);4712 const ret_llvm_ty = try self.lowerType(ret_ty);
4741 const alignment = ptr_ty.ptrAlignment(zcu).toLlvm();4713 const alignment = ptr_ty.ptrAlignment(zcu).toLlvm();
4742 return self.buildAlloca(ret_llvm_ty, alignment);4714 return self.buildAlloca(ret_llvm_ty, alignment);
4743}4715}
...@@ -4753,7 +4725,7 @@ fn buildAlloca(...@@ -4753,7 +4725,7 @@ fn buildAlloca(
4753 return buildAllocaInner(&self.wip, llvm_ty, alignment, target);4725 return buildAllocaInner(&self.wip, llvm_ty, alignment, target);
4754}4726}
47554727
4756fn airStore(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !Builder.Value {4728fn airStore(self: *FuncGen, inst: Air.Inst.Index, safety: bool) Allocator.Error!Builder.Value {
4757 const o = self.object;4729 const o = self.object;
4758 const pt = self.pt;4730 const pt = self.pt;
4759 const zcu = pt.zcu;4731 const zcu = pt.zcu;
...@@ -4790,7 +4762,7 @@ fn airStore(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !Builder.Value {...@@ -4790,7 +4762,7 @@ fn airStore(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !Builder.Value {
47904762
4791 self.maybeMarkAllowZeroAccess(ptr_info);4763 self.maybeMarkAllowZeroAccess(ptr_info);
47924764
4793 const len = try o.builder.intValue(try o.lowerType(pt, Type.usize), operand_ty.abiSize(zcu));4765 const len = try o.builder.intValue(try self.lowerType(Type.usize), operand_ty.abiSize(zcu));
4794 _ = try self.wip.callMemSet(4766 _ = try self.wip.callMemSet(
4795 dest_ptr,4767 dest_ptr,
4796 ptr_ty.ptrAlignment(zcu).toLlvm(),4768 ptr_ty.ptrAlignment(zcu).toLlvm(),
...@@ -4812,7 +4784,7 @@ fn airStore(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !Builder.Value {...@@ -4812,7 +4784,7 @@ fn airStore(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !Builder.Value {
4812 return .none;4784 return .none;
4813}4785}
48144786
4815fn airLoad(fg: *FuncGen, inst: Air.Inst.Index) !Builder.Value {4787fn airLoad(fg: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
4816 const pt = fg.pt;4788 const pt = fg.pt;
4817 const zcu = pt.zcu;4789 const zcu = pt.zcu;
4818 const ty_op = fg.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;4790 const ty_op = fg.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
...@@ -4823,7 +4795,7 @@ fn airLoad(fg: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -4823,7 +4795,7 @@ fn airLoad(fg: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
4823 return fg.load(ptr, ptr_ty);4795 return fg.load(ptr, ptr_ty);
4824}4796}
48254797
4826fn airTrap(self: *FuncGen, inst: Air.Inst.Index) !void {4798fn airTrap(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!void {
4827 _ = inst;4799 _ = inst;
4828 const target = self.pt.zcu.getTarget();4800 const target = self.pt.zcu.getTarget();
4829 if ((target.cpu.arch == .mips or target.cpu.arch == .mipsel) and4801 if ((target.cpu.arch == .mips or target.cpu.arch == .mipsel) and
...@@ -4847,17 +4819,16 @@ fn airTrap(self: *FuncGen, inst: Air.Inst.Index) !void {...@@ -4847,17 +4819,16 @@ fn airTrap(self: *FuncGen, inst: Air.Inst.Index) !void {
4847 _ = try self.wip.@"unreachable"();4819 _ = try self.wip.@"unreachable"();
4848}4820}
48494821
4850fn airBreakpoint(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {4822fn airBreakpoint(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
4851 _ = inst;4823 _ = inst;
4852 _ = try self.wip.callIntrinsic(.normal, .none, .debugtrap, &.{}, &.{}, "");4824 _ = try self.wip.callIntrinsic(.normal, .none, .debugtrap, &.{}, &.{}, "");
4853 return .none;4825 return .none;
4854}4826}
48554827
4856fn airRetAddr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {4828fn airRetAddr(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
4857 _ = inst;4829 _ = inst;
4858 const o = self.object;4830 const o = self.object;
4859 const pt = self.pt;4831 const llvm_usize = try self.lowerType(Type.usize);
4860 const llvm_usize = try o.lowerType(pt, Type.usize);
4861 if (!target_util.supportsReturnAddress(self.pt.zcu.getTarget(), self.ownerModule().optimize_mode)) {4832 if (!target_util.supportsReturnAddress(self.pt.zcu.getTarget(), self.ownerModule().optimize_mode)) {
4862 // https://github.com/ziglang/zig/issues/119464833 // https://github.com/ziglang/zig/issues/11946
4863 return o.builder.intValue(llvm_usize, 0);4834 return o.builder.intValue(llvm_usize, 0);
...@@ -4866,19 +4837,17 @@ fn airRetAddr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -4866,19 +4837,17 @@ fn airRetAddr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
4866 return self.wip.cast(.ptrtoint, result, llvm_usize, "");4837 return self.wip.cast(.ptrtoint, result, llvm_usize, "");
4867}4838}
48684839
4869fn airFrameAddress(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {4840fn airFrameAddress(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
4870 _ = inst;4841 _ = inst;
4871 const o = self.object;
4872 const pt = self.pt;
4873 const result = try self.wip.callIntrinsic(.normal, .none, .frameaddress, &.{.ptr}, &.{.@"0"}, "");4842 const result = try self.wip.callIntrinsic(.normal, .none, .frameaddress, &.{.ptr}, &.{.@"0"}, "");
4874 return self.wip.cast(.ptrtoint, result, try o.lowerType(pt, Type.usize), "");4843 return self.wip.cast(.ptrtoint, result, try self.lowerType(Type.usize), "");
4875}4844}
48764845
4877fn airCmpxchg(4846fn airCmpxchg(
4878 self: *FuncGen,4847 self: *FuncGen,
4879 inst: Air.Inst.Index,4848 inst: Air.Inst.Index,
4880 kind: Builder.Function.Instruction.CmpXchg.Kind,4849 kind: Builder.Function.Instruction.CmpXchg.Kind,
4881) !Builder.Value {4850) Allocator.Error!Builder.Value {
4882 const o = self.object;4851 const o = self.object;
4883 const pt = self.pt;4852 const pt = self.pt;
4884 const zcu = pt.zcu;4853 const zcu = pt.zcu;
...@@ -4889,7 +4858,7 @@ fn airCmpxchg(...@@ -4889,7 +4858,7 @@ fn airCmpxchg(
4889 var expected_value = try self.resolveInst(extra.expected_value);4858 var expected_value = try self.resolveInst(extra.expected_value);
4890 var new_value = try self.resolveInst(extra.new_value);4859 var new_value = try self.resolveInst(extra.new_value);
4891 const operand_ty = ptr_ty.childType(zcu);4860 const operand_ty = ptr_ty.childType(zcu);
4892 const llvm_operand_ty = try o.lowerType(pt, operand_ty);4861 const llvm_operand_ty = try self.lowerType(operand_ty);
4893 const llvm_abi_ty = try self.getAtomicAbiType(operand_ty, false);4862 const llvm_abi_ty = try self.getAtomicAbiType(operand_ty, false);
4894 if (llvm_abi_ty != .none) {4863 if (llvm_abi_ty != .none) {
4895 // operand needs widening and truncating4864 // operand needs widening and truncating
...@@ -4932,7 +4901,7 @@ fn airCmpxchg(...@@ -4932,7 +4901,7 @@ fn airCmpxchg(
4932 const non_null_bit = try self.wip.not(success_bit, "");4901 const non_null_bit = try self.wip.not(success_bit, "");
49334902
4934 const payload_align = operand_ty.abiAlignment(zcu).toLlvm();4903 const payload_align = operand_ty.abiAlignment(zcu).toLlvm();
4935 const alloca_inst = try self.buildAlloca(try o.lowerType(pt, optional_ty), payload_align);4904 const alloca_inst = try self.buildAlloca(try self.lowerType(optional_ty), payload_align);
49364905
4937 // Payload is always the first field at offset 0, so address is `alloca_inst`4906 // Payload is always the first field at offset 0, so address is `alloca_inst`
4938 _ = try self.wip.store(.normal, payload, alloca_inst, payload_align);4907 _ = try self.wip.store(.normal, payload, alloca_inst, payload_align);
...@@ -4944,7 +4913,7 @@ fn airCmpxchg(...@@ -4944,7 +4913,7 @@ fn airCmpxchg(
4944 return alloca_inst;4913 return alloca_inst;
4945}4914}
49464915
4947fn airAtomicRmw(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {4916fn airAtomicRmw(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
4948 const o = self.object;4917 const o = self.object;
4949 const pt = self.pt;4918 const pt = self.pt;
4950 const zcu = pt.zcu;4919 const zcu = pt.zcu;
...@@ -4959,7 +4928,7 @@ fn airAtomicRmw(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -4959,7 +4928,7 @@ fn airAtomicRmw(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
4959 const op = toLlvmAtomicRmwBinOp(extra.op(), is_signed_int, is_float);4928 const op = toLlvmAtomicRmwBinOp(extra.op(), is_signed_int, is_float);
4960 const ordering = toLlvmAtomicOrdering(extra.ordering());4929 const ordering = toLlvmAtomicOrdering(extra.ordering());
4961 const llvm_abi_ty = try self.getAtomicAbiType(operand_ty, op == .xchg);4930 const llvm_abi_ty = try self.getAtomicAbiType(operand_ty, op == .xchg);
4962 const llvm_operand_ty = try o.lowerType(pt, operand_ty);4931 const llvm_operand_ty = try self.lowerType(operand_ty);
49634932
4964 const access_kind: Builder.MemoryAccessKind =4933 const access_kind: Builder.MemoryAccessKind =
4965 if (ptr_ty.isVolatilePtr(zcu)) .@"volatile" else .normal;4934 if (ptr_ty.isVolatilePtr(zcu)) .@"volatile" else .normal;
...@@ -5002,7 +4971,7 @@ fn airAtomicRmw(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -5002,7 +4971,7 @@ fn airAtomicRmw(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
5002 access_kind,4971 access_kind,
5003 op,4972 op,
5004 ptr,4973 ptr,
5005 try self.wip.cast(.ptrtoint, operand, try o.lowerType(pt, Type.usize), ""),4974 try self.wip.cast(.ptrtoint, operand, try self.lowerType(Type.usize), ""),
5006 self.sync_scope,4975 self.sync_scope,
5007 ordering,4976 ordering,
5008 ptr_alignment,4977 ptr_alignment,
...@@ -5010,8 +4979,7 @@ fn airAtomicRmw(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -5010,8 +4979,7 @@ fn airAtomicRmw(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
5010 ), llvm_operand_ty, "");4979 ), llvm_operand_ty, "");
5011}4980}
50124981
5013fn airAtomicLoad(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {4982fn airAtomicLoad(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
5014 const o = self.object;
5015 const pt = self.pt;4983 const pt = self.pt;
5016 const zcu = pt.zcu;4984 const zcu = pt.zcu;
5017 const atomic_load = self.air.instructions.items(.data)[@intFromEnum(inst)].atomic_load;4985 const atomic_load = self.air.instructions.items(.data)[@intFromEnum(inst)].atomic_load;
...@@ -5028,7 +4996,7 @@ fn airAtomicLoad(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -5028,7 +4996,7 @@ fn airAtomicLoad(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
5028 Type.fromInterned(info.child).abiAlignment(zcu)).toLlvm();4996 Type.fromInterned(info.child).abiAlignment(zcu)).toLlvm();
5029 const access_kind: Builder.MemoryAccessKind =4997 const access_kind: Builder.MemoryAccessKind =
5030 if (info.flags.is_volatile) .@"volatile" else .normal;4998 if (info.flags.is_volatile) .@"volatile" else .normal;
5031 const elem_llvm_ty = try o.lowerType(pt, elem_ty);4999 const elem_llvm_ty = try self.lowerType(elem_ty);
50325000
5033 self.maybeMarkAllowZeroAccess(info);5001 self.maybeMarkAllowZeroAccess(info);
50345002
...@@ -5060,7 +5028,7 @@ fn airAtomicStore(...@@ -5060,7 +5028,7 @@ fn airAtomicStore(
5060 self: *FuncGen,5028 self: *FuncGen,
5061 inst: Air.Inst.Index,5029 inst: Air.Inst.Index,
5062 ordering: Builder.AtomicOrdering,5030 ordering: Builder.AtomicOrdering,
5063) !Builder.Value {5031) Allocator.Error!Builder.Value {
5064 const pt = self.pt;5032 const pt = self.pt;
5065 const zcu = pt.zcu;5033 const zcu = pt.zcu;
5066 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;5034 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
...@@ -5087,7 +5055,7 @@ fn airAtomicStore(...@@ -5087,7 +5055,7 @@ fn airAtomicStore(
5087 return .none;5055 return .none;
5088}5056}
50895057
5090fn airMemset(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !Builder.Value {5058fn airMemset(self: *FuncGen, inst: Air.Inst.Index, safety: bool) Allocator.Error!Builder.Value {
5091 const o = self.object;5059 const o = self.object;
5092 const pt = self.pt;5060 const pt = self.pt;
5093 const zcu = pt.zcu;5061 const zcu = pt.zcu;
...@@ -5186,7 +5154,7 @@ fn airMemset(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !Builder.Value...@@ -5186,7 +5154,7 @@ fn airMemset(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !Builder.Value
5186 const body_block = try self.wip.block(1, "InlineMemsetBody");5154 const body_block = try self.wip.block(1, "InlineMemsetBody");
5187 const end_block = try self.wip.block(1, "InlineMemsetEnd");5155 const end_block = try self.wip.block(1, "InlineMemsetEnd");
51885156
5189 const llvm_usize_ty = try o.lowerType(pt, Type.usize);5157 const llvm_usize_ty = try self.lowerType(Type.usize);
5190 const end_ptr = switch (ptr_ty.ptrSize(zcu)) {5158 const end_ptr = switch (ptr_ty.ptrSize(zcu)) {
5191 .slice => try self.ptraddScaled(5159 .slice => try self.ptraddScaled(
5192 dest_ptr,5160 dest_ptr,
...@@ -5225,7 +5193,7 @@ fn airMemset(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !Builder.Value...@@ -5225,7 +5193,7 @@ fn airMemset(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !Builder.Value
5225 return .none;5193 return .none;
5226}5194}
52275195
5228fn airMemcpy(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {5196fn airMemcpy(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
5229 const pt = self.pt;5197 const pt = self.pt;
5230 const zcu = pt.zcu;5198 const zcu = pt.zcu;
5231 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;5199 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
...@@ -5254,7 +5222,7 @@ fn airMemcpy(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -5254,7 +5222,7 @@ fn airMemcpy(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
5254 return .none;5222 return .none;
5255}5223}
52565224
5257fn airMemmove(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {5225fn airMemmove(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
5258 const pt = self.pt;5226 const pt = self.pt;
5259 const zcu = pt.zcu;5227 const zcu = pt.zcu;
5260 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;5228 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
...@@ -5279,14 +5247,15 @@ fn airMemmove(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -5279,14 +5247,15 @@ fn airMemmove(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
5279 return .none;5247 return .none;
5280}5248}
52815249
5282fn airSetUnionTag(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {5250fn airSetUnionTag(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
5283 const pt = self.pt;5251 const pt = self.pt;
5284 const zcu = pt.zcu;5252 const zcu = pt.zcu;
5285 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;5253 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
5286 const un_ptr_ty = self.typeOf(bin_op.lhs);5254 const un_ptr_ty = self.typeOf(bin_op.lhs);
5287 const un_ty = un_ptr_ty.childType(zcu);5255 const un_ty = un_ptr_ty.childType(zcu);
5288 const layout = un_ty.unionGetLayout(zcu);5256 const layout = un_ty.unionGetLayout(zcu);
5289 assert(layout.tag_size != 0);5257
5258 if (layout.tag_size == 0) return .none; // TODO: stop Sema emitting this
52905259
5291 const access_kind: Builder.MemoryAccessKind =5260 const access_kind: Builder.MemoryAccessKind =
5292 if (un_ptr_ty.isVolatilePtr(zcu)) .@"volatile" else .normal;5261 if (un_ptr_ty.isVolatilePtr(zcu)) .@"volatile" else .normal;
...@@ -5309,7 +5278,7 @@ fn airSetUnionTag(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -5309,7 +5278,7 @@ fn airSetUnionTag(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
5309 return .none;5278 return .none;
5310}5279}
53115280
5312fn airGetUnionTag(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {5281fn airGetUnionTag(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
5313 const o = self.object;5282 const o = self.object;
5314 const pt = self.pt;5283 const pt = self.pt;
5315 const zcu = pt.zcu;5284 const zcu = pt.zcu;
...@@ -5319,7 +5288,7 @@ fn airGetUnionTag(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -5319,7 +5288,7 @@ fn airGetUnionTag(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
5319 assert(layout.tag_size != 0);5288 assert(layout.tag_size != 0);
5320 const union_ptr = try self.resolveInst(ty_op.operand);5289 const union_ptr = try self.resolveInst(ty_op.operand);
5321 if (isByRef(un_ty, zcu)) {5290 if (isByRef(un_ty, zcu)) {
5322 const llvm_un_ty = try o.lowerType(pt, un_ty);5291 const llvm_un_ty = try self.lowerType(un_ty);
5323 if (layout.payload_size == 0)5292 if (layout.payload_size == 0)
5324 return self.wip.load(.normal, llvm_un_ty, union_ptr, .default, "");5293 return self.wip.load(.normal, llvm_un_ty, union_ptr, .default, "");
5325 const tag_index = @intFromBool(layout.tag_align.compare(.lt, layout.payload_align));5294 const tag_index = @intFromBool(layout.tag_align.compare(.lt, layout.payload_align));
...@@ -5333,7 +5302,7 @@ fn airGetUnionTag(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -5333,7 +5302,7 @@ fn airGetUnionTag(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
5333 }5302 }
5334}5303}
53355304
5336fn airUnaryOp(self: *FuncGen, inst: Air.Inst.Index, comptime op: FloatOp) !Builder.Value {5305fn airUnaryOp(self: *FuncGen, inst: Air.Inst.Index, comptime op: FloatOp) Allocator.Error!Builder.Value {
5337 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;5306 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
5338 const operand = try self.resolveInst(un_op);5307 const operand = try self.resolveInst(un_op);
5339 const operand_ty = self.typeOf(un_op);5308 const operand_ty = self.typeOf(un_op);
...@@ -5341,7 +5310,7 @@ fn airUnaryOp(self: *FuncGen, inst: Air.Inst.Index, comptime op: FloatOp) !Build...@@ -5341,7 +5310,7 @@ fn airUnaryOp(self: *FuncGen, inst: Air.Inst.Index, comptime op: FloatOp) !Build
5341 return self.buildFloatOp(op, .normal, operand_ty, 1, .{operand});5310 return self.buildFloatOp(op, .normal, operand_ty, 1, .{operand});
5342}5311}
53435312
5344fn airNeg(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value {5313fn airNeg(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) Allocator.Error!Builder.Value {
5345 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;5314 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
5346 const operand = try self.resolveInst(un_op);5315 const operand = try self.resolveInst(un_op);
5347 const operand_ty = self.typeOf(un_op);5316 const operand_ty = self.typeOf(un_op);
...@@ -5349,9 +5318,7 @@ fn airNeg(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Bui...@@ -5349,9 +5318,7 @@ fn airNeg(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Bui
5349 return self.buildFloatOp(.neg, fast, operand_ty, 1, .{operand});5318 return self.buildFloatOp(.neg, fast, operand_ty, 1, .{operand});
5350}5319}
53515320
5352fn airClzCtz(self: *FuncGen, inst: Air.Inst.Index, intrinsic: Builder.Intrinsic) !Builder.Value {5321fn airClzCtz(self: *FuncGen, inst: Air.Inst.Index, intrinsic: Builder.Intrinsic) Allocator.Error!Builder.Value {
5353 const o = self.object;
5354 const pt = self.pt;
5355 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;5322 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
5356 const inst_ty = self.typeOfIndex(inst);5323 const inst_ty = self.typeOfIndex(inst);
5357 const operand_ty = self.typeOf(ty_op.operand);5324 const operand_ty = self.typeOf(ty_op.operand);
...@@ -5361,16 +5328,14 @@ fn airClzCtz(self: *FuncGen, inst: Air.Inst.Index, intrinsic: Builder.Intrinsic)...@@ -5361,16 +5328,14 @@ fn airClzCtz(self: *FuncGen, inst: Air.Inst.Index, intrinsic: Builder.Intrinsic)
5361 .normal,5328 .normal,
5362 .none,5329 .none,
5363 intrinsic,5330 intrinsic,
5364 &.{try o.lowerType(pt, operand_ty)},5331 &.{try self.lowerType(operand_ty)},
5365 &.{ operand, .false },5332 &.{ operand, .false },
5366 "",5333 "",
5367 );5334 );
5368 return self.wip.conv(.unsigned, result, try o.lowerType(pt, inst_ty), "");5335 return self.wip.conv(.unsigned, result, try self.lowerType(inst_ty), "");
5369}5336}
53705337
5371fn airBitOp(self: *FuncGen, inst: Air.Inst.Index, intrinsic: Builder.Intrinsic) !Builder.Value {5338fn airBitOp(self: *FuncGen, inst: Air.Inst.Index, intrinsic: Builder.Intrinsic) Allocator.Error!Builder.Value {
5372 const o = self.object;
5373 const pt = self.pt;
5374 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;5339 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
5375 const inst_ty = self.typeOfIndex(inst);5340 const inst_ty = self.typeOfIndex(inst);
5376 const operand_ty = self.typeOf(ty_op.operand);5341 const operand_ty = self.typeOf(ty_op.operand);
...@@ -5380,14 +5345,14 @@ fn airBitOp(self: *FuncGen, inst: Air.Inst.Index, intrinsic: Builder.Intrinsic)...@@ -5380,14 +5345,14 @@ fn airBitOp(self: *FuncGen, inst: Air.Inst.Index, intrinsic: Builder.Intrinsic)
5380 .normal,5345 .normal,
5381 .none,5346 .none,
5382 intrinsic,5347 intrinsic,
5383 &.{try o.lowerType(pt, operand_ty)},5348 &.{try self.lowerType(operand_ty)},
5384 &.{operand},5349 &.{operand},
5385 "",5350 "",
5386 );5351 );
5387 return self.wip.conv(.unsigned, result, try o.lowerType(pt, inst_ty), "");5352 return self.wip.conv(.unsigned, result, try self.lowerType(inst_ty), "");
5388}5353}
53895354
5390fn airByteSwap(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {5355fn airByteSwap(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
5391 const o = self.object;5356 const o = self.object;
5392 const pt = self.pt;5357 const pt = self.pt;
5393 const zcu = pt.zcu;5358 const zcu = pt.zcu;
...@@ -5398,7 +5363,7 @@ fn airByteSwap(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -5398,7 +5363,7 @@ fn airByteSwap(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
53985363
5399 const inst_ty = self.typeOfIndex(inst);5364 const inst_ty = self.typeOfIndex(inst);
5400 var operand = try self.resolveInst(ty_op.operand);5365 var operand = try self.resolveInst(ty_op.operand);
5401 var llvm_operand_ty = try o.lowerType(pt, operand_ty);5366 var llvm_operand_ty = try self.lowerType(operand_ty);
54025367
5403 if (bits % 16 == 8) {5368 if (bits % 16 == 8) {
5404 // If not an even byte-multiple, we need zero-extend + shift-left 1 byte5369 // If not an even byte-multiple, we need zero-extend + shift-left 1 byte
...@@ -5419,10 +5384,10 @@ fn airByteSwap(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -5419,10 +5384,10 @@ fn airByteSwap(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
54195384
5420 const result =5385 const result =
5421 try self.wip.callIntrinsic(.normal, .none, .bswap, &.{llvm_operand_ty}, &.{operand}, "");5386 try self.wip.callIntrinsic(.normal, .none, .bswap, &.{llvm_operand_ty}, &.{operand}, "");
5422 return self.wip.conv(.unsigned, result, try o.lowerType(pt, inst_ty), "");5387 return self.wip.conv(.unsigned, result, try self.lowerType(inst_ty), "");
5423}5388}
54245389
5425fn airErrorSetHasValue(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {5390fn airErrorSetHasValue(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
5426 const o = self.object;5391 const o = self.object;
5427 const pt = self.pt;5392 const pt = self.pt;
5428 const zcu = pt.zcu;5393 const zcu = pt.zcu;
...@@ -5440,7 +5405,7 @@ fn airErrorSetHasValue(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -5440,7 +5405,7 @@ fn airErrorSetHasValue(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
54405405
5441 for (0..names.len) |name_index| {5406 for (0..names.len) |name_index| {
5442 const err_int = ip.getErrorValueIfExists(names.get(ip)[name_index]).?;5407 const err_int = ip.getErrorValueIfExists(names.get(ip)[name_index]).?;
5443 const this_tag_int_value = try o.builder.intConst(try o.errorIntType(pt), err_int);5408 const this_tag_int_value = try o.builder.intConst(try o.errorIntType(), err_int);
5444 try wip_switch.addCase(this_tag_int_value, valid_block, &self.wip);5409 try wip_switch.addCase(this_tag_int_value, valid_block, &self.wip);
5445 }5410 }
5446 self.wip.cursor = .{ .block = valid_block };5411 self.wip.cursor = .{ .block = valid_block };
...@@ -5455,13 +5420,13 @@ fn airErrorSetHasValue(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -5455,13 +5420,13 @@ fn airErrorSetHasValue(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
5455 return phi.toValue();5420 return phi.toValue();
5456}5421}
54575422
5458fn airIsNamedEnumValue(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {5423fn airIsNamedEnumValue(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
5459 const o = self.object;5424 const o = self.object;
5460 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;5425 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
5461 const operand = try self.resolveInst(un_op);5426 const operand = try self.resolveInst(un_op);
5462 const enum_ty = self.typeOf(un_op);5427 const enum_ty = self.typeOf(un_op);
54635428
5464 const llvm_fn = try self.getIsNamedEnumValueFunction(enum_ty);5429 const llvm_fn = try o.getIsNamedEnumValueFunction(self.pt, enum_ty);
5465 return self.wip.call(5430 return self.wip.call(
5466 .normal,5431 .normal,
5467 .fastcc,5432 .fastcc,
...@@ -5473,28 +5438,7 @@ fn airIsNamedEnumValue(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -5473,28 +5438,7 @@ fn airIsNamedEnumValue(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
5473 );5438 );
5474}5439}
54755440
5476fn getIsNamedEnumValueFunction(self: *FuncGen, enum_ty: Type) !Builder.Function.Index {5441fn airTagName(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
5477 const o = self.object;
5478 const pt = self.pt;
5479 const zcu = pt.zcu;
5480 const ip = &zcu.intern_pool;
5481
5482 const gop = try o.named_enum_map.getOrPut(o.gpa, enum_ty.toIntern());
5483 if (gop.found_existing) return gop.value_ptr.*;
5484 errdefer assert(o.named_enum_map.remove(enum_ty.toIntern()));
5485 const function_index = try o.builder.addFunction(
5486 // Dummy function type; `updateIsNamedEnumValue` will replace it with the correct type.
5487 // TODO: change the builder API so we don't need to do this.
5488 try o.builder.fnType(.void, &.{}, .normal),
5489 try o.builder.strtabStringFmt("__zig_is_named_enum_value_{f}", .{enum_ty.containerTypeName(ip).fmt(ip)}),
5490 toLlvmAddressSpace(.generic, zcu.getTarget()),
5491 );
5492 gop.value_ptr.* = function_index;
5493 try o.updateIsNamedEnumValueFunction(pt, enum_ty, function_index);
5494 return function_index;
5495}
5496
5497fn airTagName(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
5498 const o = self.object;5442 const o = self.object;
5499 const pt = self.pt;5443 const pt = self.pt;
5500 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;5444 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
...@@ -5513,34 +5457,31 @@ fn airTagName(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -5513,34 +5457,31 @@ fn airTagName(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
5513 );5457 );
5514}5458}
55155459
5516fn airErrorName(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {5460fn airErrorName(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
5517 const o = self.object;5461 const o = self.object;
5518 const pt = self.pt;5462 const pt = self.pt;
5519 const zcu = pt.zcu;5463 const zcu = pt.zcu;
5520 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;5464 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
5521 const operand = try self.resolveInst(un_op);5465 const operand = try self.resolveInst(un_op);
5522 const slice_ty = self.typeOfIndex(inst);5466 const slice_ty = self.typeOfIndex(inst);
5523 const slice_llvm_ty = try o.lowerType(pt, slice_ty);5467 const slice_llvm_ty = try self.lowerType(slice_ty);
55245468
5525 // If operand is small (e.g. `u8`), then signedness becomes a problem -- GEP always treats the index as signed.5469 // If operand is small (e.g. `u8`), then signedness becomes a problem -- GEP always treats the index as signed.
5526 const operand_usize = try self.wip.conv(.unsigned, operand, try o.lowerType(pt, .usize), "");5470 const operand_usize = try self.wip.conv(.unsigned, operand, try self.lowerType(.usize), "");
55275471
5528 const error_name_table_ptr = try self.getErrorNameTable();5472 const error_name_table_ptr = try o.getErrorNameTable();
5529 const error_name_table = try self.wip.load(.normal, .ptr, error_name_table_ptr.toValue(&o.builder), .default, "");5473 const error_name_ptr = try self.ptraddScaled(error_name_table_ptr.toValue(&o.builder), operand_usize, slice_ty.abiSize(zcu));
5530 const error_name_ptr = try self.ptraddScaled(error_name_table, operand_usize, slice_ty.abiSize(zcu));
5531 return self.wip.load(.normal, slice_llvm_ty, error_name_ptr, .default, "");5474 return self.wip.load(.normal, slice_llvm_ty, error_name_ptr, .default, "");
5532}5475}
55335476
5534fn airSplat(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {5477fn airSplat(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
5535 const o = self.object;
5536 const pt = self.pt;
5537 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;5478 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
5538 const scalar = try self.resolveInst(ty_op.operand);5479 const scalar = try self.resolveInst(ty_op.operand);
5539 const vector_ty = self.typeOfIndex(inst);5480 const vector_ty = self.typeOfIndex(inst);
5540 return self.wip.splatVector(try o.lowerType(pt, vector_ty), scalar, "");5481 return self.wip.splatVector(try self.lowerType(vector_ty), scalar, "");
5541}5482}
55425483
5543fn airSelect(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {5484fn airSelect(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
5544 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;5485 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
5545 const extra = self.air.extraData(Air.Bin, pl_op.payload).data;5486 const extra = self.air.extraData(Air.Bin, pl_op.payload).data;
5546 const pred = try self.resolveInst(pl_op.operand);5487 const pred = try self.resolveInst(pl_op.operand);
...@@ -5550,7 +5491,7 @@ fn airSelect(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -5550,7 +5491,7 @@ fn airSelect(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
5550 return self.wip.select(.normal, pred, a, b, "");5491 return self.wip.select(.normal, pred, a, b, "");
5551}5492}
55525493
5553fn airShuffleOne(fg: *FuncGen, inst: Air.Inst.Index) !Builder.Value {5494fn airShuffleOne(fg: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
5554 const o = fg.object;5495 const o = fg.object;
5555 const pt = fg.pt;5496 const pt = fg.pt;
5556 const zcu = pt.zcu;5497 const zcu = pt.zcu;
...@@ -5561,9 +5502,9 @@ fn airShuffleOne(fg: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -5561,9 +5502,9 @@ fn airShuffleOne(fg: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
5561 const operand = try fg.resolveInst(unwrapped.operand);5502 const operand = try fg.resolveInst(unwrapped.operand);
5562 const mask = unwrapped.mask;5503 const mask = unwrapped.mask;
5563 const operand_ty = fg.typeOf(unwrapped.operand);5504 const operand_ty = fg.typeOf(unwrapped.operand);
5564 const llvm_operand_ty = try o.lowerType(pt, operand_ty);5505 const llvm_operand_ty = try fg.lowerType(operand_ty);
5565 const llvm_result_ty = try o.lowerType(pt, unwrapped.result_ty);5506 const llvm_result_ty = try fg.lowerType(unwrapped.result_ty);
5566 const llvm_elem_ty = try o.lowerType(pt, unwrapped.result_ty.childType(zcu));5507 const llvm_elem_ty = try fg.lowerType(unwrapped.result_ty.childType(zcu));
5567 const llvm_poison_elem = try o.builder.poisonConst(llvm_elem_ty);5508 const llvm_poison_elem = try o.builder.poisonConst(llvm_elem_ty);
5568 const llvm_poison_mask_elem = try o.builder.poisonConst(.i32);5509 const llvm_poison_mask_elem = try o.builder.poisonConst(.i32);
5569 const llvm_mask_ty = try o.builder.vectorType(.normal, @intCast(mask.len), .i32);5510 const llvm_mask_ty = try o.builder.vectorType(.normal, @intCast(mask.len), .i32);
...@@ -5657,7 +5598,7 @@ fn airShuffleOne(fg: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -5657,7 +5598,7 @@ fn airShuffleOne(fg: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
5657 );5598 );
5658}5599}
56595600
5660fn airShuffleTwo(fg: *FuncGen, inst: Air.Inst.Index) !Builder.Value {5601fn airShuffleTwo(fg: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
5661 const o = fg.object;5602 const o = fg.object;
5662 const pt = fg.pt;5603 const pt = fg.pt;
5663 const zcu = pt.zcu;5604 const zcu = pt.zcu;
...@@ -5666,7 +5607,7 @@ fn airShuffleTwo(fg: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -5666,7 +5607,7 @@ fn airShuffleTwo(fg: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
5666 const unwrapped = fg.air.unwrapShuffleTwo(zcu, inst);5607 const unwrapped = fg.air.unwrapShuffleTwo(zcu, inst);
56675608
5668 const mask = unwrapped.mask;5609 const mask = unwrapped.mask;
5669 const llvm_elem_ty = try o.lowerType(pt, unwrapped.result_ty.childType(zcu));5610 const llvm_elem_ty = try fg.lowerType(unwrapped.result_ty.childType(zcu));
5670 const llvm_mask_ty = try o.builder.vectorType(.normal, @intCast(mask.len), .i32);5611 const llvm_mask_ty = try o.builder.vectorType(.normal, @intCast(mask.len), .i32);
5671 const llvm_poison_mask_elem = try o.builder.poisonConst(.i32);5612 const llvm_poison_mask_elem = try o.builder.poisonConst(.i32);
56725613
...@@ -5756,10 +5697,9 @@ fn buildReducedCall(...@@ -5756,10 +5697,9 @@ fn buildReducedCall(
5756 operand_vector: Builder.Value,5697 operand_vector: Builder.Value,
5757 vector_len: usize,5698 vector_len: usize,
5758 accum_init: Builder.Value,5699 accum_init: Builder.Value,
5759) !Builder.Value {5700) Allocator.Error!Builder.Value {
5760 const o = self.object;5701 const o = self.object;
5761 const pt = self.pt;5702 const usize_ty = try self.lowerType(Type.usize);
5762 const usize_ty = try o.lowerType(pt, Type.usize);
5763 const llvm_vector_len = try o.builder.intValue(usize_ty, vector_len);5703 const llvm_vector_len = try o.builder.intValue(usize_ty, vector_len);
5764 const llvm_result_ty = accum_init.typeOfWip(&self.wip);5704 const llvm_result_ty = accum_init.typeOfWip(&self.wip);
57655705
...@@ -5811,7 +5751,7 @@ fn buildReducedCall(...@@ -5811,7 +5751,7 @@ fn buildReducedCall(
5811 return self.wip.load(.normal, llvm_result_ty, accum_ptr, .default, "");5751 return self.wip.load(.normal, llvm_result_ty, accum_ptr, .default, "");
5812}5752}
58135753
5814fn airReduce(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value {5754fn airReduce(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) Allocator.Error!Builder.Value {
5815 const o = self.object;5755 const o = self.object;
5816 const pt = self.pt;5756 const pt = self.pt;
5817 const zcu = pt.zcu;5757 const zcu = pt.zcu;
...@@ -5820,9 +5760,9 @@ fn airReduce(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !...@@ -5820,9 +5760,9 @@ fn airReduce(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !
5820 const reduce = self.air.instructions.items(.data)[@intFromEnum(inst)].reduce;5760 const reduce = self.air.instructions.items(.data)[@intFromEnum(inst)].reduce;
5821 const operand = try self.resolveInst(reduce.operand);5761 const operand = try self.resolveInst(reduce.operand);
5822 const operand_ty = self.typeOf(reduce.operand);5762 const operand_ty = self.typeOf(reduce.operand);
5823 const llvm_operand_ty = try o.lowerType(pt, operand_ty);5763 const llvm_operand_ty = try self.lowerType(operand_ty);
5824 const scalar_ty = self.typeOfIndex(inst);5764 const scalar_ty = self.typeOfIndex(inst);
5825 const llvm_scalar_ty = try o.lowerType(pt, scalar_ty);5765 const llvm_scalar_ty = try self.lowerType(scalar_ty);
58265766
5827 switch (reduce.operation) {5767 switch (reduce.operation) {
5828 .And, .Or, .Xor => return self.wip.callIntrinsic(.normal, .none, switch (reduce.operation) {5768 .And, .Or, .Xor => return self.wip.callIntrinsic(.normal, .none, switch (reduce.operation) {
...@@ -5890,8 +5830,7 @@ fn airReduce(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !...@@ -5890,8 +5830,7 @@ fn airReduce(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !
5890 else => unreachable,5830 else => unreachable,
5891 };5831 };
58925832
5893 const libc_fn =5833 const libc_fn = try o.getLibcFunction(fn_name, &.{ llvm_scalar_ty, llvm_scalar_ty }, llvm_scalar_ty);
5894 try self.getLibcFunction(fn_name, &.{ llvm_scalar_ty, llvm_scalar_ty }, llvm_scalar_ty);
5895 const init_val = switch (llvm_scalar_ty) {5834 const init_val = switch (llvm_scalar_ty) {
5896 .i16 => try o.builder.intValue(.i16, @as(i16, @bitCast(5835 .i16 => try o.builder.intValue(.i16, @as(i16, @bitCast(
5897 @as(f16, switch (reduce.operation) {5836 @as(f16, switch (reduce.operation) {
...@@ -5922,7 +5861,7 @@ fn airReduce(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !...@@ -5922,7 +5861,7 @@ fn airReduce(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !
5922 return self.buildReducedCall(libc_fn, operand, operand_ty.vectorLen(zcu), init_val);5861 return self.buildReducedCall(libc_fn, operand, operand_ty.vectorLen(zcu), init_val);
5923}5862}
59245863
5925fn airAggregateInit(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {5864fn airAggregateInit(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
5926 const o = self.object;5865 const o = self.object;
5927 const pt = self.pt;5866 const pt = self.pt;
5928 const zcu = pt.zcu;5867 const zcu = pt.zcu;
...@@ -5931,7 +5870,7 @@ fn airAggregateInit(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -5931,7 +5870,7 @@ fn airAggregateInit(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
5931 const result_ty = self.typeOfIndex(inst);5870 const result_ty = self.typeOfIndex(inst);
5932 const len: usize = @intCast(result_ty.arrayLen(zcu));5871 const len: usize = @intCast(result_ty.arrayLen(zcu));
5933 const elements: []const Air.Inst.Ref = @ptrCast(self.air.extra.items[ty_pl.payload..][0..len]);5872 const elements: []const Air.Inst.Ref = @ptrCast(self.air.extra.items[ty_pl.payload..][0..len]);
5934 const llvm_result_ty = try o.lowerType(pt, result_ty);5873 const llvm_result_ty = try self.lowerType(result_ty);
59355874
5936 switch (result_ty.zigTypeTag(zcu)) {5875 switch (result_ty.zigTypeTag(zcu)) {
5937 .vector => {5876 .vector => {
...@@ -5997,7 +5936,7 @@ fn airAggregateInit(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -5997,7 +5936,7 @@ fn airAggregateInit(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
5997 field_ptr_align.toLlvm(),5936 field_ptr_align.toLlvm(),
5998 llvm_field_val,5937 llvm_field_val,
5999 field_ty.abiAlignment(zcu).toLlvm(),5938 field_ty.abiAlignment(zcu).toLlvm(),
6000 try o.builder.intValue(try o.lowerType(pt, .usize), field_ty.abiSize(zcu)),5939 try o.builder.intValue(try self.lowerType(.usize), field_ty.abiSize(zcu)),
6001 .normal,5940 .normal,
6002 self.disable_intrinsics,5941 self.disable_intrinsics,
6003 );5942 );
...@@ -6042,7 +5981,7 @@ fn airAggregateInit(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -6042,7 +5981,7 @@ fn airAggregateInit(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
6042 }5981 }
6043}5982}
60445983
6045fn airUnionInit(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {5984fn airUnionInit(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
6046 const o = self.object;5985 const o = self.object;
6047 const pt = self.pt;5986 const pt = self.pt;
6048 const zcu = pt.zcu;5987 const zcu = pt.zcu;
...@@ -6050,7 +5989,7 @@ fn airUnionInit(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -6050,7 +5989,7 @@ fn airUnionInit(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
6050 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;5989 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
6051 const extra = self.air.extraData(Air.UnionInit, ty_pl.payload).data;5990 const extra = self.air.extraData(Air.UnionInit, ty_pl.payload).data;
6052 const union_ty = self.typeOfIndex(inst);5991 const union_ty = self.typeOfIndex(inst);
6053 const union_llvm_ty = try o.lowerType(pt, union_ty);5992 const union_llvm_ty = try self.lowerType(union_ty);
6054 const union_obj = zcu.typeToUnion(union_ty).?;5993 const union_obj = zcu.typeToUnion(union_ty).?;
60555994
6056 assert(union_obj.layout != .@"packed");5995 assert(union_obj.layout != .@"packed");
...@@ -6086,7 +6025,7 @@ fn airUnionInit(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -6086,7 +6025,7 @@ fn airUnionInit(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
6086 return result_ptr;6025 return result_ptr;
6087}6026}
60886027
6089fn airPrefetch(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {6028fn airPrefetch(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
6090 const o = self.object;6029 const o = self.object;
6091 const prefetch = self.air.instructions.items(.data)[@intFromEnum(inst)].prefetch;6030 const prefetch = self.air.instructions.items(.data)[@intFromEnum(inst)].prefetch;
60926031
...@@ -6135,14 +6074,12 @@ fn airPrefetch(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -6135,14 +6074,12 @@ fn airPrefetch(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
6135 return .none;6074 return .none;
6136}6075}
61376076
6138fn airAddrSpaceCast(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {6077fn airAddrSpaceCast(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
6139 const o = self.object;
6140 const pt = self.pt;
6141 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;6078 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
6142 const inst_ty = self.typeOfIndex(inst);6079 const inst_ty = self.typeOfIndex(inst);
6143 const operand = try self.resolveInst(ty_op.operand);6080 const operand = try self.resolveInst(ty_op.operand);
61446081
6145 return self.wip.cast(.addrspacecast, operand, try o.lowerType(pt, inst_ty), "");6082 return self.wip.cast(.addrspacecast, operand, try self.lowerType(inst_ty), "");
6146}6083}
61476084
6148fn workIntrinsic(6085fn workIntrinsic(
...@@ -6150,7 +6087,7 @@ fn workIntrinsic(...@@ -6150,7 +6087,7 @@ fn workIntrinsic(
6150 dimension: u32,6087 dimension: u32,
6151 default: u32,6088 default: u32,
6152 comptime basename: []const u8,6089 comptime basename: []const u8,
6153) !Builder.Value {6090) Allocator.Error!Builder.Value {
6154 return self.wip.callIntrinsic(.normal, .none, switch (dimension) {6091 return self.wip.callIntrinsic(.normal, .none, switch (dimension) {
6155 0 => @field(Builder.Intrinsic, basename ++ ".x"),6092 0 => @field(Builder.Intrinsic, basename ++ ".x"),
6156 1 => @field(Builder.Intrinsic, basename ++ ".y"),6093 1 => @field(Builder.Intrinsic, basename ++ ".y"),
...@@ -6159,7 +6096,7 @@ fn workIntrinsic(...@@ -6159,7 +6096,7 @@ fn workIntrinsic(
6159 }, &.{}, &.{}, "");6096 }, &.{}, &.{}, "");
6160}6097}
61616098
6162fn airWorkItemId(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {6099fn airWorkItemId(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
6163 const target = self.pt.zcu.getTarget();6100 const target = self.pt.zcu.getTarget();
61646101
6165 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;6102 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
...@@ -6172,7 +6109,7 @@ fn airWorkItemId(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -6172,7 +6109,7 @@ fn airWorkItemId(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
6172 };6109 };
6173}6110}
61746111
6175fn airWorkGroupSize(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {6112fn airWorkGroupSize(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
6176 const pt = self.pt;6113 const pt = self.pt;
6177 const target = pt.zcu.getTarget();6114 const target = pt.zcu.getTarget();
61786115
...@@ -6200,7 +6137,7 @@ fn airWorkGroupSize(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -6200,7 +6137,7 @@ fn airWorkGroupSize(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
6200 }6137 }
6201}6138}
62026139
6203fn airWorkGroupId(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {6140fn airWorkGroupId(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value {
6204 const target = self.pt.zcu.getTarget();6141 const target = self.pt.zcu.getTarget();
62056142
6206 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;6143 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
...@@ -6213,28 +6150,6 @@ fn airWorkGroupId(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {...@@ -6213,28 +6150,6 @@ fn airWorkGroupId(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
6213 };6150 };
6214}6151}
62156152
6216fn getErrorNameTable(self: *FuncGen) Allocator.Error!Builder.Variable.Index {
6217 const o = self.object;
6218 const pt = self.pt;
6219
6220 const table = o.error_name_table;
6221 if (table != .none) return table;
6222
6223 // TODO: Address space
6224 const variable_index =
6225 try o.builder.addVariable(try o.builder.strtabString("__zig_err_name_table"), .ptr, .default);
6226 variable_index.setLinkage(.private, &o.builder);
6227 variable_index.setMutability(.constant, &o.builder);
6228 variable_index.setUnnamedAddr(.unnamed_addr, &o.builder);
6229 variable_index.setAlignment(
6230 Type.slice_const_u8_sentinel_0.abiAlignment(pt.zcu).toLlvm(),
6231 &o.builder,
6232 );
6233
6234 o.error_name_table = variable_index;
6235 return variable_index;
6236}
6237
6238/// Assumes that `Type.optionalReprIsPayload` is `false` for `opt_ty` and that the payload has bits.6153/// Assumes that `Type.optionalReprIsPayload` is `false` for `opt_ty` and that the payload has bits.
6239fn optCmpNull(6154fn optCmpNull(
6240 self: *FuncGen,6155 self: *FuncGen,
...@@ -6258,7 +6173,7 @@ fn optPayloadHandle(...@@ -6258,7 +6173,7 @@ fn optPayloadHandle(
6258 opt_ptr: Builder.Value,6173 opt_ptr: Builder.Value,
6259 opt_ty: Type,6174 opt_ty: Type,
6260 can_elide_load: bool,6175 can_elide_load: bool,
6261) !Builder.Value {6176) Allocator.Error!Builder.Value {
6262 const pt = fg.pt;6177 const pt = fg.pt;
6263 const zcu = pt.zcu;6178 const zcu = pt.zcu;
6264 assert(isByRef(opt_ty, zcu));6179 assert(isByRef(opt_ty, zcu));
...@@ -6281,7 +6196,7 @@ fn fieldPtr(...@@ -6281,7 +6196,7 @@ fn fieldPtr(
6281 aggregate_ptr: Builder.Value,6196 aggregate_ptr: Builder.Value,
6282 aggregate_ptr_ty: Type,6197 aggregate_ptr_ty: Type,
6283 field_index: u32,6198 field_index: u32,
6284) !Builder.Value {6199) Allocator.Error!Builder.Value {
6285 const pt = self.pt;6200 const pt = self.pt;
6286 const zcu = pt.zcu;6201 const zcu = pt.zcu;
6287 const aggregate_ty = aggregate_ptr_ty.childType(zcu);6202 const aggregate_ty = aggregate_ptr_ty.childType(zcu);
...@@ -6305,7 +6220,7 @@ fn loadTruncate(...@@ -6305,7 +6220,7 @@ fn loadTruncate(
6305 payload_ty: Type,6220 payload_ty: Type,
6306 payload_ptr: Builder.Value,6221 payload_ptr: Builder.Value,
6307 payload_alignment: Builder.Alignment,6222 payload_alignment: Builder.Alignment,
6308) !Builder.Value {6223) Allocator.Error!Builder.Value {
6309 // from https://llvm.org/docs/LangRef.html#load-instruction :6224 // from https://llvm.org/docs/LangRef.html#load-instruction :
6310 // "When loading a value of a type like i20 with a size that is not an integral number of bytes, the result is undefined if the value was not originally written using a store of the same type. "6225 // "When loading a value of a type like i20 with a size that is not an integral number of bytes, the result is undefined if the value was not originally written using a store of the same type. "
6311 // => so load the byte aligned value and trunc the unwanted bits.6226 // => so load the byte aligned value and trunc the unwanted bits.
...@@ -6313,7 +6228,7 @@ fn loadTruncate(...@@ -6313,7 +6228,7 @@ fn loadTruncate(
6313 const o = fg.object;6228 const o = fg.object;
6314 const pt = fg.pt;6229 const pt = fg.pt;
6315 const zcu = pt.zcu;6230 const zcu = pt.zcu;
6316 const payload_llvm_ty = try o.lowerType(pt, payload_ty);6231 const payload_llvm_ty = try fg.lowerType(payload_ty);
6317 const abi_size = payload_ty.abiSize(zcu);6232 const abi_size = payload_ty.abiSize(zcu);
63186233
6319 const load_llvm_ty = if (payload_ty.isAbiInt(zcu))6234 const load_llvm_ty = if (payload_ty.isAbiInt(zcu))
...@@ -6321,7 +6236,7 @@ fn loadTruncate(...@@ -6321,7 +6236,7 @@ fn loadTruncate(
6321 else6236 else
6322 payload_llvm_ty;6237 payload_llvm_ty;
6323 const loaded = try fg.wip.load(access_kind, load_llvm_ty, payload_ptr, payload_alignment, "");6238 const loaded = try fg.wip.load(access_kind, load_llvm_ty, payload_ptr, payload_alignment, "");
6324 const shifted = if (payload_llvm_ty != load_llvm_ty and o.target.cpu.arch.endian() == .big)6239 const shifted = if (payload_llvm_ty != load_llvm_ty and zcu.getTarget().cpu.arch.endian() == .big)
6325 try fg.wip.bin(.lshr, loaded, try o.builder.intValue(6240 try fg.wip.bin(.lshr, loaded, try o.builder.intValue(
6326 load_llvm_ty,6241 load_llvm_ty,
6327 (payload_ty.abiSize(zcu) - (std.math.divCeil(u64, payload_ty.bitSize(zcu), 8) catch unreachable)) * 8,6242 (payload_ty.abiSize(zcu) - (std.math.divCeil(u64, payload_ty.bitSize(zcu), 8) catch unreachable)) * 8,
...@@ -6339,10 +6254,10 @@ fn loadByRef(...@@ -6339,10 +6254,10 @@ fn loadByRef(
6339 pointee_type: Type,6254 pointee_type: Type,
6340 ptr_alignment: Builder.Alignment,6255 ptr_alignment: Builder.Alignment,
6341 access_kind: Builder.MemoryAccessKind,6256 access_kind: Builder.MemoryAccessKind,
6342) !Builder.Value {6257) Allocator.Error!Builder.Value {
6343 const o = fg.object;6258 const o = fg.object;
6344 const pt = fg.pt;6259 const pt = fg.pt;
6345 const pointee_llvm_ty = try o.lowerType(pt, pointee_type);6260 const pointee_llvm_ty = try fg.lowerType(pointee_type);
6346 const result_align = InternPool.Alignment.fromLlvm(ptr_alignment)6261 const result_align = InternPool.Alignment.fromLlvm(ptr_alignment)
6347 .max(pointee_type.abiAlignment(pt.zcu)).toLlvm();6262 .max(pointee_type.abiAlignment(pt.zcu)).toLlvm();
6348 const result_ptr = try fg.buildAlloca(pointee_llvm_ty, result_align);6263 const result_ptr = try fg.buildAlloca(pointee_llvm_ty, result_align);
...@@ -6352,7 +6267,7 @@ fn loadByRef(...@@ -6352,7 +6267,7 @@ fn loadByRef(
6352 result_align,6267 result_align,
6353 ptr,6268 ptr,
6354 ptr_alignment,6269 ptr_alignment,
6355 try o.builder.intValue(try o.lowerType(pt, Type.usize), size_bytes),6270 try o.builder.intValue(try fg.lowerType(.usize), size_bytes),
6356 access_kind,6271 access_kind,
6357 fg.disable_intrinsics,6272 fg.disable_intrinsics,
6358 );6273 );
...@@ -6362,7 +6277,7 @@ fn loadByRef(...@@ -6362,7 +6277,7 @@ fn loadByRef(
6362/// This function always performs a copy. For isByRef=true types, it creates a new6277/// This function always performs a copy. For isByRef=true types, it creates a new
6363/// alloca and copies the value into it, then returns the alloca instruction.6278/// alloca and copies the value into it, then returns the alloca instruction.
6364/// For isByRef=false types, it creates a load instruction and returns it.6279/// For isByRef=false types, it creates a load instruction and returns it.
6365fn load(self: *FuncGen, ptr: Builder.Value, ptr_ty: Type) !Builder.Value {6280fn load(self: *FuncGen, ptr: Builder.Value, ptr_ty: Type) Allocator.Error!Builder.Value {
6366 const o = self.object;6281 const o = self.object;
6367 const pt = self.pt;6282 const pt = self.pt;
6368 const zcu = pt.zcu;6283 const zcu = pt.zcu;
...@@ -6380,7 +6295,7 @@ fn load(self: *FuncGen, ptr: Builder.Value, ptr_ty: Type) !Builder.Value {...@@ -6380,7 +6295,7 @@ fn load(self: *FuncGen, ptr: Builder.Value, ptr_ty: Type) !Builder.Value {
63806295
6381 if (info.flags.vector_index != .none) {6296 if (info.flags.vector_index != .none) {
6382 const index_u32 = try o.builder.intValue(.i32, info.flags.vector_index);6297 const index_u32 = try o.builder.intValue(.i32, info.flags.vector_index);
6383 const vec_elem_ty = try o.lowerType(pt, elem_ty);6298 const vec_elem_ty = try self.lowerType(elem_ty);
6384 const vec_ty = try o.builder.vectorType(.normal, info.packed_offset.host_size, vec_elem_ty);6299 const vec_ty = try o.builder.vectorType(.normal, info.packed_offset.host_size, vec_elem_ty);
63856300
6386 const loaded_vector = try self.wip.load(access_kind, vec_ty, ptr, ptr_alignment, "");6301 const loaded_vector = try self.wip.load(access_kind, vec_ty, ptr, ptr_alignment, "");
...@@ -6401,7 +6316,7 @@ fn load(self: *FuncGen, ptr: Builder.Value, ptr_ty: Type) !Builder.Value {...@@ -6401,7 +6316,7 @@ fn load(self: *FuncGen, ptr: Builder.Value, ptr_ty: Type) !Builder.Value {
6401 const elem_bits = ptr_ty.childType(zcu).bitSize(zcu);6316 const elem_bits = ptr_ty.childType(zcu).bitSize(zcu);
6402 const shift_amt = try o.builder.intValue(containing_int_ty, info.packed_offset.bit_offset);6317 const shift_amt = try o.builder.intValue(containing_int_ty, info.packed_offset.bit_offset);
6403 const shifted_value = try self.wip.bin(.lshr, containing_int, shift_amt, "");6318 const shifted_value = try self.wip.bin(.lshr, containing_int, shift_amt, "");
6404 const elem_llvm_ty = try o.lowerType(pt, elem_ty);6319 const elem_llvm_ty = try self.lowerType(elem_ty);
64056320
6406 if (isByRef(elem_ty, zcu)) {6321 if (isByRef(elem_ty, zcu)) {
6407 const result_align = elem_ty.abiAlignment(zcu).toLlvm();6322 const result_align = elem_ty.abiAlignment(zcu).toLlvm();
...@@ -6434,7 +6349,7 @@ fn store(...@@ -6434,7 +6349,7 @@ fn store(
6434 ptr_ty: Type,6349 ptr_ty: Type,
6435 elem: Builder.Value,6350 elem: Builder.Value,
6436 ordering: Builder.AtomicOrdering,6351 ordering: Builder.AtomicOrdering,
6437) !void {6352) Allocator.Error!void {
6438 const o = self.object;6353 const o = self.object;
6439 const pt = self.pt;6354 const pt = self.pt;
6440 const zcu = pt.zcu;6355 const zcu = pt.zcu;
...@@ -6449,7 +6364,7 @@ fn store(...@@ -6449,7 +6364,7 @@ fn store(
64496364
6450 if (info.flags.vector_index != .none) {6365 if (info.flags.vector_index != .none) {
6451 const index_u32 = try o.builder.intValue(.i32, info.flags.vector_index);6366 const index_u32 = try o.builder.intValue(.i32, info.flags.vector_index);
6452 const vec_elem_ty = try o.lowerType(pt, elem_ty);6367 const vec_elem_ty = try self.lowerType(elem_ty);
6453 const vec_ty = try o.builder.vectorType(.normal, info.packed_offset.host_size, vec_elem_ty);6368 const vec_ty = try o.builder.vectorType(.normal, info.packed_offset.host_size, vec_elem_ty);
64546369
6455 const loaded_vector = try self.wip.load(.normal, vec_ty, ptr, ptr_alignment, "");6370 const loaded_vector = try self.wip.load(.normal, vec_ty, ptr, ptr_alignment, "");
...@@ -6518,7 +6433,7 @@ fn store(...@@ -6518,7 +6433,7 @@ fn store(
6518 ptr_alignment,6433 ptr_alignment,
6519 elem,6434 elem,
6520 elem_ty.abiAlignment(zcu).toLlvm(),6435 elem_ty.abiAlignment(zcu).toLlvm(),
6521 try o.builder.intValue(try o.lowerType(pt, Type.usize), elem_ty.abiSize(zcu)),6436 try o.builder.intValue(try self.lowerType(Type.usize), elem_ty.abiSize(zcu)),
6522 access_kind,6437 access_kind,
6523 self.disable_intrinsics,6438 self.disable_intrinsics,
6524 );6439 );
...@@ -6527,8 +6442,7 @@ fn store(...@@ -6527,8 +6442,7 @@ fn store(
6527fn valgrindMarkUndef(fg: *FuncGen, ptr: Builder.Value, len: Builder.Value) Allocator.Error!void {6442fn valgrindMarkUndef(fg: *FuncGen, ptr: Builder.Value, len: Builder.Value) Allocator.Error!void {
6528 const VG_USERREQ__MAKE_MEM_UNDEFINED = 1296236545;6443 const VG_USERREQ__MAKE_MEM_UNDEFINED = 1296236545;
6529 const o = fg.object;6444 const o = fg.object;
6530 const pt = fg.pt;6445 const usize_ty = try fg.lowerType(.usize);
6531 const usize_ty = try o.lowerType(pt, Type.usize);
6532 const zero = try o.builder.intValue(usize_ty, 0);6446 const zero = try o.builder.intValue(usize_ty, 0);
6533 const req = try o.builder.intValue(usize_ty, VG_USERREQ__MAKE_MEM_UNDEFINED);6447 const req = try o.builder.intValue(usize_ty, VG_USERREQ__MAKE_MEM_UNDEFINED);
6534 const ptr_as_usize = try fg.wip.cast(.ptrtoint, ptr, usize_ty, "");6448 const ptr_as_usize = try fg.wip.cast(.ptrtoint, ptr, usize_ty, "");
...@@ -6551,7 +6465,7 @@ fn valgrindClientRequest(...@@ -6551,7 +6465,7 @@ fn valgrindClientRequest(
6551 const target = zcu.getTarget();6465 const target = zcu.getTarget();
6552 if (!target_util.hasValgrindSupport(target, .stage2_llvm)) return default_value;6466 if (!target_util.hasValgrindSupport(target, .stage2_llvm)) return default_value;
65536467
6554 const llvm_usize = try o.lowerType(pt, Type.usize);6468 const llvm_usize = try fg.lowerType(.usize);
6555 const usize_alignment = Type.usize.abiAlignment(zcu).toLlvm();6469 const usize_alignment = Type.usize.abiAlignment(zcu).toLlvm();
65566470
6557 const array_llvm_ty = try o.builder.arrayType(6, llvm_usize);6471 const array_llvm_ty = try o.builder.arrayType(6, llvm_usize);
...@@ -7360,11 +7274,12 @@ pub fn isByRef(ty: Type, zcu: *const Zcu) bool {...@@ -7360,11 +7274,12 @@ pub fn isByRef(ty: Type, zcu: *const Zcu) bool {
7360 => false,7274 => false,
73617275
7362 .array,7276 .array,
7363 .error_union,
7364 .frame,7277 .frame,
7365 => ty.hasRuntimeBits(zcu),7278 => ty.hasRuntimeBits(zcu),
73667279
7367 .optional => ty.hasRuntimeBits(zcu) and !ty.optionalReprIsPayload(zcu),7280 .error_union => ty.errorUnionPayload(zcu).hasRuntimeBits(zcu),
7281
7282 .optional => !ty.optionalReprIsPayload(zcu) and ty.optionalChild(zcu).hasRuntimeBits(zcu),
73687283
7369 .@"struct" => switch (ty.containerLayout(zcu)) {7284 .@"struct" => switch (ty.containerLayout(zcu)) {
7370 .@"packed" => false,7285 .@"packed" => false,
...@@ -7402,25 +7317,19 @@ fn getAtomicAbiType(fg: *const FuncGen, ty: Type, is_rmw_xchg: bool) Allocator.E...@@ -7402,25 +7317,19 @@ fn getAtomicAbiType(fg: *const FuncGen, ty: Type, is_rmw_xchg: bool) Allocator.E
74027317
7403fn ptraddConst(fg: *FuncGen, ptr: Builder.Value, offset: u64) Allocator.Error!Builder.Value {7318fn ptraddConst(fg: *FuncGen, ptr: Builder.Value, offset: u64) Allocator.Error!Builder.Value {
7404 if (offset == 0) return ptr;7319 if (offset == 0) return ptr;
7405 const llvm_usize_ty = try fg.object.lowerType(fg.pt, .usize);7320 const llvm_usize_ty = try fg.lowerType(.usize);
7406 const offset_val = try fg.object.builder.intValue(llvm_usize_ty, offset);7321 const offset_val = try fg.object.builder.intValue(llvm_usize_ty, offset);
7407 return fg.ptradd(ptr, offset_val);7322 return fg.wip.gep(.inbounds, .i8, ptr, &.{offset_val}, "");
7408}7323}
7409fn ptraddScaled(fg: *FuncGen, ptr: Builder.Value, index: Builder.Value, scale: u64) Allocator.Error!Builder.Value {7324fn ptraddScaled(fg: *FuncGen, ptr: Builder.Value, index: Builder.Value, scale: u64) Allocator.Error!Builder.Value {
7410 switch (scale) {7325 if (scale == 0) return ptr;
7411 0 => return ptr,7326 // Right now LLVM seems to fare a bit worse with an explicit `mul nuw` instruction than it does
7412 1 => return fg.ptradd(ptr, index),7327 // if we use a bigger type for the GEP, so we'll do that. As I understand it, it has not yet
7413 else => {7328 // been decided whether the planned `ptradd` instruction will accept a scale or not; if it does
7414 const o = fg.object;7329 // not then presumably upstream will improve their handling of explicit `mul nuw` computing the
7415 const llvm_usize_ty = try o.lowerType(fg.pt, .usize);7330 // offset.
7416 const scale_val = try o.builder.intValue(llvm_usize_ty, scale);7331 const llvm_scale_ty = try fg.object.builder.arrayType(scale, .i8);
7417 const offset = try fg.wip.bin(.@"mul nuw", index, scale_val, "");7332 return fg.wip.gep(.inbounds, llvm_scale_ty, ptr, &.{index}, "");
7418 return fg.ptradd(ptr, offset);
7419 },
7420 }
7421}
7422fn ptradd(fg: *FuncGen, ptr: Builder.Value, offset: Builder.Value) Allocator.Error!Builder.Value {
7423 return fg.wip.gep(.inbounds, .i8, ptr, &.{offset}, "");
7424}7333}
74257334
7426fn compilerRtIntBits(bits: u16) ?u16 {7335fn compilerRtIntBits(bits: u16) ?u16 {