aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2022-09-13 15:39:19 -0700
committerAndrew Kelley <andrew@ziglang.org>2022-09-13 15:39:19 -0700
commit716d9237cb757c15217b21964fde8e755aabe853 (patch)
tree92760021e4d49af92db2d37701f4a303d32d69ac /src
parentfda6d44778f3faf53c66945a0db65be68113416f (diff)
parent0a4cfb81bcca0ca514758049f8d7d99224537f93 (diff)
downloadzig-716d9237cb757c15217b21964fde8e755aabe853.tar.gz
zig-716d9237cb757c15217b21964fde8e755aabe853.zip
Merge remote-tracking branch 'origin/llvm15'
Upgrade to LLVM 15
Diffstat (limited to 'src')
-rw-r--r--src/Compilation.zig11
-rw-r--r--src/clang.zig23
-rw-r--r--src/clang_options_data.zig295
-rw-r--r--src/codegen/llvm.zig674
-rw-r--r--src/codegen/llvm/bindings.zig56
-rw-r--r--src/libcxx.zig31
-rw-r--r--src/libunwind.zig29
-rw-r--r--src/link.zig3
-rw-r--r--src/link/Elf.zig2
-rw-r--r--src/link/Wasm.zig2
-rw-r--r--src/stage1/all_types.hpp2
-rw-r--r--src/stage1/analyze.cpp4
-rw-r--r--src/stage1/codegen.cpp911
-rw-r--r--src/stage1/stage1.h3
-rw-r--r--src/stage1/target.cpp57
-rw-r--r--src/stage1/zig0.cpp6
-rw-r--r--src/target.zig24
-rw-r--r--src/type.zig8
-rw-r--r--src/zig_clang.cpp46
-rw-r--r--src/zig_clang.h55
-rw-r--r--src/zig_clang_cc1_main.cpp14
-rw-r--r--src/zig_clang_cc1as_main.cpp28
-rw-r--r--src/zig_clang_driver.cpp66
-rw-r--r--src/zig_llvm-ar.cpp327
-rw-r--r--src/zig_llvm.cpp17
-rw-r--r--src/zig_llvm.h47
26 files changed, 1902 insertions, 839 deletions
diff --git a/src/Compilation.zig b/src/Compilation.zig
index 5a1abcb52b..18dab183a5 100644
--- a/src/Compilation.zig
+++ b/src/Compilation.zig
@@ -154,6 +154,8 @@ owned_link_dir: ?std.fs.Dir,
/// Don't use this for anything other than stage1 compatibility.
color: Color = .auto,
+libcxx_abi_version: libcxx.AbiVersion = libcxx.AbiVersion.default,
+
/// This mutex guards all `Compilation` mutable state.
mutex: std.Thread.Mutex = .{},
@@ -950,6 +952,7 @@ pub const InitOptions = struct {
headerpad_max_install_names: bool = false,
/// (Darwin) remove dylibs that are unreachable by the entry point or exported symbols
dead_strip_dylibs: bool = false,
+ libcxx_abi_version: libcxx.AbiVersion = libcxx.AbiVersion.default,
};
fn addPackageTableToCacheHash(
@@ -1843,6 +1846,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
.test_evented_io = options.test_evented_io,
.debug_compiler_runtime_libs = options.debug_compiler_runtime_libs,
.debug_compile_errors = options.debug_compile_errors,
+ .libcxx_abi_version = options.libcxx_abi_version,
};
break :comp comp;
};
@@ -4026,6 +4030,13 @@ pub fn addCCArgs(
if (comp.bin_file.options.single_threaded) {
try argv.append("-D_LIBCPP_HAS_NO_THREADS");
}
+
+ try argv.append(try std.fmt.allocPrint(arena, "-D_LIBCPP_ABI_VERSION={d}", .{
+ @enumToInt(comp.libcxx_abi_version),
+ }));
+ try argv.append(try std.fmt.allocPrint(arena, "-D_LIBCPP_ABI_NAMESPACE=__{d}", .{
+ @enumToInt(comp.libcxx_abi_version),
+ }));
}
if (comp.bin_file.options.link_libunwind) {
diff --git a/src/clang.zig b/src/clang.zig
index 40dacc5df8..205a3cccc6 100644
--- a/src/clang.zig
+++ b/src/clang.zig
@@ -859,7 +859,7 @@ pub const StmtExpr = opaque {
pub const StringLiteral = opaque {
pub const getKind = ZigClangStringLiteral_getKind;
- extern fn ZigClangStringLiteral_getKind(*const StringLiteral) StringLiteral_StringKind;
+ extern fn ZigClangStringLiteral_getKind(*const StringLiteral) CharacterLiteral_CharacterKind;
pub const getCodeUnit = ZigClangStringLiteral_getCodeUnit;
extern fn ZigClangStringLiteral_getCodeUnit(*const StringLiteral, usize) u32;
@@ -1117,6 +1117,7 @@ pub const TypeClass = enum(c_int) {
VariableArray,
Atomic,
Attributed,
+ BTFTagAttributed,
BitInt,
BlockPointer,
Builtin,
@@ -1202,25 +1203,33 @@ const StmtClass = enum(c_int) {
OMPForDirectiveClass,
OMPForSimdDirectiveClass,
OMPGenericLoopDirectiveClass,
+ OMPMaskedTaskLoopDirectiveClass,
+ OMPMaskedTaskLoopSimdDirectiveClass,
OMPMasterTaskLoopDirectiveClass,
OMPMasterTaskLoopSimdDirectiveClass,
OMPParallelForDirectiveClass,
OMPParallelForSimdDirectiveClass,
+ OMPParallelGenericLoopDirectiveClass,
+ OMPParallelMaskedTaskLoopDirectiveClass,
+ OMPParallelMaskedTaskLoopSimdDirectiveClass,
OMPParallelMasterTaskLoopDirectiveClass,
OMPParallelMasterTaskLoopSimdDirectiveClass,
OMPSimdDirectiveClass,
OMPTargetParallelForSimdDirectiveClass,
+ OMPTargetParallelGenericLoopDirectiveClass,
OMPTargetSimdDirectiveClass,
OMPTargetTeamsDistributeDirectiveClass,
OMPTargetTeamsDistributeParallelForDirectiveClass,
OMPTargetTeamsDistributeParallelForSimdDirectiveClass,
OMPTargetTeamsDistributeSimdDirectiveClass,
+ OMPTargetTeamsGenericLoopDirectiveClass,
OMPTaskLoopDirectiveClass,
OMPTaskLoopSimdDirectiveClass,
OMPTeamsDistributeDirectiveClass,
OMPTeamsDistributeParallelForDirectiveClass,
OMPTeamsDistributeParallelForSimdDirectiveClass,
OMPTeamsDistributeSimdDirectiveClass,
+ OMPTeamsGenericLoopDirectiveClass,
OMPTileDirectiveClass,
OMPUnrollDirectiveClass,
OMPMaskedDirectiveClass,
@@ -1228,6 +1237,7 @@ const StmtClass = enum(c_int) {
OMPMetaDirectiveClass,
OMPOrderedDirectiveClass,
OMPParallelDirectiveClass,
+ OMPParallelMaskedDirectiveClass,
OMPParallelMasterDirectiveClass,
OMPParallelSectionsDirectiveClass,
OMPScanDirectiveClass,
@@ -1532,6 +1542,7 @@ pub const DeclKind = enum(c_int) {
OMPDeclareMapper,
OMPDeclareReduction,
TemplateParamObject,
+ UnnamedGlobalConstant,
UnresolvedUsingValue,
OMPAllocate,
OMPRequires,
@@ -1805,6 +1816,8 @@ pub const CallingConv = enum(c_int) {
PreserveMost,
PreserveAll,
AArch64VectorCall,
+ AArch64SVEPCS,
+ AMDGPUKernelCall,
};
pub const StorageClass = enum(c_int) {
@@ -1826,14 +1839,6 @@ pub const APFloat_roundingMode = enum(i8) {
Invalid = -1,
};
-pub const StringLiteral_StringKind = enum(c_int) {
- Ascii,
- Wide,
- UTF8,
- UTF16,
- UTF32,
-};
-
pub const CharacterLiteral_CharacterKind = enum(c_int) {
Ascii,
Wide,
diff --git a/src/clang_options_data.zig b/src/clang_options_data.zig
index 90ba377847..edabac2da6 100644
--- a/src/clang_options_data.zig
+++ b/src/clang_options_data.zig
@@ -144,7 +144,9 @@ flagpd1("Wframe-larger-than"),
flagpd1("Wlarge-by-value-copy"),
flagpd1("Wno-deprecated"),
flagpd1("Wno-rewrite-macros"),
+flagpd1("Wno-system-headers"),
flagpd1("Wno-write-strings"),
+flagpd1("Wsystem-headers"),
flagpd1("Wwrite-strings"),
flagpd1("X"),
sepd1("Xanalyzer"),
@@ -243,14 +245,6 @@ sepd1("Zlinker-input"),
.psl = true,
},
.{
- .name = "FA",
- .syntax = .flag,
- .zig_equivalent = .other,
- .pd1 = true,
- .pd2 = false,
- .psl = true,
-},
-.{
.name = "FC",
.syntax = .flag,
.zig_equivalent = .other,
@@ -539,6 +533,14 @@ sepd1("Zlinker-input"),
.psl = true,
},
.{
+ .name = "JMC-",
+ .syntax = .flag,
+ .zig_equivalent = .other,
+ .pd1 = true,
+ .pd2 = false,
+ .psl = true,
+},
+.{
.name = "LD",
.syntax = .flag,
.zig_equivalent = .other,
@@ -1044,6 +1046,14 @@ flagpsl("MT"),
.psl = true,
},
.{
+ .name = "Zc:wchar_t-",
+ .syntax = .flag,
+ .zig_equivalent = .other,
+ .pd1 = true,
+ .pd2 = false,
+ .psl = true,
+},
+.{
.name = "Ze",
.syntax = .flag,
.zig_equivalent = .other,
@@ -1204,6 +1214,46 @@ flagpsl("MT"),
.psl = true,
},
.{
+ .name = "external:W0",
+ .syntax = .flag,
+ .zig_equivalent = .other,
+ .pd1 = true,
+ .pd2 = false,
+ .psl = true,
+},
+.{
+ .name = "external:W1",
+ .syntax = .flag,
+ .zig_equivalent = .other,
+ .pd1 = true,
+ .pd2 = false,
+ .psl = true,
+},
+.{
+ .name = "external:W2",
+ .syntax = .flag,
+ .zig_equivalent = .other,
+ .pd1 = true,
+ .pd2 = false,
+ .psl = true,
+},
+.{
+ .name = "external:W3",
+ .syntax = .flag,
+ .zig_equivalent = .other,
+ .pd1 = true,
+ .pd2 = false,
+ .psl = true,
+},
+.{
+ .name = "external:W4",
+ .syntax = .flag,
+ .zig_equivalent = .other,
+ .pd1 = true,
+ .pd2 = false,
+ .psl = true,
+},
+.{
.name = "fp:except",
.syntax = .flag,
.zig_equivalent = .other,
@@ -2213,6 +2263,8 @@ flagpd1("shared-libasan"),
.pd2 = false,
.psl = true,
},
+flagpd1("fdiagnostics-color"),
+flagpd1("fno-diagnostics-color"),
flagpd1("frecord-gcc-switches"),
flagpd1("fno-record-gcc-switches"),
flagpd1("fident"),
@@ -2385,6 +2437,8 @@ flagpd1("dD"),
flagpd1("dI"),
flagpd1("dM"),
flagpd1("d"),
+sepd1("darwin-target-variant"),
+sepd1("darwin-target-variant-triple"),
flagpd1("dead_strip"),
flagpd1("debug-forward-template-params"),
flagpd1("debug-info-macro"),
@@ -2401,7 +2455,6 @@ flagpd1("disable-lifetime-markers"),
flagpd1("disable-llvm-optzns"),
flagpd1("disable-llvm-passes"),
flagpd1("disable-llvm-verifier"),
-flagpd1("disable-noundef-analysis"),
flagpd1("disable-objc-default-synthesize-properties"),
flagpd1("disable-pragma-debug-crash"),
flagpd1("disable-red-zone"),
@@ -2417,6 +2470,14 @@ sepd1("dwarf-debug-flags"),
sepd1("dwarf-debug-producer"),
flagpd1("dwarf-explicit-import"),
flagpd1("dwarf-ext-refs"),
+.{
+ .name = "hlsl-no-stdinc",
+ .syntax = .flag,
+ .zig_equivalent = .other,
+ .pd1 = true,
+ .pd2 = false,
+ .psl = true,
+},
sepd1("dylib_file"),
flagpd1("dylinker"),
flagpd1("dynamic"),
@@ -2431,7 +2492,9 @@ flagpd1("dynamic"),
flagpd1("ehcontguard"),
flagpd1("emit-ast"),
flagpd1("emit-codegen-only"),
+flagpd1("emit-fir"),
flagpd1("emit-header-module"),
+flagpd1("emit-header-unit"),
flagpd1("emit-html"),
flagpd1("emit-interface-stubs"),
.{
@@ -2446,11 +2509,20 @@ flagpd1("emit-llvm-bc"),
flagpd1("emit-llvm-only"),
flagpd1("emit-llvm-uselists"),
flagpd1("emit-merged-ifs"),
+flagpd1("emit-mlir"),
flagpd1("emit-module"),
flagpd1("emit-module-interface"),
flagpd1("emit-obj"),
flagpd1("emit-pch"),
.{
+ .name = "emit-pristine-llvm",
+ .syntax = .flag,
+ .zig_equivalent = .other,
+ .pd1 = true,
+ .pd2 = false,
+ .psl = true,
+},
+.{
.name = "emit-static-lib",
.syntax = .flag,
.zig_equivalent = .other,
@@ -2458,6 +2530,15 @@ flagpd1("emit-pch"),
.pd2 = true,
.psl = false,
},
+.{
+ .name = "enable-16bit-types",
+ .syntax = .flag,
+ .zig_equivalent = .other,
+ .pd1 = true,
+ .pd2 = false,
+ .psl = true,
+},
+flagpd1("enable-noundef-analysis"),
flagpd1("enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang"),
.{
.name = "end-no-unused-arguments",
@@ -2508,6 +2589,7 @@ flagpd1("falternative-parameter-statement"),
flagpd1("faltivec"),
flagpd1("fanalyzed-objects-for-unparse"),
flagpd1("fkeep-inline-functions"),
+flagpd1("funit-at-a-time"),
flagpd1("fansi-escape-codes"),
flagpd1("fapple-kext"),
flagpd1("fapple-link-rtlib"),
@@ -2565,6 +2647,14 @@ flagpd1("fcaller-saves"),
},
sepd1("fcaret-diagnostics-max-lines"),
flagpd1("fcf-protection"),
+.{
+ .name = "fcgl",
+ .syntax = .flag,
+ .zig_equivalent = .other,
+ .pd1 = true,
+ .pd2 = false,
+ .psl = true,
+},
flagpd1("fchar8_t"),
flagpd1("fcheck-array-temporaries"),
.{
@@ -2608,6 +2698,7 @@ flagpd1("fdebug-dump-all"),
flagpd1("fdebug-dump-parse-tree"),
flagpd1("fdebug-dump-parse-tree-no-sema"),
flagpd1("fdebug-dump-parsing-log"),
+flagpd1("fdebug-dump-pft"),
flagpd1("fdebug-dump-provenance"),
flagpd1("fdebug-dump-symbols"),
flagpd1("fdebug-info-for-profiling"),
@@ -2638,7 +2729,6 @@ flagpd1("fdeprecated-macro"),
flagpd1("fdevirtualize"),
flagpd1("fdevirtualize-speculatively"),
flagpd1("fdiagnostics-absolute-paths"),
-flagpd1("fdiagnostics-color"),
flagpd1("fdiagnostics-fixit-info"),
sepd1("fdiagnostics-format"),
flagpd1("fdiagnostics-parseable-fixits"),
@@ -2650,11 +2740,13 @@ flagpd1("fdiagnostics-show-option"),
flagpd1("fdiagnostics-show-template-tree"),
flagpd1("fdigraphs"),
flagpd1("fdirect-access-external-data"),
+flagpd1("fdirectives-only"),
flagpd1("fdisable-module-hash"),
flagpd1("fdiscard-value-names"),
flagpd1("fdollar-ok"),
flagpd1("fdollars-in-identifiers"),
flagpd1("fdouble-square-bracket-attributes"),
+flagpd1("fdriver-only"),
flagpd1("fdump-fortran-optimized"),
flagpd1("fdump-fortran-original"),
flagpd1("fdump-parse-tree"),
@@ -2679,6 +2771,7 @@ sepd1("ferror-limit"),
flagpd1("fescaping-block-tail-calls"),
flagpd1("fexceptions"),
flagpd1("fexperimental-isel"),
+flagpd1("fexperimental-library"),
flagpd1("fexperimental-new-constant-interpreter"),
flagpd1("fexperimental-new-pass-manager"),
flagpd1("fexperimental-relative-c++-abi-vtables"),
@@ -2690,6 +2783,7 @@ flagpd1("ffake-address-space-map"),
flagpd1("ffast-math"),
flagpd1("ffat-lto-objects"),
flagpd1("fcheck-new"),
+flagpd1("ffile-reproducible"),
flagpd1("fimplicit-modules-use-lock"),
flagpd1("ffine-grained-bitfield-accesses"),
flagpd1("ffinite-loops"),
@@ -2793,6 +2887,7 @@ flagpd1("fhalf-no-semantic-interposition"),
flagpd1("fheinous-gnu-extensions"),
flagpd1("fhip-dump-offload-linker-script"),
flagpd1("fhip-fp32-correctly-rounded-divide-sqrt"),
+flagpd1("fhip-kernel-arg-name"),
flagpd1("fhip-new-launch-api"),
flagpd1("fhonor-infinities"),
flagpd1("fhonor-nans"),
@@ -2818,6 +2913,7 @@ flagpd1("finstrument-functions-after-inlining"),
flagpd1("finteger-4-integer-8"),
flagpd1("fintegrated-as"),
flagpd1("fintegrated-cc1"),
+flagpd1("fintegrated-objemitter"),
sepd1("fintrinsic-modules-path"),
flagpd1("fipa-cp"),
flagpd1("fivopts"),
@@ -2826,12 +2922,13 @@ flagpd1("fix-what-you-can"),
flagpd1("fixit"),
flagpd1("fixit-recompile"),
flagpd1("fixit-to-temporary"),
+flagpd1("fjmc"),
flagpd1("fjump-tables"),
flagpd1("fkeep-static-consts"),
+flagpd1("flang-experimental-exec"),
flagpd1("flarge-sizes"),
flagpd1("flat_namespace"),
flagpd1("flax-vector-conversions"),
-flagpd1("flegacy-pass-manager"),
flagpd1("flimit-debug-info"),
flagpd1("flogical-abbreviations"),
.{
@@ -2856,6 +2953,8 @@ flagpd1("fmerge-functions"),
flagpd1("fminimize-whitespace"),
sepd1("fmodule-feature"),
flagpd1("fmodule-file-deps"),
+flagpd1("fmodule-file-home-is-cwd"),
+flagpd1("fmodule-header"),
sepd1("fmodule-implementation-of"),
flagpd1("fmodule-map-file-home-is-cwd"),
flagpd1("fmodule-maps"),
@@ -2880,6 +2979,7 @@ flagpd1("fmodulo-sched-allow-regmoves"),
flagpd1("fms-compatibility"),
flagpd1("fms-extensions"),
flagpd1("fms-hotpatch"),
+flagpd1("fms-kernel"),
flagpd1("fms-volatile"),
flagpd1("fmudflap"),
flagpd1("fmudflapth"),
@@ -2919,6 +3019,7 @@ flagpd1("fno-allow-editor-placeholders"),
flagpd1("fno-altivec"),
flagpd1("fno-analyzed-objects-for-unparse"),
flagpd1("fno-keep-inline-functions"),
+flagpd1("fno-unit-at-a-time"),
flagpd1("fno-apple-pragma-pack"),
flagpd1("fno-application-extension"),
flagpd1("fno-approx-func"),
@@ -2968,7 +3069,6 @@ flagpd1("fno-check-array-temporaries"),
},
flagpd1("fno-common"),
flagpd1("fno-complete-member-pointers"),
-flagpd1("fno-concept-satisfaction-caching"),
flagpd1("fno-const-strings"),
flagpd1("fno-constant-cfstrings"),
flagpd1("fno-coroutines-ts"),
@@ -2997,7 +3097,6 @@ flagpd1("fno-delete-null-pointer-checks"),
flagpd1("fno-deprecated-macro"),
flagpd1("fno-devirtualize"),
flagpd1("fno-devirtualize-speculatively"),
-flagpd1("fno-diagnostics-color"),
flagpd1("fno-diagnostics-fixit-info"),
flagpd1("fno-diagnostics-show-hotness"),
flagpd1("fno-diagnostics-show-note-include-stack"),
@@ -3005,6 +3104,7 @@ flagpd1("fno-diagnostics-show-option"),
flagpd1("fno-diagnostics-use-presumed-location"),
flagpd1("fno-digraphs"),
flagpd1("fno-direct-access-external-data"),
+flagpd1("fno-directives-only"),
flagpd1("fno-discard-value-names"),
flagpd1("fno-dllexport-inlines"),
flagpd1("fno-dollar-ok"),
@@ -3023,13 +3123,14 @@ flagpd1("fno-emulated-tls"),
flagpd1("fno-escaping-block-tail-calls"),
flagpd1("fno-exceptions"),
flagpd1("fno-experimental-isel"),
-flagpd1("fno-experimental-new-pass-manager"),
+flagpd1("fno-experimental-library"),
flagpd1("fno-experimental-relative-c++-abi-vtables"),
flagpd1("fno-external-blas"),
flagpd1("fno-f2c"),
flagpd1("fno-fast-math"),
flagpd1("fno-fat-lto-objects"),
flagpd1("fno-check-new"),
+flagpd1("fno-file-reproducible"),
flagpd1("fno-implicit-modules-use-lock"),
flagpd1("fno-fine-grained-bitfield-accesses"),
flagpd1("fno-finite-loops"),
@@ -3068,6 +3169,7 @@ flagpd1("fno-gpu-flush-denormals-to-zero"),
flagpd1("fno-gpu-rdc"),
flagpd1("fno-gpu-sanitize"),
flagpd1("fno-hip-fp32-correctly-rounded-divide-sqrt"),
+flagpd1("fno-hip-kernel-arg-name"),
flagpd1("fno-hip-new-launch-api"),
flagpd1("fno-honor-infinities"),
flagpd1("fno-honor-nans"),
@@ -3084,10 +3186,13 @@ flagpd1("fno-inline-small-functions"),
flagpd1("fno-integer-4-integer-8"),
flagpd1("fno-integrated-as"),
flagpd1("fno-integrated-cc1"),
+flagpd1("fno-integrated-objemitter"),
flagpd1("fno-ipa-cp"),
flagpd1("fno-ivopts"),
+flagpd1("fno-jmc"),
flagpd1("fno-jump-tables"),
flagpd1("fno-keep-static-consts"),
+flagpd1("fno-knr-functions"),
flagpd1("fno-lax-vector-conversions"),
flagpd1("fno-legacy-pass-manager"),
flagpd1("fno-limit-debug-info"),
@@ -3152,6 +3257,7 @@ flagpd1("fno-openmp-cuda-force-full-runtime"),
flagpd1("fno-openmp-cuda-mode"),
flagpd1("fno-openmp-extensions"),
flagpd1("fno-openmp-implicit-rpath"),
+flagpd1("fno-openmp-new-driver"),
flagpd1("fno-openmp-optimistic-collapse"),
flagpd1("fno-openmp-simd"),
flagpd1("fno-openmp-target-debug"),
@@ -3234,6 +3340,7 @@ flagpd1("fno-rtlib-add-rpath"),
flagpd1("fno-rtti"),
flagpd1("fno-rtti-data"),
flagpd1("fno-rwpi"),
+flagpd1("fno-sanitize-address-globals-dead-stripping"),
flagpd1("fno-sanitize-address-outline-instrumentation"),
flagpd1("fno-sanitize-address-poison-custom-array-cookie"),
flagpd1("fno-sanitize-address-use-after-scope"),
@@ -3325,7 +3432,6 @@ flagpd1("fno-underscoring"),
flagpd1("fno-unique-basic-block-section-names"),
flagpd1("fno-unique-internal-linkage-names"),
flagpd1("fno-unique-section-names"),
-flagpd1("fno-unit-at-a-time"),
flagpd1("fno-unroll-all-loops"),
flagpd1("fno-unroll-loops"),
flagpd1("fno-unsafe-loop-optimizations"),
@@ -3406,6 +3512,7 @@ flagpd1("foffload-lto"),
},
flagpd1("fopenacc"),
flagpd1("fopenmp"),
+flagpd1("fopenmp-assume-no-thread-state"),
flagpd1("fopenmp-assume-teams-oversubscription"),
flagpd1("fopenmp-assume-threads-oversubscription"),
flagpd1("fopenmp-cuda-force-full-runtime"),
@@ -3416,6 +3523,7 @@ sepd1("fopenmp-host-ir-file-path"),
flagpd1("fopenmp-implicit-rpath"),
flagpd1("fopenmp-is-device"),
flagpd1("fopenmp-new-driver"),
+flagpd1("fopenmp-offload-mandatory"),
flagpd1("fopenmp-optimistic-collapse"),
flagpd1("fopenmp-relocatable-target"),
flagpd1("fopenmp-simd"),
@@ -3659,7 +3767,6 @@ flagpd1("funderscoring"),
flagpd1("funique-basic-block-section-names"),
flagpd1("funique-internal-linkage-names"),
flagpd1("funique-section-names"),
-flagpd1("funit-at-a-time"),
flagpd1("funknown-anytype"),
flagpd1("funroll-all-loops"),
flagpd1("funroll-loops"),
@@ -3844,6 +3951,7 @@ flagpd1("m68060"),
flagpd1("m80387"),
m("mseses"),
flagpd1("mabi=ieeelongdouble"),
+flagpd1("mabi=quadword-atomics"),
flagpd1("mabi=vec-default"),
flagpd1("mabi=vec-extabi"),
flagpd1("mabicalls"),
@@ -3907,7 +4015,6 @@ m("mcumode"),
m("mcx16"),
sepd1("mdebug-pass"),
m("mdirect-move"),
-flagpd1("mdisable-tail-calls"),
flagpd1("mdouble-float"),
m("mdsp"),
m("mdspr2"),
@@ -3921,6 +4028,7 @@ flagpd1("menable-unsafe-fp-math"),
m("menqcmd"),
m("mexception-handling"),
m("mexecute-only"),
+flagpd1("mextended-const"),
flagpd1("mextern-sdata"),
m("mf16c"),
flagpd1("mfancy-math-387"),
@@ -3929,6 +4037,8 @@ flagpd1("mfix4300"),
flagpd1("mfix-and-continue"),
m("mfix-cmse-cve-2021-35465"),
m("mfix-cortex-a53-835769"),
+flagpd1("mfix-cortex-a57-aes-1742098"),
+flagpd1("mfix-cortex-a72-aes-1655431"),
m("mfloat128"),
sepd1("mfloat-abi"),
m("mfma"),
@@ -4007,6 +4117,7 @@ m("mmemops"),
flagpd1("mmfcrf"),
m("mmfocrf"),
m("mmicromips"),
+sepd1("mmlir"),
m("mmma"),
m("mmmx"),
m("mmovbe"),
@@ -4077,10 +4188,13 @@ m("mno-enqcmd"),
m("mno-exception-handling"),
flagpd1("mnoexecstack"),
m("mno-execute-only"),
+flagpd1("mno-extended-const"),
flagpd1("mno-extern-sdata"),
m("mno-f16c"),
m("mno-fix-cmse-cve-2021-35465"),
m("mno-fix-cortex-a53-835769"),
+flagpd1("mno-fix-cortex-a57-aes-1742098"),
+flagpd1("mno-fix-cortex-a72-aes-1655431"),
m("mno-float128"),
m("mno-fma"),
m("mno-fma4"),
@@ -4158,6 +4272,7 @@ m("mno-prfchw"),
m("mno-ptwrite"),
flagpd1("mno-pure-code"),
m("mno-rdpid"),
+flagpd1("mno-rdpru"),
m("mno-rdrnd"),
m("mno-rdseed"),
.{
@@ -4239,7 +4354,6 @@ m("mnvj"),
m("mnvs"),
flagpd1("modd-spreg"),
sepd1("module-dependency-dir"),
-sepd1("module-dir"),
flagpd1("module-file-deps"),
flagpd1("module-file-info"),
sepd1("module-suffix"),
@@ -4268,6 +4382,7 @@ m("mptwrite"),
flagpd1("mpure-code"),
flagpd1("mqdsp6-compat"),
m("mrdpid"),
+flagpd1("mrdpru"),
m("mrdrnd"),
m("mrdseed"),
flagpd1("mreassociate"),
@@ -4404,6 +4519,7 @@ flagpd1("no-cpp-precomp"),
.psl = false,
},
flagpd1("no-emit-llvm-uselists"),
+flagpd1("no-enable-noundef-analysis"),
.{
.name = "no-gpu-bundle-output",
.syntax = .flag,
@@ -4412,6 +4528,7 @@ flagpd1("no-emit-llvm-uselists"),
.pd2 = true,
.psl = false,
},
+flagpd1("no-hip-rt"),
flagpd1("no-implicit-float"),
.{
.name = "no-integrated-cpp",
@@ -4422,6 +4539,15 @@ flagpd1("no-implicit-float"),
.psl = false,
},
.{
+ .name = "no-offload-new-driver",
+ .syntax = .flag,
+ .zig_equivalent = .other,
+ .pd1 = false,
+ .pd2 = true,
+ .psl = false,
+},
+flagpd1("no-opaque-pointers"),
+.{
.name = "no-pedantic",
.syntax = .flag,
.zig_equivalent = .other,
@@ -4443,6 +4569,7 @@ flagpd1("no-struct-path-tbaa"),
flagpd1("nobuiltininc"),
flagpd1("nocpp"),
flagpd1("nodefaultlibs"),
+flagpd1("nodriverkitlib"),
flagpd1("nofixprebinding"),
flagpd1("nogpuinc"),
flagpd1("nogpulib"),
@@ -4526,6 +4653,47 @@ flagpd1("objcmt-ns-nonatomic-iosonly"),
flagpd1("objcmt-returns-innerpointer-property"),
flagpd1("object"),
sepd1("object-file-name"),
+.{
+ .name = "offload-device-only",
+ .syntax = .flag,
+ .zig_equivalent = .other,
+ .pd1 = false,
+ .pd2 = true,
+ .psl = false,
+},
+.{
+ .name = "offload-host-device",
+ .syntax = .flag,
+ .zig_equivalent = .other,
+ .pd1 = false,
+ .pd2 = true,
+ .psl = false,
+},
+.{
+ .name = "offload-host-only",
+ .syntax = .flag,
+ .zig_equivalent = .other,
+ .pd1 = false,
+ .pd2 = true,
+ .psl = false,
+},
+.{
+ .name = "offload-link",
+ .syntax = .flag,
+ .zig_equivalent = .other,
+ .pd1 = false,
+ .pd2 = true,
+ .psl = false,
+},
+.{
+ .name = "offload-new-driver",
+ .syntax = .flag,
+ .zig_equivalent = .other,
+ .pd1 = false,
+ .pd2 = true,
+ .psl = false,
+},
+flagpd1("opaque-pointers"),
sepd1("opt-record-file"),
sepd1("opt-record-format"),
sepd1("opt-record-passes"),
@@ -4582,6 +4750,14 @@ flagpd1("prebind_all_twolevel_modules"),
flagpd1("preload"),
flagpd1("print-dependency-directives-minimized-source"),
.{
+ .name = "print-diagnostic-options",
+ .syntax = .flag,
+ .zig_equivalent = .other,
+ .pd1 = true,
+ .pd2 = true,
+ .psl = false,
+},
+.{
.name = "print-effective-triple",
.syntax = .flag,
.zig_equivalent = .other,
@@ -4982,6 +5158,7 @@ joinpd1("fsanitize-undefined-strip-path-components="),
joinpd1("fopenmp-cuda-teams-reduction-recs-num="),
joinpd1("fvisibility-externs-nodllstorageclass="),
joinpd1("analyzer-config-compatibility-mode="),
+joinpd1("mdefault-visibility-export-mapping="),
joinpd1("fsanitize-address-use-after-return="),
.{
.name = "fsanitize-address-use-after-return",
@@ -4991,9 +5168,12 @@ joinpd1("fsanitize-address-use-after-return="),
.pd2 = false,
.psl = true,
},
+joinpd1("darwin-target-variant-sdk-version="),
joinpd1("ftrivial-auto-var-init-stop-after="),
joinpd1("fverify-debuginfo-preserve-export="),
+joinpd1("fdiagnostics-misexpect-tolerance="),
joinpd1("fpatchable-function-entry-offset="),
+joinpd1("fprofile-selected-function-group="),
joinpd1("analyzer-inline-max-stack-depth="),
joinpd1("fsanitize-address-field-padding="),
.{
@@ -5005,6 +5185,7 @@ joinpd1("fsanitize-address-field-padding="),
.psl = true,
},
joinpd1("fdiagnostics-hotness-threshold="),
+joinpd1("fexperimental-max-bitint-width="),
joinpd1("fsanitize-memory-track-origins="),
joinpd1("mwatchos-simulator-version-min="),
joinpd1("fsanitize-coverage-ignorelist="),
@@ -5013,6 +5194,7 @@ joinpd1("fvisibility-nodllstorageclass="),
joinpd1("fxray-selected-function-group="),
joinpd1("mappletvsimulator-version-min="),
joinpd1("mstack-protector-guard-offset="),
+joinpd1("mstack-protector-guard-symbol="),
.{
.name = "sourceDependencies:directives",
.syntax = .joined_or_separate,
@@ -5021,16 +5203,17 @@ joinpd1("mstack-protector-guard-offset="),
.pd2 = false,
.psl = true,
},
+joinpd1("miphonesimulator-version-min="),
joinpd1("fsanitize-coverage-whitelist="),
joinpd1("fsanitize-coverage-blacklist="),
joinpd1("fobjc-nonfragile-abi-version="),
joinpd1("fprofile-instrument-use-path="),
joinpd1("fsanitize-coverage-allowlist="),
jspd1("fxray-instrumentation-bundle="),
-joinpd1("miphonesimulator-version-min="),
joinpd1("fsanitize-address-destructor="),
joinpd1("faddress-space-map-mangling="),
joinpd1("foptimization-record-passes="),
+joinpd1("frandomize-layout-seed-file="),
joinpd1("fsanitize-system-ignorelist="),
joinpd1("ftest-module-file-extension="),
jspd1("fxray-instruction-threshold="),
@@ -5042,6 +5225,14 @@ jspd1("fxray-instruction-threshold="),
.pd2 = true,
.psl = false,
},
+.{
+ .name = "libomptarget-amdgpu-bc-path=",
+ .syntax = .joined,
+ .zig_equivalent = .other,
+ .pd1 = false,
+ .pd2 = true,
+ .psl = false,
+},
joinpd1("mno-default-build-attributes"),
joinpd1("mtvos-simulator-version-min="),
joinpd1("mwatchsimulator-version-min="),
@@ -5107,6 +5298,7 @@ joinpd1("objcmt-allowlist-dir-path="),
joinpd1("Wno-nonportable-cfstrings"),
joinpd1("analyzer-disable-checker="),
joinpd1("fbuild-session-timestamp="),
+joinpd1("fprofile-function-groups="),
joinpd1("fprofile-instrument-path="),
joinpd1("mdefault-build-attributes"),
joinpd1("msign-return-address-key="),
@@ -5178,6 +5370,7 @@ joinpd1("ffp-exception-behavior="),
joinpd1("fmacro-backtrace-limit="),
joinpd1("fmax-array-constructor="),
joinpd1("fprofile-exclude-files="),
+joinpd1("frandomize-layout-seed="),
joinpd1("ftrivial-auto-var-init="),
jspd1("fxray-never-instrument="),
joinpd1("gsimple-template-names="),
@@ -5186,6 +5379,7 @@ joinpd1("malign-branch-boundary="),
joinpd1("mappletvos-version-min="),
joinpd1("mstack-protector-guard="),
joinpd1("Wnonportable-cfstrings"),
+joinpd1("miphoneos-version-min="),
joinpd1("fbasic-block-sections="),
joinpd1("fdefault-calling-conv="),
joinpd1("fdenormal-fp-math-f32="),
@@ -5206,10 +5400,10 @@ joinpd1("fobjc-dispatch-method="),
joinpd1("foperator-arrow-depth="),
joinpd1("fprebuilt-module-path="),
joinpd1("fprofile-filter-files="),
+joinpd1("fsanitize-memtag-mode="),
joinpd1("fspell-checking-limit="),
joinpd1("fvisibility-dllexport="),
joinpd1("fxray-function-groups="),
-joinpd1("miphoneos-version-min="),
joinpd1("msmall-data-threshold="),
joinpd1("Wlarge-by-value-copy="),
joinpd1("analyzer-constraints="),
@@ -5229,6 +5423,7 @@ joinpd1("fmodules-prune-after="),
},
joinpd1("fopenmp-target-debug="),
joinpd1("fsanitize-ignorelist="),
+joinpd1("fzero-call-used-regs="),
jspd1("iframeworkwithsysroot"),
joinpd1("mcode-object-version="),
joinpd1("mpad-max-prefix-size="),
@@ -5260,6 +5455,7 @@ joinpd1("mwatchos-version-min="),
.psl = false,
},
joinpd1("faltivec-src-compat="),
+joinpd1("mmacosx-version-min="),
joinpd1("fsanitize-blacklist="),
.{
.name = "hip-device-lib-path=",
@@ -5272,12 +5468,13 @@ joinpd1("fsanitize-blacklist="),
joinpd1("coverage-notes-file="),
joinpd1("fbuild-session-file="),
joinpd1("fdiagnostics-format="),
+joinpd1("fgpu-default-stream="),
joinpd1("fmax-stack-var-size="),
joinpd1("fmodules-cache-path="),
joinpd1("fmodules-embed-file="),
joinpd1("fprofile-instrument="),
joinpd1("fprofile-sample-use="),
-joinpd1("mmacosx-version-min="),
+joinpd1("fstrict-flex-arrays="),
.{
.name = "no-cuda-include-ptx=",
.syntax = .joined,
@@ -5291,6 +5488,7 @@ joinpd1("code-completion-at="),
joinpd1("coverage-data-file="),
joinpd1("fblas-matmul-limit="),
joinpd1("fdiagnostics-color="),
+joinpd1("femit-dwarf-unwind="),
joinpd1("ffixed-line-length="),
joinpd1("ffixed-line-length-"),
joinpd1("ffuchsia-api-level="),
@@ -5430,6 +5628,7 @@ joinpd1("fproc-stat-report"),
joinpd1("fwarn-stack-size="),
jspd1("iwithprefixbefore"),
joinpd1("malign-functions="),
+joinpd1("mfunction-return="),
joinpd1("mios-version-min="),
joinpd1("mstack-alignment="),
joinpd1("msve-vector-bits="),
@@ -5473,6 +5672,7 @@ joinpd1("debug-info-kind="),
joinpd1("debugger-tuning="),
joinpd1("exception-model="),
joinpd1("fcf-runtime-abi="),
+joinpd1("ffp-eval-method="),
joinpd1("finit-character="),
joinpd1("fmax-type-align="),
joinpd1("fmemory-profile="),
@@ -5521,6 +5721,14 @@ joinpd1("mlinker-version="),
jspd1("stdlib++-isystem"),
joinpd1("Rpass-analysis="),
.{
+ .name = "Xoffload-linker",
+ .syntax = .joined_and_separate,
+ .zig_equivalent = .other,
+ .pd1 = true,
+ .pd2 = false,
+ .psl = false,
+},
+.{
.name = "Xopenmp-target=",
.syntax = .joined_and_separate,
.zig_equivalent = .other,
@@ -5570,6 +5778,7 @@ joinpd1("fdepfile-entry="),
joinpd1("fembed-bitcode="),
joinpd1("finput-charset="),
joinpd1("fmodule-format="),
+joinpd1("fmodule-header="),
joinpd1("fms-memptr-rep="),
joinpd1("fnew-alignment="),
joinpd1("frecord-marker="),
@@ -5592,6 +5801,7 @@ joinpd1("ftrapv-handler="),
.pd2 = false,
.psl = false,
},
+joinpd1("gen-reproducer="),
.{
.name = "hip-device-lib=",
.syntax = .joined,
@@ -5725,6 +5935,14 @@ joinpd1("ast-dump-all="),
.pd2 = true,
.psl = false,
},
+.{
+ .name = "cuda-feature=",
+ .syntax = .joined,
+ .zig_equivalent = .other,
+ .pd1 = false,
+ .pd2 = true,
+ .psl = false,
+},
joinpd1("falign-jumps="),
joinpd1("falign-loops="),
joinpd1("faligned-new="),
@@ -5752,6 +5970,7 @@ joinpd1("gsplit-dwarf="),
jspd1("isystem-after"),
joinpd1("malign-jumps="),
joinpd1("malign-loops="),
+joinpd1("mframe-chain="),
joinpd1("mimplicit-it="),
.{
.name = "offload-arch=",
@@ -5762,6 +5981,14 @@ joinpd1("mimplicit-it="),
.psl = false,
},
jspd1("pagezero_size"),
+.{
+ .name = "product-name=",
+ .syntax = .joined,
+ .zig_equivalent = .other,
+ .pd1 = false,
+ .pd2 = true,
+ .psl = false,
+},
joinpd1("resource-dir="),
.{
.name = "dyld-prefix=",
@@ -5783,6 +6010,7 @@ joinpd1("fmax-errors="),
joinpd1("fmax-tokens="),
joinpd1("fno-builtin-"),
joinpd1("fplugin-arg-"),
+joinpd1("ftime-trace="),
joinpd1("fvisibility="),
joinpd1("fwchar-type="),
jspd1("fxray-modes="),
@@ -5988,6 +6216,7 @@ joinpd1("flto-jobs="),
},
joinpd1("fuse-cuid="),
jspd1("iframework"),
+jspd1("module-dir"),
joinpd1("mtargetos="),
joinpd1("mtls-size="),
.{
@@ -6527,6 +6756,14 @@ joinpd1("mtp="),
},
joinpd1("gz="),
joinpd1("A-"),
+.{
+ .name = "Fo",
+ .syntax = .joined_or_separate,
+ .zig_equivalent = .other,
+ .pd1 = true,
+ .pd2 = false,
+ .psl = true,
+},
joinpd1("G="),
.{
.name = "MF",
@@ -6705,6 +6942,14 @@ joinpd1("G="),
.psl = true,
},
.{
+ .name = "Wv",
+ .syntax = .joined,
+ .zig_equivalent = .other,
+ .pd1 = true,
+ .pd2 = false,
+ .psl = true,
+},
+.{
.name = "Yc",
.syntax = .joined,
.zig_equivalent = .other,
@@ -6903,6 +7148,14 @@ joinpd1("d"),
.pd2 = false,
.psl = false,
},
+.{
+ .name = "T",
+ .syntax = .joined_or_separate,
+ .zig_equivalent = .linker_script,
+ .pd1 = true,
+ .pd2 = false,
+ .psl = true,
+},
jspd1("u"),
jspd1("x"),
joinpd1("y"),
diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig
index 3603713195..d20b6f2ab6 100644
--- a/src/codegen/llvm.zig
+++ b/src/codegen/llvm.zig
@@ -42,7 +42,10 @@ pub fn targetTriple(allocator: Allocator, target: std.Target) ![:0]u8 {
.bpfel => "bpfel",
.bpfeb => "bpfeb",
.csky => "csky",
+ .dxil => "dxil",
.hexagon => "hexagon",
+ .loongarch32 => "loongarch32",
+ .loongarch64 => "loongarch64",
.m68k => "m68k",
.mips => "mips",
.mipsel => "mipsel",
@@ -117,6 +120,7 @@ pub fn targetTriple(allocator: Allocator, target: std.Target) ![:0]u8 {
.nvcl => "nvcl",
.amdhsa => "amdhsa",
.ps4 => "ps4",
+ .ps5 => "ps5",
.elfiamcu => "elfiamcu",
.mesa3d => "mesa3d",
.contiki => "contiki",
@@ -130,6 +134,8 @@ pub fn targetTriple(allocator: Allocator, target: std.Target) ![:0]u8 {
.ios => "ios",
.tvos => "tvos",
.watchos => "watchos",
+ .driverkit => "driverkit",
+ .shadermodel => "shadermodel",
.opencl,
.glsl450,
.vulkan,
@@ -172,6 +178,21 @@ pub fn targetTriple(allocator: Allocator, target: std.Target) ![:0]u8 {
.coreclr => "coreclr",
.simulator => "simulator",
.macabi => "macabi",
+ .pixel => "pixel",
+ .vertex => "vertex",
+ .geometry => "geometry",
+ .hull => "hull",
+ .domain => "domain",
+ .compute => "compute",
+ .library => "library",
+ .raygeneration => "raygeneration",
+ .intersection => "intersection",
+ .anyhit => "anyhit",
+ .closesthit => "closesthit",
+ .miss => "miss",
+ .callable => "callable",
+ .mesh => "mesh",
+ .amplification => "amplification",
};
try llvm_triple.appendSlice(llvm_abi);
@@ -205,6 +226,7 @@ pub fn targetOs(os_tag: std.Target.Os.Tag) llvm.OSType {
.nvcl => .NVCL,
.amdhsa => .AMDHSA,
.ps4 => .PS4,
+ .ps5 => .PS5,
.elfiamcu => .ELFIAMCU,
.tvos => .TvOS,
.watchos => .WatchOS,
@@ -215,6 +237,8 @@ pub fn targetOs(os_tag: std.Target.Os.Tag) llvm.OSType {
.hurd => .Hurd,
.wasi => .WASI,
.emscripten => .Emscripten,
+ .driverkit => .DriverKit,
+ .shadermodel => .ShaderModel,
};
}
@@ -230,7 +254,10 @@ pub fn targetArch(arch_tag: std.Target.Cpu.Arch) llvm.ArchType {
.bpfel => .bpfel,
.bpfeb => .bpfeb,
.csky => .csky,
+ .dxil => .dxil,
.hexagon => .hexagon,
+ .loongarch32 => .loongarch32,
+ .loongarch64 => .loongarch64,
.m68k => .m68k,
.mips => .mips,
.mipsel => .mipsel,
@@ -893,7 +920,9 @@ pub const Object = struct {
while (it.next()) |lowering| switch (lowering) {
.no_bits => continue,
.byval => {
- const param_ty = fn_info.param_types[it.zig_index - 1];
+ assert(!it.byval_attr);
+ const param_index = it.zig_index - 1;
+ const param_ty = fn_info.param_types[param_index];
const param = llvm_func.getParam(llvm_arg_i);
try args.ensureUnusedCapacity(1);
@@ -908,43 +937,17 @@ pub const Object = struct {
} else {
args.appendAssumeCapacity(param);
- if (param_ty.isPtrAtRuntime()) {
- const ptr_info = param_ty.ptrInfo().data;
- if (math.cast(u5, it.zig_index - 1)) |i| {
- if (@truncate(u1, fn_info.noalias_bits >> i) != 0) {
- dg.addArgAttr(llvm_func, llvm_arg_i, "noalias");
- }
- }
- if (!param_ty.isPtrLikeOptional() and !ptr_info.@"allowzero") {
- dg.addArgAttr(llvm_func, llvm_arg_i, "nonnull");
- }
- if (!ptr_info.mutable) {
- dg.addArgAttr(llvm_func, llvm_arg_i, "readonly");
- }
- if (ptr_info.@"align" != 0) {
- dg.addArgAttrInt(llvm_func, llvm_arg_i, "align", ptr_info.@"align");
- } else {
- const elem_align = @maximum(
- ptr_info.pointee_type.abiAlignment(target),
- 1,
- );
- dg.addArgAttrInt(llvm_func, llvm_arg_i, "align", elem_align);
- }
- } else if (ccAbiPromoteInt(fn_info.cc, target, param_ty)) |s| switch (s) {
- .signed => dg.addArgAttr(llvm_func, llvm_arg_i, "signext"),
- .unsigned => dg.addArgAttr(llvm_func, llvm_arg_i, "zeroext"),
- };
+ dg.addByValParamAttrs(llvm_func, param_ty, param_index, fn_info, llvm_arg_i);
}
llvm_arg_i += 1;
},
.byref => {
const param_ty = fn_info.param_types[it.zig_index - 1];
+ const param_llvm_ty = try dg.lowerType(param_ty);
const param = llvm_func.getParam(llvm_arg_i);
+ const alignment = param_ty.abiAlignment(target);
- dg.addArgAttr(llvm_func, llvm_arg_i, "nonnull");
- dg.addArgAttr(llvm_func, llvm_arg_i, "readonly");
- dg.addArgAttrInt(llvm_func, llvm_arg_i, "align", param_ty.abiAlignment(target));
-
+ dg.addByRefParamAttrs(llvm_func, llvm_arg_i, alignment, it.byval_attr, param_llvm_ty);
llvm_arg_i += 1;
try args.ensureUnusedCapacity(1);
@@ -952,13 +955,13 @@ pub const Object = struct {
if (isByRef(param_ty)) {
args.appendAssumeCapacity(param);
} else {
- const alignment = param_ty.abiAlignment(target);
- const load_inst = builder.buildLoad(param, "");
+ const load_inst = builder.buildLoad(param_llvm_ty, param, "");
load_inst.setAlignment(alignment);
args.appendAssumeCapacity(load_inst);
}
},
.abi_sized_int => {
+ assert(!it.byval_attr);
const param_ty = fn_info.param_types[it.zig_index - 1];
const param = llvm_func.getParam(llvm_arg_i);
llvm_arg_i += 1;
@@ -982,12 +985,13 @@ pub const Object = struct {
if (isByRef(param_ty)) {
args.appendAssumeCapacity(arg_ptr);
} else {
- const load_inst = builder.buildLoad(arg_ptr, "");
+ const load_inst = builder.buildLoad(param_llvm_ty, arg_ptr, "");
load_inst.setAlignment(alignment);
args.appendAssumeCapacity(load_inst);
}
},
.slice => {
+ assert(!it.byval_attr);
const param_ty = fn_info.param_types[it.zig_index - 1];
const ptr_info = param_ty.ptrInfo().data;
@@ -1017,6 +1021,7 @@ pub const Object = struct {
try args.append(aggregate);
},
.multiple_llvm_ints => {
+ assert(!it.byval_attr);
const llvm_ints = it.llvm_types_buffer[0..it.llvm_types_len];
const param_ty = fn_info.param_types[it.zig_index - 1];
const param_llvm_ty = try dg.lowerType(param_ty);
@@ -1033,20 +1038,21 @@ pub const Object = struct {
for (llvm_ints) |_, i_usize| {
const i = @intCast(c_uint, i_usize);
const param = llvm_func.getParam(i);
- const field_ptr = builder.buildStructGEP(casted_ptr, i, "");
+ const field_ptr = builder.buildStructGEP(ints_llvm_ty, casted_ptr, i, "");
const store_inst = builder.buildStore(param, field_ptr);
store_inst.setAlignment(target.cpu.arch.ptrBitWidth() / 8);
}
const is_by_ref = isByRef(param_ty);
const loaded = if (is_by_ref) arg_ptr else l: {
- const load_inst = builder.buildLoad(arg_ptr, "");
+ const load_inst = builder.buildLoad(param_llvm_ty, arg_ptr, "");
load_inst.setAlignment(param_alignment);
break :l load_inst;
};
try args.append(loaded);
},
.multiple_llvm_float => {
+ assert(!it.byval_attr);
const llvm_floats = it.llvm_types_buffer[0..it.llvm_types_len];
const param_ty = fn_info.param_types[it.zig_index - 1];
const param_llvm_ty = try dg.lowerType(param_ty);
@@ -1062,25 +1068,26 @@ pub const Object = struct {
else => {},
}
}
- const ints_llvm_ty = dg.context.structType(field_types.ptr, @intCast(c_uint, field_types.len), .False);
- const casted_ptr = builder.buildBitCast(arg_ptr, ints_llvm_ty.pointerType(0), "");
+ const floats_llvm_ty = dg.context.structType(field_types.ptr, @intCast(c_uint, field_types.len), .False);
+ const casted_ptr = builder.buildBitCast(arg_ptr, floats_llvm_ty.pointerType(0), "");
for (llvm_floats) |_, i_usize| {
const i = @intCast(c_uint, i_usize);
const param = llvm_func.getParam(i);
- const field_ptr = builder.buildStructGEP(casted_ptr, i, "");
+ const field_ptr = builder.buildStructGEP(floats_llvm_ty, casted_ptr, i, "");
const store_inst = builder.buildStore(param, field_ptr);
store_inst.setAlignment(target.cpu.arch.ptrBitWidth() / 8);
}
const is_by_ref = isByRef(param_ty);
const loaded = if (is_by_ref) arg_ptr else l: {
- const load_inst = builder.buildLoad(arg_ptr, "");
+ const load_inst = builder.buildLoad(param_llvm_ty, arg_ptr, "");
load_inst.setAlignment(param_alignment);
break :l load_inst;
};
try args.append(loaded);
},
.as_u16 => {
+ assert(!it.byval_attr);
const param = llvm_func.getParam(llvm_arg_i);
llvm_arg_i += 1;
const casted = builder.buildBitCast(param, dg.context.halfType(), "");
@@ -1102,7 +1109,7 @@ pub const Object = struct {
if (isByRef(param_ty)) {
try args.append(arg_ptr);
} else {
- const load_inst = builder.buildLoad(arg_ptr, "");
+ const load_inst = builder.buildLoad(param_llvm_ty, arg_ptr, "");
load_inst.setAlignment(alignment);
try args.append(load_inst);
}
@@ -2515,12 +2522,38 @@ pub const DeclGen = struct {
dg.addFnAttr(llvm_fn, "noreturn");
}
- var llvm_arg_i = @as(c_uint, @boolToInt(sret)) + @boolToInt(err_return_tracing);
- var it = iterateParamTypes(dg, fn_info);
- while (it.next()) |_| : (llvm_arg_i += 1) {
- if (!it.byval_attr) continue;
- const param = llvm_fn.getParam(llvm_arg_i);
- llvm_fn.addByValAttr(llvm_arg_i, param.typeOf().getElementType());
+ // Add parameter attributes. We handle only the case of extern functions (no body)
+ // because functions with bodies are handled in `updateFunc`.
+ if (is_extern) {
+ var it = iterateParamTypes(dg, fn_info);
+ it.llvm_index += @boolToInt(sret);
+ it.llvm_index += @boolToInt(err_return_tracing);
+ while (it.next()) |lowering| switch (lowering) {
+ .byval => {
+ const param_index = it.zig_index - 1;
+ const param_ty = fn_info.param_types[param_index];
+ if (!isByRef(param_ty)) {
+ dg.addByValParamAttrs(llvm_fn, param_ty, param_index, fn_info, it.llvm_index - 1);
+ }
+ },
+ .byref => {
+ const param_ty = fn_info.param_types[it.zig_index - 1];
+ const param_llvm_ty = try dg.lowerType(param_ty);
+ const alignment = param_ty.abiAlignment(target);
+ dg.addByRefParamAttrs(llvm_fn, it.llvm_index - 1, alignment, it.byval_attr, param_llvm_ty);
+ },
+ // No attributes needed for these.
+ .no_bits,
+ .abi_sized_int,
+ .multiple_llvm_ints,
+ .multiple_llvm_float,
+ .as_u16,
+ .float_array,
+ => continue,
+
+ .slice => unreachable, // extern functions do not support slice types.
+
+ };
}
return llvm_fn;
@@ -2539,7 +2572,7 @@ pub const DeclGen = struct {
}
dg.addFnAttr(llvm_fn, "nounwind");
if (comp.unwind_tables) {
- dg.addFnAttr(llvm_fn, "uwtable");
+ dg.addFnAttrString(llvm_fn, "uwtable", "sync");
}
if (comp.bin_file.options.skip_linker_dependencies or
comp.bin_file.options.no_builtin)
@@ -2697,16 +2730,7 @@ pub const DeclGen = struct {
if (ptr_info.host_size != 0) {
return dg.context.intType(ptr_info.host_size * 8).pointerType(llvm_addrspace);
}
- const elem_ty = ptr_info.pointee_type;
- const lower_elem_ty = switch (elem_ty.zigTypeTag()) {
- .Opaque, .Fn => true,
- .Array => elem_ty.childType().hasRuntimeBitsIgnoreComptime(),
- else => elem_ty.hasRuntimeBitsIgnoreComptime(),
- };
- const llvm_elem_ty = if (lower_elem_ty)
- try dg.lowerType(elem_ty)
- else
- dg.context.intType(8);
+ const llvm_elem_ty = try dg.lowerPtrElemTy(ptr_info.pointee_type);
return llvm_elem_ty.pointerType(llvm_addrspace);
},
.Opaque => switch (t.tag()) {
@@ -3108,6 +3132,23 @@ pub const DeclGen = struct {
);
}
+ /// Use this instead of lowerType when you want to handle correctly the case of elem_ty
+ /// being a zero bit type, but it should still be lowered as an i8 in such case.
+ /// There are other similar cases handled here as well.
+ fn lowerPtrElemTy(dg: *DeclGen, elem_ty: Type) Allocator.Error!*const llvm.Type {
+ const lower_elem_ty = switch (elem_ty.zigTypeTag()) {
+ .Opaque, .Fn => true,
+ .Array => elem_ty.childType().hasRuntimeBitsIgnoreComptime(),
+ else => elem_ty.hasRuntimeBitsIgnoreComptime(),
+ };
+ const llvm_elem_ty = if (lower_elem_ty)
+ try dg.lowerType(elem_ty)
+ else
+ dg.context.intType(8);
+
+ return llvm_elem_ty;
+ }
+
fn lowerValue(dg: *DeclGen, tv: TypedValue) Error!*const llvm.Value {
if (tv.val.isUndef()) {
const llvm_type = try dg.lowerType(tv.ty);
@@ -3858,7 +3899,8 @@ pub const DeclGen = struct {
llvm_u32.constInt(0, .False),
llvm_u32.constInt(llvm_pl_index, .False),
};
- break :blk parent_llvm_ptr.constInBoundsGEP(&indices, indices.len);
+ const parent_llvm_ty = try dg.lowerType(parent_ty);
+ break :blk parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
},
.Struct => {
const field_ty = parent_ty.structFieldType(field_index);
@@ -3888,7 +3930,8 @@ pub const DeclGen = struct {
llvm_u32.constInt(0, .False),
llvm_u32.constInt(llvm_field_index, .False),
};
- break :blk parent_llvm_ptr.constInBoundsGEP(&indices, indices.len);
+ const parent_llvm_ty = try dg.lowerType(parent_ty);
+ break :blk parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
},
else => unreachable,
}
@@ -3902,7 +3945,8 @@ pub const DeclGen = struct {
const indices: [1]*const llvm.Value = .{
llvm_usize.constInt(elem_ptr.index, .False),
};
- break :blk parent_llvm_ptr.constInBoundsGEP(&indices, indices.len);
+ const elem_llvm_ty = try dg.lowerType(elem_ptr.elem_ty);
+ break :blk elem_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
},
.opt_payload_ptr => blk: {
const opt_payload_ptr = ptr_val.castTag(.opt_payload_ptr).?.data;
@@ -3925,7 +3969,8 @@ pub const DeclGen = struct {
llvm_u32.constInt(0, .False),
llvm_u32.constInt(0, .False),
};
- break :blk parent_llvm_ptr.constInBoundsGEP(&indices, indices.len);
+ const opt_llvm_ty = try dg.lowerType(opt_payload_ptr.container_ty);
+ break :blk opt_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
},
.eu_payload_ptr => blk: {
const eu_payload_ptr = ptr_val.castTag(.eu_payload_ptr).?.data;
@@ -3946,7 +3991,8 @@ pub const DeclGen = struct {
llvm_u32.constInt(0, .False),
llvm_u32.constInt(payload_offset, .False),
};
- break :blk parent_llvm_ptr.constInBoundsGEP(&indices, indices.len);
+ const eu_llvm_ty = try dg.lowerType(eu_payload_ptr.container_ty);
+ break :blk eu_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
},
else => unreachable,
};
@@ -4127,6 +4173,59 @@ pub const DeclGen = struct {
return null;
}
}
+
+ fn addByValParamAttrs(
+ dg: DeclGen,
+ llvm_fn: *const llvm.Value,
+ param_ty: Type,
+ param_index: u32,
+ fn_info: Type.Payload.Function.Data,
+ llvm_arg_i: u32,
+ ) void {
+ const target = dg.module.getTarget();
+ if (param_ty.isPtrAtRuntime()) {
+ const ptr_info = param_ty.ptrInfo().data;
+ if (math.cast(u5, param_index)) |i| {
+ if (@truncate(u1, fn_info.noalias_bits >> i) != 0) {
+ dg.addArgAttr(llvm_fn, llvm_arg_i, "noalias");
+ }
+ }
+ if (!param_ty.isPtrLikeOptional() and !ptr_info.@"allowzero") {
+ dg.addArgAttr(llvm_fn, llvm_arg_i, "nonnull");
+ }
+ if (!ptr_info.mutable) {
+ dg.addArgAttr(llvm_fn, llvm_arg_i, "readonly");
+ }
+ if (ptr_info.@"align" != 0) {
+ dg.addArgAttrInt(llvm_fn, llvm_arg_i, "align", ptr_info.@"align");
+ } else {
+ const elem_align = @maximum(
+ ptr_info.pointee_type.abiAlignment(target),
+ 1,
+ );
+ dg.addArgAttrInt(llvm_fn, llvm_arg_i, "align", elem_align);
+ }
+ } else if (ccAbiPromoteInt(fn_info.cc, target, param_ty)) |s| switch (s) {
+ .signed => dg.addArgAttr(llvm_fn, llvm_arg_i, "signext"),
+ .unsigned => dg.addArgAttr(llvm_fn, llvm_arg_i, "zeroext"),
+ };
+ }
+
+ fn addByRefParamAttrs(
+ dg: DeclGen,
+ llvm_fn: *const llvm.Value,
+ llvm_arg_i: u32,
+ alignment: u32,
+ byval_attr: bool,
+ param_llvm_ty: *const llvm.Type,
+ ) void {
+ dg.addArgAttr(llvm_fn, llvm_arg_i, "nonnull");
+ dg.addArgAttr(llvm_fn, llvm_arg_i, "readonly");
+ dg.addArgAttrInt(llvm_fn, llvm_arg_i, "align", alignment);
+ if (byval_attr) {
+ llvm_fn.addByValAttr(llvm_arg_i, param_llvm_ty);
+ }
+ }
};
pub const FuncGen = struct {
@@ -4504,9 +4603,10 @@ pub const FuncGen = struct {
const arg = args[it.zig_index - 1];
const param_ty = self.air.typeOf(arg);
const llvm_arg = try self.resolveInst(arg);
+ const llvm_param_ty = try self.dg.lowerType(param_ty);
if (isByRef(param_ty)) {
const alignment = param_ty.abiAlignment(target);
- const load_inst = self.builder.buildLoad(llvm_arg, "");
+ const load_inst = self.builder.buildLoad(llvm_param_ty, llvm_arg, "");
load_inst.setAlignment(alignment);
try llvm_args.append(load_inst);
} else {
@@ -4516,7 +4616,6 @@ pub const FuncGen = struct {
// which is always lowered to an LLVM type of `*i8`.
// 2. The argument is a global which does act as a pointer, however
// a bitcast is needed in order for the LLVM types to match.
- const llvm_param_ty = try self.dg.lowerType(param_ty);
const casted_ptr = self.builder.buildBitCast(llvm_arg, llvm_param_ty, "");
try llvm_args.append(casted_ptr);
} else {
@@ -4551,7 +4650,7 @@ pub const FuncGen = struct {
if (isByRef(param_ty)) {
const alignment = param_ty.abiAlignment(target);
const casted_ptr = self.builder.buildBitCast(llvm_arg, int_ptr_llvm_ty, "");
- const load_inst = self.builder.buildLoad(casted_ptr, "");
+ const load_inst = self.builder.buildLoad(int_llvm_ty, casted_ptr, "");
load_inst.setAlignment(alignment);
try llvm_args.append(load_inst);
} else {
@@ -4567,7 +4666,7 @@ pub const FuncGen = struct {
const casted_ptr = self.builder.buildBitCast(int_ptr, param_llvm_ty.pointerType(0), "");
const store_inst = self.builder.buildStore(llvm_arg, casted_ptr);
store_inst.setAlignment(alignment);
- const load_inst = self.builder.buildLoad(int_ptr, "");
+ const load_inst = self.builder.buildLoad(int_llvm_ty, int_ptr, "");
load_inst.setAlignment(alignment);
try llvm_args.append(load_inst);
}
@@ -4604,8 +4703,8 @@ pub const FuncGen = struct {
try llvm_args.ensureUnusedCapacity(it.llvm_types_len);
for (llvm_ints) |_, i_usize| {
const i = @intCast(c_uint, i_usize);
- const field_ptr = self.builder.buildStructGEP(casted_ptr, i, "");
- const load_inst = self.builder.buildLoad(field_ptr, "");
+ const field_ptr = self.builder.buildStructGEP(ints_llvm_ty, casted_ptr, i, "");
+ const load_inst = self.builder.buildLoad(field_types[i], field_ptr, "");
load_inst.setAlignment(target.cpu.arch.ptrBitWidth() / 8);
llvm_args.appendAssumeCapacity(load_inst);
}
@@ -4632,13 +4731,13 @@ pub const FuncGen = struct {
else => {},
}
}
- const ints_llvm_ty = self.dg.context.structType(field_types.ptr, @intCast(c_uint, field_types.len), .False);
- const casted_ptr = self.builder.buildBitCast(arg_ptr, ints_llvm_ty.pointerType(0), "");
+ const floats_llvm_ty = self.dg.context.structType(field_types.ptr, @intCast(c_uint, field_types.len), .False);
+ const casted_ptr = self.builder.buildBitCast(arg_ptr, floats_llvm_ty.pointerType(0), "");
try llvm_args.ensureUnusedCapacity(it.llvm_types_len);
for (llvm_floats) |_, i_usize| {
const i = @intCast(c_uint, i_usize);
- const field_ptr = self.builder.buildStructGEP(casted_ptr, i, "");
- const load_inst = self.builder.buildLoad(field_ptr, "");
+ const field_ptr = self.builder.buildStructGEP(floats_llvm_ty, casted_ptr, i, "");
+ const load_inst = self.builder.buildLoad(field_types[i], field_ptr, "");
load_inst.setAlignment(target.cpu.arch.ptrBitWidth() / 8);
llvm_args.appendAssumeCapacity(load_inst);
}
@@ -4662,17 +4761,18 @@ pub const FuncGen = struct {
const float_ty = try self.dg.lowerType(arg_ty.structFieldType(0));
const field_count = @intCast(u32, arg_ty.structFieldCount());
- const arr_ty = float_ty.arrayType(field_count);
+ const array_llvm_ty = float_ty.arrayType(field_count);
- const casted = self.builder.buildBitCast(llvm_arg, arr_ty.pointerType(0), "");
+ const casted = self.builder.buildBitCast(llvm_arg, array_llvm_ty.pointerType(0), "");
const alignment = arg_ty.abiAlignment(target);
- const load_inst = self.builder.buildLoad(casted, "");
+ const load_inst = self.builder.buildLoad(array_llvm_ty, casted, "");
load_inst.setAlignment(alignment);
try llvm_args.append(load_inst);
},
};
const call = self.builder.buildCall(
+ try self.dg.lowerType(zig_fn_ty),
llvm_fn,
llvm_args.items.ptr,
@intCast(c_uint, llvm_args.items.len),
@@ -4698,7 +4798,7 @@ pub const FuncGen = struct {
return rp;
} else {
// our by-ref status disagrees with sret so we must load.
- const loaded = self.builder.buildLoad(rp, "");
+ const loaded = self.builder.buildLoad(llvm_ret_ty, rp, "");
loaded.setAlignment(return_type.abiAlignment(target));
return loaded;
}
@@ -4720,7 +4820,7 @@ pub const FuncGen = struct {
if (isByRef(return_type)) {
return rp;
} else {
- const load_inst = self.builder.buildLoad(rp, "");
+ const load_inst = self.builder.buildLoad(llvm_ret_ty, rp, "");
load_inst.setAlignment(alignment);
return load_inst;
}
@@ -4778,7 +4878,7 @@ pub const FuncGen = struct {
// operand is a pointer however self.ret_ptr is null so that means
// we need to return a value.
const casted_ptr = self.builder.buildBitCast(operand, ptr_abi_ty, "");
- const load_inst = self.builder.buildLoad(casted_ptr, "");
+ const load_inst = self.builder.buildLoad(abi_ret_ty, casted_ptr, "");
load_inst.setAlignment(alignment);
_ = self.builder.buildRet(load_inst);
return null;
@@ -4795,7 +4895,7 @@ pub const FuncGen = struct {
const store_inst = self.builder.buildStore(operand, rp);
store_inst.setAlignment(alignment);
const casted_ptr = self.builder.buildBitCast(rp, ptr_abi_ty, "");
- const load_inst = self.builder.buildLoad(casted_ptr, "");
+ const load_inst = self.builder.buildLoad(abi_ret_ty, casted_ptr, "");
load_inst.setAlignment(alignment);
_ = self.builder.buildRet(load_inst);
return null;
@@ -4830,7 +4930,7 @@ pub const FuncGen = struct {
const ptr_abi_ty = abi_ret_ty.pointerType(0);
break :p self.builder.buildBitCast(ptr, ptr_abi_ty, "");
};
- const loaded = self.builder.buildLoad(casted_ptr, "");
+ const loaded = self.builder.buildLoad(abi_ret_ty, casted_ptr, "");
loaded.setAlignment(ret_ty.abiAlignment(target));
_ = self.builder.buildRet(loaded);
return null;
@@ -4870,7 +4970,7 @@ pub const FuncGen = struct {
const operand = try self.resolveInst(un_op);
const llvm_fn = try self.getCmpLtErrorsLenFunction();
const args: [1]*const llvm.Value = .{operand};
- return self.builder.buildCall(llvm_fn, &args, args.len, .Fast, .Auto, "");
+ return self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &args, args.len, .Fast, .Auto, "");
}
fn cmp(
@@ -4897,8 +4997,9 @@ pub const FuncGen = struct {
// We need to emit instructions to check for equality/inequality
// of optionals that are not pointers.
const is_by_ref = isByRef(scalar_ty);
- const lhs_non_null = self.optIsNonNull(lhs, is_by_ref);
- const rhs_non_null = self.optIsNonNull(rhs, is_by_ref);
+ const opt_llvm_ty = try self.dg.lowerType(scalar_ty);
+ const lhs_non_null = self.optIsNonNull(opt_llvm_ty, lhs, is_by_ref);
+ const rhs_non_null = self.optIsNonNull(opt_llvm_ty, rhs, is_by_ref);
const llvm_i2 = self.context.intType(2);
const lhs_non_null_i2 = self.builder.buildZExt(lhs_non_null, llvm_i2, "");
const rhs_non_null_i2 = self.builder.buildZExt(rhs_non_null, llvm_i2, "");
@@ -4921,8 +5022,8 @@ pub const FuncGen = struct {
_ = self.builder.buildBr(end_block);
self.builder.positionBuilderAtEnd(both_pl_block);
- const lhs_payload = self.optPayloadHandle(lhs, scalar_ty);
- const rhs_payload = self.optPayloadHandle(rhs, scalar_ty);
+ const lhs_payload = try self.optPayloadHandle(opt_llvm_ty, lhs, scalar_ty);
+ const rhs_payload = try self.optPayloadHandle(opt_llvm_ty, rhs, scalar_ty);
const payload_cmp = try self.cmp(lhs_payload, rhs_payload, payload_ty, op);
_ = self.builder.buildBr(end_block);
const both_pl_block_end = self.builder.getInsertBlock();
@@ -5087,10 +5188,18 @@ pub const FuncGen = struct {
return lowerTry(self, err_union_ptr, body, err_union_ty, true, result_ty);
}
- fn lowerTry(fg: *FuncGen, err_union: *const llvm.Value, body: []const Air.Inst.Index, err_union_ty: Type, operand_is_ptr: bool, result_ty: Type) !?*const llvm.Value {
+ fn lowerTry(
+ fg: *FuncGen,
+ err_union: *const llvm.Value,
+ body: []const Air.Inst.Index,
+ err_union_ty: Type,
+ operand_is_ptr: bool,
+ result_ty: Type,
+ ) !?*const llvm.Value {
const payload_ty = err_union_ty.errorUnionPayload();
const payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime();
const target = fg.dg.module.getTarget();
+ const err_union_llvm_ty = try fg.dg.lowerType(err_union_ty);
if (!err_union_ty.errorUnionSet().errorSetIsEmpty()) {
const is_err = err: {
@@ -5098,14 +5207,17 @@ pub const FuncGen = struct {
const zero = err_set_ty.constNull();
if (!payload_has_bits) {
// TODO add alignment to this load
- const loaded = if (operand_is_ptr) fg.builder.buildLoad(err_union, "") else err_union;
+ const loaded = if (operand_is_ptr)
+ fg.builder.buildLoad(err_set_ty, err_union, "")
+ else
+ err_union;
break :err fg.builder.buildICmp(.NE, loaded, zero, "");
}
const err_field_index = errUnionErrorOffset(payload_ty, target);
if (operand_is_ptr or isByRef(err_union_ty)) {
- const err_field_ptr = fg.builder.buildStructGEP(err_union, err_field_index, "");
+ const err_field_ptr = fg.builder.buildStructGEP(err_union_llvm_ty, err_union, err_field_index, "");
// TODO add alignment to this load
- const loaded = fg.builder.buildLoad(err_field_ptr, "");
+ const loaded = fg.builder.buildLoad(err_set_ty, err_field_ptr, "");
break :err fg.builder.buildICmp(.NE, loaded, zero, "");
}
const loaded = fg.builder.buildExtractValue(err_union, err_field_index, "");
@@ -5131,13 +5243,13 @@ pub const FuncGen = struct {
}
const offset = errUnionPayloadOffset(payload_ty, target);
if (operand_is_ptr or isByRef(payload_ty)) {
- return fg.builder.buildStructGEP(err_union, offset, "");
+ return fg.builder.buildStructGEP(err_union_llvm_ty, err_union, offset, "");
} else if (isByRef(err_union_ty)) {
- const payload_ptr = fg.builder.buildStructGEP(err_union, offset, "");
+ const payload_ptr = fg.builder.buildStructGEP(err_union_llvm_ty, err_union, offset, "");
if (isByRef(payload_ty)) {
return payload_ptr;
}
- const load_inst = fg.builder.buildLoad(payload_ptr, "");
+ const load_inst = fg.builder.buildLoad(payload_ptr.getGEPResultElementType(), payload_ptr, "");
load_inst.setAlignment(payload_ty.abiAlignment(target));
return load_inst;
}
@@ -5232,7 +5344,8 @@ pub const FuncGen = struct {
const indices: [2]*const llvm.Value = .{
llvm_usize.constNull(), llvm_usize.constNull(),
};
- const ptr = self.builder.buildInBoundsGEP(operand, &indices, indices.len, "");
+ const array_llvm_ty = try self.dg.lowerType(array_ty);
+ const ptr = self.builder.buildInBoundsGEP(array_llvm_ty, operand, &indices, indices.len, "");
const partial = self.builder.buildInsertValue(slice_llvm_ty.getUndef(), ptr, 0, "");
return self.builder.buildInsertValue(partial, len, 1, "");
}
@@ -5293,7 +5406,7 @@ pub const FuncGen = struct {
const libc_fn = self.getLibcFunction(fn_name, &param_types, dest_llvm_ty);
const params = [1]*const llvm.Value{extended};
- return self.builder.buildCall(libc_fn, &params, params.len, .C, .Auto, "");
+ return self.builder.buildCall(libc_fn.globalGetValueType(), libc_fn, &params, params.len, .C, .Auto, "");
}
fn airFloatToInt(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*const llvm.Value {
@@ -5348,7 +5461,7 @@ pub const FuncGen = struct {
const libc_fn = self.getLibcFunction(fn_name, &param_types, libc_ret_ty);
const params = [1]*const llvm.Value{operand};
- var result = self.builder.buildCall(libc_fn, &params, params.len, .C, .Auto, "");
+ var result = self.builder.buildCall(libc_fn.globalGetValueType(), libc_fn, &params, params.len, .C, .Auto, "");
if (libc_ret_ty != ret_ty) result = self.builder.buildBitCast(result, ret_ty, "");
if (ret_ty != dest_llvm_ty) result = self.builder.buildTrunc(result, dest_llvm_ty, "");
@@ -5368,8 +5481,10 @@ pub const FuncGen = struct {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const slice_ptr = try self.resolveInst(ty_op.operand);
+ const slice_ptr_ty = self.air.typeOf(ty_op.operand);
+ const slice_llvm_ty = try self.dg.lowerPtrElemTy(slice_ptr_ty.childType());
- return self.builder.buildStructGEP(slice_ptr, index, "");
+ return self.builder.buildStructGEP(slice_llvm_ty, slice_ptr, index, "");
}
fn airSliceElemVal(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
@@ -5379,7 +5494,10 @@ pub const FuncGen = struct {
const slice = try self.resolveInst(bin_op.lhs);
const index = try self.resolveInst(bin_op.rhs);
- const ptr = self.sliceElemPtr(slice, index);
+ const llvm_elem_ty = try self.dg.lowerPtrElemTy(slice_ty.childType());
+ const base_ptr = self.builder.buildExtractValue(slice, 0, "");
+ const indices: [1]*const llvm.Value = .{index};
+ const ptr = self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, "");
return self.load(ptr, slice_ty);
}
@@ -5387,10 +5505,14 @@ pub const FuncGen = struct {
if (self.liveness.isUnused(inst)) return null;
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
+ const slice_ty = self.air.typeOf(bin_op.lhs);
const slice = try self.resolveInst(bin_op.lhs);
const index = try self.resolveInst(bin_op.rhs);
- return self.sliceElemPtr(slice, index);
+ const llvm_elem_ty = try self.dg.lowerPtrElemTy(slice_ty.childType());
+ const base_ptr = self.builder.buildExtractValue(slice, 0, "");
+ const indices: [1]*const llvm.Value = .{index};
+ return self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, "");
}
fn airArrayElemVal(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
@@ -5401,13 +5523,15 @@ pub const FuncGen = struct {
const array_llvm_val = try self.resolveInst(bin_op.lhs);
const rhs = try self.resolveInst(bin_op.rhs);
if (isByRef(array_ty)) {
+ const array_llvm_ty = try self.dg.lowerType(array_ty);
const indices: [2]*const llvm.Value = .{ self.context.intType(32).constNull(), rhs };
- const elem_ptr = self.builder.buildInBoundsGEP(array_llvm_val, &indices, indices.len, "");
+ const elem_ptr = self.builder.buildInBoundsGEP(array_llvm_ty, array_llvm_val, &indices, indices.len, "");
const elem_ty = array_ty.childType();
if (isByRef(elem_ty)) {
return elem_ptr;
} else {
- return self.builder.buildLoad(elem_ptr, "");
+ const elem_llvm_ty = try self.dg.lowerType(elem_ty);
+ return self.builder.buildLoad(elem_llvm_ty, elem_ptr, "");
}
}
@@ -5420,15 +5544,17 @@ pub const FuncGen = struct {
const ptr_ty = self.air.typeOf(bin_op.lhs);
if (!ptr_ty.isVolatilePtr() and self.liveness.isUnused(inst)) return null;
+ const llvm_elem_ty = try self.dg.lowerPtrElemTy(ptr_ty.childType());
const base_ptr = try self.resolveInst(bin_op.lhs);
const rhs = try self.resolveInst(bin_op.rhs);
+ // TODO: when we go fully opaque pointers in LLVM 16 we can remove this branch
const ptr = if (ptr_ty.isSinglePointer()) ptr: {
// If this is a single-item pointer to an array, we need another index in the GEP.
const indices: [2]*const llvm.Value = .{ self.context.intType(32).constNull(), rhs };
- break :ptr self.builder.buildInBoundsGEP(base_ptr, &indices, indices.len, "");
+ break :ptr self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, "");
} else ptr: {
const indices: [1]*const llvm.Value = .{rhs};
- break :ptr self.builder.buildInBoundsGEP(base_ptr, &indices, indices.len, "");
+ break :ptr self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, "");
};
return self.load(ptr, ptr_ty);
}
@@ -5444,13 +5570,14 @@ pub const FuncGen = struct {
const base_ptr = try self.resolveInst(bin_op.lhs);
const rhs = try self.resolveInst(bin_op.rhs);
+ const llvm_elem_ty = try self.dg.lowerPtrElemTy(elem_ty);
if (ptr_ty.isSinglePointer()) {
// If this is a single-item pointer to an array, we need another index in the GEP.
const indices: [2]*const llvm.Value = .{ self.context.intType(32).constNull(), rhs };
- return self.builder.buildInBoundsGEP(base_ptr, &indices, indices.len, "");
+ return self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, "");
} else {
const indices: [1]*const llvm.Value = .{rhs};
- return self.builder.buildInBoundsGEP(base_ptr, &indices, indices.len, "");
+ return self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, "");
}
}
@@ -5534,20 +5661,22 @@ pub const FuncGen = struct {
assert(struct_ty.containerLayout() != .Packed);
var ptr_ty_buf: Type.Payload.Pointer = undefined;
const llvm_field_index = llvmFieldIndex(struct_ty, field_index, target, &ptr_ty_buf).?;
- const field_ptr = self.builder.buildStructGEP(struct_llvm_val, llvm_field_index, "");
+ const struct_llvm_ty = try self.dg.lowerType(struct_ty);
+ const field_ptr = self.builder.buildStructGEP(struct_llvm_ty, struct_llvm_val, llvm_field_index, "");
const field_ptr_ty = Type.initPayload(&ptr_ty_buf.base);
return self.load(field_ptr, field_ptr_ty);
},
.Union => {
- const llvm_field_ty = try self.dg.lowerType(field_ty);
+ const union_llvm_ty = try self.dg.lowerType(struct_ty);
const layout = struct_ty.unionGetLayout(target);
const payload_index = @boolToInt(layout.tag_align >= layout.payload_align);
- const union_field_ptr = self.builder.buildStructGEP(struct_llvm_val, payload_index, "");
+ const union_field_ptr = self.builder.buildStructGEP(union_llvm_ty, struct_llvm_val, payload_index, "");
+ const llvm_field_ty = try self.dg.lowerType(field_ty);
const field_ptr = self.builder.buildBitCast(union_field_ptr, llvm_field_ty.pointerType(0), "");
if (isByRef(field_ty)) {
return field_ptr;
} else {
- return self.builder.buildLoad(field_ptr, "");
+ return self.builder.buildLoad(llvm_field_ty, field_ptr, "");
}
},
else => unreachable,
@@ -5776,7 +5905,9 @@ pub const FuncGen = struct {
const max_param_count = inputs.len + outputs.len;
const llvm_param_types = try arena.alloc(*const llvm.Type, max_param_count);
const llvm_param_values = try arena.alloc(*const llvm.Value, max_param_count);
- const llvm_param_attrs = try arena.alloc(bool, max_param_count);
+ // This stores whether we need to add an elementtype attribute and
+ // if so, the element type itself.
+ const llvm_param_attrs = try arena.alloc(?*const llvm.Type, max_param_count);
const target = self.dg.module.getTarget();
var llvm_ret_i: usize = 0;
@@ -5794,7 +5925,7 @@ pub const FuncGen = struct {
// for the string, we still use the next u32 for the null terminator.
extra_i += (constraint.len + name.len + (2 + 3)) / 4;
- try llvm_constraints.ensureUnusedCapacity(self.gpa, constraint.len + 1);
+ try llvm_constraints.ensureUnusedCapacity(self.gpa, constraint.len + 3);
if (total_i != 0) {
llvm_constraints.appendAssumeCapacity(',');
}
@@ -5803,8 +5934,10 @@ pub const FuncGen = struct {
// Pass any non-return outputs indirectly, if the constraint accepts a memory location
llvm_ret_indirect[i] = (output != .none) and constraintAllowsMemory(constraint);
if (output != .none) {
- try llvm_constraints.ensureUnusedCapacity(self.gpa, llvm_constraints.capacity + 1);
const output_inst = try self.resolveInst(output);
+ const output_ty = self.air.typeOf(output);
+ assert(output_ty.zigTypeTag() == .Pointer);
+ const elem_llvm_ty = try self.dg.lowerPtrElemTy(output_ty.childType());
if (llvm_ret_indirect[i]) {
// Pass the result by reference as an indirect output (e.g. "=*m")
@@ -5812,11 +5945,11 @@ pub const FuncGen = struct {
llvm_param_values[llvm_param_i] = output_inst;
llvm_param_types[llvm_param_i] = output_inst.typeOf();
- llvm_param_attrs[llvm_param_i] = true;
+ llvm_param_attrs[llvm_param_i] = elem_llvm_ty;
llvm_param_i += 1;
} else {
// Pass the result directly (e.g. "=r")
- llvm_ret_types[llvm_ret_i] = output_inst.typeOf().getElementType();
+ llvm_ret_types[llvm_ret_i] = elem_llvm_ty;
llvm_ret_i += 1;
}
} else {
@@ -5854,16 +5987,19 @@ pub const FuncGen = struct {
const arg_llvm_value = try self.resolveInst(input);
const arg_ty = self.air.typeOf(input);
+ var llvm_elem_ty: ?*const llvm.Type = null;
if (isByRef(arg_ty)) {
+ llvm_elem_ty = try self.dg.lowerPtrElemTy(arg_ty);
if (constraintAllowsMemory(constraint)) {
llvm_param_values[llvm_param_i] = arg_llvm_value;
llvm_param_types[llvm_param_i] = arg_llvm_value.typeOf();
} else {
const alignment = arg_ty.abiAlignment(target);
- const load_inst = self.builder.buildLoad(arg_llvm_value, "");
+ const arg_llvm_ty = try self.dg.lowerType(arg_ty);
+ const load_inst = self.builder.buildLoad(arg_llvm_ty, arg_llvm_value, "");
load_inst.setAlignment(alignment);
llvm_param_values[llvm_param_i] = load_inst;
- llvm_param_types[llvm_param_i] = load_inst.typeOf();
+ llvm_param_types[llvm_param_i] = arg_llvm_ty;
}
} else {
if (constraintAllowsRegister(constraint)) {
@@ -5897,7 +6033,12 @@ pub const FuncGen = struct {
// In the case of indirect inputs, LLVM requires the callsite to have
// an elementtype(<ty>) attribute.
- llvm_param_attrs[llvm_param_i] = constraint[0] == '*';
+ if (constraint[0] == '*') {
+ llvm_param_attrs[llvm_param_i] = llvm_elem_ty orelse
+ try self.dg.lowerPtrElemTy(arg_ty.childType());
+ } else {
+ llvm_param_attrs[llvm_param_i] = null;
+ }
llvm_param_i += 1;
total_i += 1;
@@ -6024,6 +6165,7 @@ pub const FuncGen = struct {
.False,
);
const call = self.builder.buildCall(
+ llvm_fn_ty,
asm_fn,
llvm_param_values.ptr,
@intCast(c_uint, param_count),
@@ -6031,10 +6173,9 @@ pub const FuncGen = struct {
.Auto,
"",
);
- for (llvm_param_attrs[0..param_count]) |need_elem_ty, i| {
- if (need_elem_ty) {
- const elem_ty = llvm_param_types[i].getElementType();
- llvm.setCallElemTypeAttr(call, i, elem_ty);
+ for (llvm_param_attrs[0..param_count]) |llvm_elem_ty, i| {
+ if (llvm_elem_ty) |llvm_ty| {
+ llvm.setCallElemTypeAttr(call, i, llvm_ty);
}
}
@@ -6074,9 +6215,12 @@ pub const FuncGen = struct {
const operand = try self.resolveInst(un_op);
const operand_ty = self.air.typeOf(un_op);
const optional_ty = if (operand_is_ptr) operand_ty.childType() else operand_ty;
+ const optional_llvm_ty = try self.dg.lowerType(optional_ty);
if (optional_ty.optionalReprIsPayload()) {
- const optional_llvm_ty = try self.dg.lowerType(optional_ty);
- const loaded = if (operand_is_ptr) self.builder.buildLoad(operand, "") else operand;
+ const loaded = if (operand_is_ptr)
+ self.builder.buildLoad(optional_llvm_ty, operand, "")
+ else
+ operand;
return self.builder.buildICmp(pred, loaded, optional_llvm_ty.constNull(), "");
}
@@ -6085,13 +6229,16 @@ pub const FuncGen = struct {
var buf: Type.Payload.ElemType = undefined;
const payload_ty = optional_ty.optionalChild(&buf);
if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
- const loaded = if (operand_is_ptr) self.builder.buildLoad(operand, "") else operand;
+ const loaded = if (operand_is_ptr)
+ self.builder.buildLoad(optional_llvm_ty, operand, "")
+ else
+ operand;
const llvm_i8 = self.dg.context.intType(8);
return self.builder.buildICmp(pred, loaded, llvm_i8.constNull(), "");
}
const is_by_ref = operand_is_ptr or isByRef(optional_ty);
- const non_null_bit = self.optIsNonNull(operand, is_by_ref);
+ const non_null_bit = self.optIsNonNull(optional_llvm_ty, operand, is_by_ref);
if (pred == .EQ) {
return self.builder.buildNot(non_null_bit, "");
} else {
@@ -6112,7 +6259,7 @@ pub const FuncGen = struct {
const operand_ty = self.air.typeOf(un_op);
const err_union_ty = if (operand_is_ptr) operand_ty.childType() else operand_ty;
const payload_ty = err_union_ty.errorUnionPayload();
- const err_set_ty = try self.dg.lowerType(Type.initTag(.anyerror));
+ const err_set_ty = try self.dg.lowerType(Type.anyerror);
const zero = err_set_ty.constNull();
if (err_union_ty.errorUnionSet().errorSetIsEmpty()) {
@@ -6125,7 +6272,10 @@ pub const FuncGen = struct {
}
if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
- const loaded = if (operand_is_ptr) self.builder.buildLoad(operand, "") else operand;
+ const loaded = if (operand_is_ptr)
+ self.builder.buildLoad(try self.dg.lowerType(err_union_ty), operand, "")
+ else
+ operand;
return self.builder.buildICmp(op, loaded, zero, "");
}
@@ -6133,8 +6283,9 @@ pub const FuncGen = struct {
const err_field_index = errUnionErrorOffset(payload_ty, target);
if (operand_is_ptr or isByRef(err_union_ty)) {
- const err_field_ptr = self.builder.buildStructGEP(operand, err_field_index, "");
- const loaded = self.builder.buildLoad(err_field_ptr, "");
+ const err_union_llvm_ty = try self.dg.lowerType(err_union_ty);
+ const err_field_ptr = self.builder.buildStructGEP(err_union_llvm_ty, operand, err_field_index, "");
+ const loaded = self.builder.buildLoad(err_set_ty, err_field_ptr, "");
return self.builder.buildICmp(op, loaded, zero, "");
}
@@ -6155,7 +6306,7 @@ pub const FuncGen = struct {
// We have a pointer to a zero-bit value and we need to return
// a pointer to a zero-bit value.
- // TODO once we update to LLVM 14 this bitcast won't be necessary.
+ // TODO once we update to LLVM 16 this bitcast won't be necessary.
const res_ptr_ty = try self.dg.lowerType(result_ty);
return self.builder.buildBitCast(operand, res_ptr_ty, "");
}
@@ -6163,7 +6314,8 @@ pub const FuncGen = struct {
// The payload and the optional are the same value.
return operand;
}
- return self.builder.buildStructGEP(operand, 0, "");
+ const optional_llvm_ty = try self.dg.lowerType(optional_ty);
+ return self.builder.buildStructGEP(optional_llvm_ty, operand, 0, "");
}
fn airOptionalPayloadPtrSet(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
@@ -6180,7 +6332,7 @@ pub const FuncGen = struct {
// We have a pointer to a i8. We need to set it to 1 and then return the same pointer.
_ = self.builder.buildStore(non_null_bit, operand);
- // TODO once we update to LLVM 14 this bitcast won't be necessary.
+ // TODO once we update to LLVM 16 this bitcast won't be necessary.
const res_ptr_ty = try self.dg.lowerType(result_ty);
return self.builder.buildBitCast(operand, res_ptr_ty, "");
}
@@ -6191,7 +6343,8 @@ pub const FuncGen = struct {
}
// First set the non-null bit.
- const non_null_ptr = self.builder.buildStructGEP(operand, 1, "");
+ const optional_llvm_ty = try self.dg.lowerType(optional_ty);
+ const non_null_ptr = self.builder.buildStructGEP(optional_llvm_ty, operand, 1, "");
// TODO set alignment on this store
_ = self.builder.buildStore(non_null_bit, non_null_ptr);
@@ -6199,7 +6352,7 @@ pub const FuncGen = struct {
if (self.liveness.isUnused(inst))
return null;
- return self.builder.buildStructGEP(operand, 0, "");
+ return self.builder.buildStructGEP(optional_llvm_ty, operand, 0, "");
}
fn airOptionalPayload(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
@@ -6216,7 +6369,8 @@ pub const FuncGen = struct {
return operand;
}
- return self.optPayloadHandle(operand, optional_ty);
+ const opt_llvm_ty = try self.dg.lowerType(optional_ty);
+ return self.optPayloadHandle(opt_llvm_ty, operand, optional_ty);
}
fn airErrUnionPayload(
@@ -6242,14 +6396,15 @@ pub const FuncGen = struct {
return self.builder.buildBitCast(operand, res_ptr_ty, "");
}
const offset = errUnionPayloadOffset(payload_ty, target);
+ const err_union_llvm_ty = try self.dg.lowerType(err_union_ty);
if (operand_is_ptr or isByRef(payload_ty)) {
- return self.builder.buildStructGEP(operand, offset, "");
+ return self.builder.buildStructGEP(err_union_llvm_ty, operand, offset, "");
} else if (isByRef(err_union_ty)) {
- const payload_ptr = self.builder.buildStructGEP(operand, offset, "");
+ const payload_ptr = self.builder.buildStructGEP(err_union_llvm_ty, operand, offset, "");
if (isByRef(payload_ty)) {
return payload_ptr;
}
- const load_inst = self.builder.buildLoad(payload_ptr, "");
+ const load_inst = self.builder.buildLoad(payload_ptr.getGEPResultElementType(), payload_ptr, "");
load_inst.setAlignment(payload_ty.abiAlignment(target));
return load_inst;
}
@@ -6277,18 +6432,21 @@ pub const FuncGen = struct {
}
}
+ const err_set_llvm_ty = try self.dg.lowerType(Type.anyerror);
+
const payload_ty = err_union_ty.errorUnionPayload();
if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
if (!operand_is_ptr) return operand;
- return self.builder.buildLoad(operand, "");
+ return self.builder.buildLoad(err_set_llvm_ty, operand, "");
}
const target = self.dg.module.getTarget();
const offset = errUnionErrorOffset(payload_ty, target);
if (operand_is_ptr or isByRef(err_union_ty)) {
- const err_field_ptr = self.builder.buildStructGEP(operand, offset, "");
- return self.builder.buildLoad(err_field_ptr, "");
+ const err_union_llvm_ty = try self.dg.lowerType(err_union_ty);
+ const err_field_ptr = self.builder.buildStructGEP(err_union_llvm_ty, operand, offset, "");
+ return self.builder.buildLoad(err_set_llvm_ty, err_field_ptr, "");
}
return self.builder.buildExtractValue(operand, offset, "");
@@ -6297,19 +6455,20 @@ pub const FuncGen = struct {
fn airErrUnionPayloadPtrSet(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const operand = try self.resolveInst(ty_op.operand);
- const error_union_ty = self.air.typeOf(ty_op.operand).childType();
+ const err_union_ty = self.air.typeOf(ty_op.operand).childType();
- const payload_ty = error_union_ty.errorUnionPayload();
+ const payload_ty = err_union_ty.errorUnionPayload();
const non_error_val = try self.dg.lowerValue(.{ .ty = Type.anyerror, .val = Value.zero });
if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
_ = self.builder.buildStore(non_error_val, operand);
return operand;
}
const target = self.dg.module.getTarget();
+ const err_union_llvm_ty = try self.dg.lowerType(err_union_ty);
{
const error_offset = errUnionErrorOffset(payload_ty, target);
// First set the non-error value.
- const non_null_ptr = self.builder.buildStructGEP(operand, error_offset, "");
+ const non_null_ptr = self.builder.buildStructGEP(err_union_llvm_ty, operand, error_offset, "");
const store_inst = self.builder.buildStore(non_error_val, non_null_ptr);
store_inst.setAlignment(Type.anyerror.abiAlignment(target));
}
@@ -6318,7 +6477,7 @@ pub const FuncGen = struct {
return null;
const payload_offset = errUnionPayloadOffset(payload_ty, target);
- return self.builder.buildStructGEP(operand, payload_offset, "");
+ return self.builder.buildStructGEP(err_union_llvm_ty, operand, payload_offset, "");
}
fn airErrReturnTrace(self: *FuncGen, _: Air.Inst.Index) !?*const llvm.Value {
@@ -6350,14 +6509,14 @@ pub const FuncGen = struct {
const target = self.dg.module.getTarget();
const optional_ptr = self.buildAlloca(llvm_optional_ty);
optional_ptr.setAlignment(optional_ty.abiAlignment(target));
- const payload_ptr = self.builder.buildStructGEP(optional_ptr, 0, "");
+ const payload_ptr = self.builder.buildStructGEP(llvm_optional_ty, optional_ptr, 0, "");
var ptr_ty_payload: Type.Payload.ElemType = .{
.base = .{ .tag = .single_mut_pointer },
.data = payload_ty,
};
const payload_ptr_ty = Type.initPayload(&ptr_ty_payload.base);
self.store(payload_ptr, payload_ptr_ty, operand, .NotAtomic);
- const non_null_ptr = self.builder.buildStructGEP(optional_ptr, 1, "");
+ const non_null_ptr = self.builder.buildStructGEP(llvm_optional_ty, optional_ptr, 1, "");
_ = self.builder.buildStore(non_null_bit, non_null_ptr);
return optional_ptr;
}
@@ -6384,10 +6543,10 @@ pub const FuncGen = struct {
if (isByRef(err_un_ty)) {
const result_ptr = self.buildAlloca(err_un_llvm_ty);
result_ptr.setAlignment(err_un_ty.abiAlignment(target));
- const err_ptr = self.builder.buildStructGEP(result_ptr, error_offset, "");
+ const err_ptr = self.builder.buildStructGEP(err_un_llvm_ty, result_ptr, error_offset, "");
const store_inst = self.builder.buildStore(ok_err_code, err_ptr);
store_inst.setAlignment(Type.anyerror.abiAlignment(target));
- const payload_ptr = self.builder.buildStructGEP(result_ptr, payload_offset, "");
+ const payload_ptr = self.builder.buildStructGEP(err_un_llvm_ty, result_ptr, payload_offset, "");
var ptr_ty_payload: Type.Payload.ElemType = .{
.base = .{ .tag = .single_mut_pointer },
.data = payload_ty,
@@ -6419,10 +6578,10 @@ pub const FuncGen = struct {
if (isByRef(err_un_ty)) {
const result_ptr = self.buildAlloca(err_un_llvm_ty);
result_ptr.setAlignment(err_un_ty.abiAlignment(target));
- const err_ptr = self.builder.buildStructGEP(result_ptr, error_offset, "");
+ const err_ptr = self.builder.buildStructGEP(err_un_llvm_ty, result_ptr, error_offset, "");
const store_inst = self.builder.buildStore(operand, err_ptr);
store_inst.setAlignment(Type.anyerror.abiAlignment(target));
- const payload_ptr = self.builder.buildStructGEP(result_ptr, payload_offset, "");
+ const payload_ptr = self.builder.buildStructGEP(err_un_llvm_ty, result_ptr, payload_offset, "");
var ptr_ty_payload: Type.Payload.ElemType = .{
.base = .{ .tag = .single_mut_pointer },
.data = payload_ty,
@@ -6447,7 +6606,7 @@ pub const FuncGen = struct {
const llvm_u32 = self.context.intType(32);
const llvm_fn = self.getIntrinsic("llvm.wasm.memory.size", &.{llvm_u32});
const args: [1]*const llvm.Value = .{llvm_u32.constInt(index, .False)};
- return self.builder.buildCall(llvm_fn, &args, args.len, .Fast, .Auto, "");
+ return self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &args, args.len, .Fast, .Auto, "");
}
fn airWasmMemoryGrow(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
@@ -6460,7 +6619,7 @@ pub const FuncGen = struct {
llvm_u32.constInt(index, .False),
operand,
};
- return self.builder.buildCall(llvm_fn, &args, args.len, .Fast, .Auto, "");
+ return self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &args, args.len, .Fast, .Auto, "");
}
fn airMin(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
@@ -6763,15 +6922,16 @@ pub const FuncGen = struct {
const base_ptr = try self.resolveInst(bin_op.lhs);
const offset = try self.resolveInst(bin_op.rhs);
const ptr_ty = self.air.typeOf(bin_op.lhs);
+ const llvm_elem_ty = try self.dg.lowerPtrElemTy(ptr_ty.childType());
if (ptr_ty.ptrSize() == .One) {
// It's a pointer to an array, so according to LLVM we need an extra GEP index.
const indices: [2]*const llvm.Value = .{
self.context.intType(32).constNull(), offset,
};
- return self.builder.buildInBoundsGEP(base_ptr, &indices, indices.len, "");
+ return self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, "");
} else {
const indices: [1]*const llvm.Value = .{offset};
- return self.builder.buildInBoundsGEP(base_ptr, &indices, indices.len, "");
+ return self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, "");
}
}
@@ -6784,15 +6944,16 @@ pub const FuncGen = struct {
const offset = try self.resolveInst(bin_op.rhs);
const negative_offset = self.builder.buildNeg(offset, "");
const ptr_ty = self.air.typeOf(bin_op.lhs);
+ const llvm_elem_ty = try self.dg.lowerPtrElemTy(ptr_ty.childType());
if (ptr_ty.ptrSize() == .One) {
// It's a pointer to an array, so according to LLVM we need an extra GEP index.
const indices: [2]*const llvm.Value = .{
self.context.intType(32).constNull(), negative_offset,
};
- return self.builder.buildInBoundsGEP(base_ptr, &indices, indices.len, "");
+ return self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, "");
} else {
const indices: [1]*const llvm.Value = .{negative_offset};
- return self.builder.buildInBoundsGEP(base_ptr, &indices, indices.len, "");
+ return self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, "");
}
}
@@ -6823,7 +6984,7 @@ pub const FuncGen = struct {
const tg = self.dg.module.getTarget();
const llvm_fn = self.getIntrinsic(intrinsic_name, &.{llvm_lhs_ty});
- const result_struct = self.builder.buildCall(llvm_fn, &[_]*const llvm.Value{ lhs, rhs }, 2, .Fast, .Auto, "");
+ const result_struct = self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &[_]*const llvm.Value{ lhs, rhs }, 2, .Fast, .Auto, "");
const result = self.builder.buildExtractValue(result_struct, 0, "");
const overflow_bit = self.builder.buildExtractValue(result_struct, 1, "");
@@ -6838,12 +6999,12 @@ pub const FuncGen = struct {
const result_alignment = dest_ty.abiAlignment(target);
alloca_inst.setAlignment(result_alignment);
{
- const field_ptr = self.builder.buildStructGEP(alloca_inst, result_index, "");
+ const field_ptr = self.builder.buildStructGEP(llvm_dest_ty, alloca_inst, result_index, "");
const store_inst = self.builder.buildStore(result, field_ptr);
store_inst.setAlignment(result_alignment);
}
{
- const field_ptr = self.builder.buildStructGEP(alloca_inst, overflow_index, "");
+ const field_ptr = self.builder.buildStructGEP(llvm_dest_ty, alloca_inst, overflow_index, "");
const store_inst = self.builder.buildStore(overflow_bit, field_ptr);
store_inst.setAlignment(1);
}
@@ -6875,7 +7036,7 @@ pub const FuncGen = struct {
for (args_vectors) |arg_vector, k| {
args[k] = self.builder.buildExtractElement(arg_vector, index_i32, "");
}
- const result_elem = self.builder.buildCall(llvm_fn, &args, args_len, .C, .Auto, "");
+ const result_elem = self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &args, args_len, .C, .Auto, "");
result = self.builder.buildInsertElement(result, result_elem, index_i32, "");
}
return result;
@@ -7002,7 +7163,7 @@ pub const FuncGen = struct {
return self.builder.buildICmp(int_pred, result, zero_vector, "");
}
- const result = self.builder.buildCall(libc_fn, &params, params.len, .C, .Auto, "");
+ const result = self.builder.buildCall(libc_fn.globalGetValueType(), libc_fn, &params, params.len, .C, .Auto, "");
return self.builder.buildICmp(int_pred, result, zero, "");
}
@@ -7130,7 +7291,7 @@ pub const FuncGen = struct {
break :b libc_fn;
},
};
- return self.builder.buildCall(llvm_fn, &params, params_len, .C, .Auto, "");
+ return self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &params, params_len, .C, .Auto, "");
}
fn airMulAdd(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
@@ -7190,12 +7351,12 @@ pub const FuncGen = struct {
const result_alignment = dest_ty.abiAlignment(target);
alloca_inst.setAlignment(result_alignment);
{
- const field_ptr = self.builder.buildStructGEP(alloca_inst, result_index, "");
+ const field_ptr = self.builder.buildStructGEP(llvm_dest_ty, alloca_inst, result_index, "");
const store_inst = self.builder.buildStore(result, field_ptr);
store_inst.setAlignment(result_alignment);
}
{
- const field_ptr = self.builder.buildStructGEP(alloca_inst, overflow_index, "");
+ const field_ptr = self.builder.buildStructGEP(llvm_dest_ty, alloca_inst, overflow_index, "");
const store_inst = self.builder.buildStore(overflow_bit, field_ptr);
store_inst.setAlignment(1);
}
@@ -7485,7 +7646,7 @@ pub const FuncGen = struct {
const index_usize = llvm_usize.constInt(i, .False);
const index_u32 = llvm_u32.constInt(i, .False);
const indexes: [2]*const llvm.Value = .{ zero, index_usize };
- const elem_ptr = self.builder.buildInBoundsGEP(array_ptr, &indexes, indexes.len, "");
+ const elem_ptr = self.builder.buildInBoundsGEP(llvm_dest_ty, array_ptr, &indexes, indexes.len, "");
const elem = self.builder.buildExtractElement(operand, index_u32, "");
_ = self.builder.buildStore(elem, elem_ptr);
}
@@ -7502,7 +7663,7 @@ pub const FuncGen = struct {
if (bitcast_ok) {
const llvm_vector_ptr_ty = llvm_vector_ty.pointerType(0);
const casted_ptr = self.builder.buildBitCast(operand, llvm_vector_ptr_ty, "");
- const vector = self.builder.buildLoad(casted_ptr, "");
+ const vector = self.builder.buildLoad(llvm_vector_ty, casted_ptr, "");
// The array is aligned to the element's alignment, while the vector might have a completely
// different alignment. This means we need to enforce the alignment of this load.
vector.setAlignment(elem_ty.abiAlignment(target));
@@ -7510,6 +7671,8 @@ pub const FuncGen = struct {
} else {
// If the ABI size of the element type is not evenly divisible by size in bits;
// a simple bitcast will not work, and we fall back to extractelement.
+ const array_llvm_ty = try self.dg.lowerType(operand_ty);
+ const elem_llvm_ty = try self.dg.lowerType(elem_ty);
const llvm_usize = try self.dg.lowerType(Type.usize);
const llvm_u32 = self.context.intType(32);
const zero = llvm_usize.constNull();
@@ -7520,8 +7683,8 @@ pub const FuncGen = struct {
const index_usize = llvm_usize.constInt(i, .False);
const index_u32 = llvm_u32.constInt(i, .False);
const indexes: [2]*const llvm.Value = .{ zero, index_usize };
- const elem_ptr = self.builder.buildInBoundsGEP(operand, &indexes, indexes.len, "");
- const elem = self.builder.buildLoad(elem_ptr, "");
+ const elem_ptr = self.builder.buildInBoundsGEP(array_llvm_ty, operand, &indexes, indexes.len, "");
+ const elem = self.builder.buildLoad(elem_llvm_ty, elem_ptr, "");
vector = self.builder.buildInsertElement(vector, elem, index_u32, "");
}
@@ -7532,7 +7695,7 @@ pub const FuncGen = struct {
if (operand_is_ref) {
// Bitcast the operand pointer, then load.
const casted_ptr = self.builder.buildBitCast(operand, llvm_dest_ty.pointerType(0), "");
- const load_inst = self.builder.buildLoad(casted_ptr, "");
+ const load_inst = self.builder.buildLoad(llvm_dest_ty, casted_ptr, "");
load_inst.setAlignment(operand_ty.abiAlignment(target));
return load_inst;
}
@@ -7560,7 +7723,7 @@ pub const FuncGen = struct {
const casted_ptr = self.builder.buildBitCast(result_ptr, operand_llvm_ty.pointerType(0), "");
const store_inst = self.builder.buildStore(operand, casted_ptr);
store_inst.setAlignment(alignment);
- const load_inst = self.builder.buildLoad(result_ptr, "");
+ const load_inst = self.builder.buildLoad(llvm_dest_ty, result_ptr, "");
load_inst.setAlignment(alignment);
return load_inst;
}
@@ -7739,7 +7902,7 @@ pub const FuncGen = struct {
fn airBreakpoint(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
_ = inst;
const llvm_fn = self.getIntrinsic("llvm.debugtrap", &.{});
- _ = self.builder.buildCall(llvm_fn, undefined, 0, .C, .Auto, "");
+ _ = self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, undefined, 0, .C, .Auto, "");
return null;
}
@@ -7756,7 +7919,7 @@ pub const FuncGen = struct {
const llvm_i32 = self.context.intType(32);
const llvm_fn = self.getIntrinsic("llvm.returnaddress", &.{});
const params = [_]*const llvm.Value{llvm_i32.constNull()};
- const ptr_val = self.builder.buildCall(llvm_fn, &params, params.len, .Fast, .Auto, "");
+ const ptr_val = self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &params, params.len, .Fast, .Auto, "");
return self.builder.buildPtrToInt(ptr_val, llvm_usize, "");
}
@@ -7764,7 +7927,7 @@ pub const FuncGen = struct {
if (self.liveness.isUnused(inst)) return null;
const llvm_i32 = self.context.intType(32);
- const llvm_fn_name = "llvm.frameaddress.p0i8";
+ const llvm_fn_name = "llvm.frameaddress.p0";
const llvm_fn = self.dg.object.llvm_module.getNamedFunction(llvm_fn_name) orelse blk: {
const llvm_p0i8 = self.context.intType(8).pointerType(0);
const param_types = [_]*const llvm.Type{llvm_i32};
@@ -7773,7 +7936,7 @@ pub const FuncGen = struct {
};
const params = [_]*const llvm.Value{llvm_i32.constNull()};
- const ptr_val = self.builder.buildCall(llvm_fn, &params, params.len, .Fast, .Auto, "");
+ const ptr_val = self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &params, params.len, .Fast, .Auto, "");
const llvm_usize = try self.dg.lowerType(Type.usize);
return self.builder.buildPtrToInt(ptr_val, llvm_usize, "");
}
@@ -7894,20 +8057,31 @@ pub const FuncGen = struct {
const atomic_load = self.air.instructions.items(.data)[inst].atomic_load;
const ptr = try self.resolveInst(atomic_load.ptr);
const ptr_ty = self.air.typeOf(atomic_load.ptr);
- if (!ptr_ty.isVolatilePtr() and self.liveness.isUnused(inst))
+ const ptr_info = ptr_ty.ptrInfo().data;
+ if (!ptr_info.@"volatile" and self.liveness.isUnused(inst))
+ return null;
+ const elem_ty = ptr_info.pointee_type;
+ if (!elem_ty.hasRuntimeBitsIgnoreComptime())
return null;
const ordering = toLlvmAtomicOrdering(atomic_load.order);
- const operand_ty = ptr_ty.elemType();
- const opt_abi_ty = self.dg.getAtomicAbiType(operand_ty, false);
+ const opt_abi_llvm_ty = self.dg.getAtomicAbiType(elem_ty, false);
+ const target = self.dg.module.getTarget();
+ const ptr_alignment = ptr_info.alignment(target);
+ const ptr_volatile = llvm.Bool.fromBool(ptr_info.@"volatile");
+ const elem_llvm_ty = try self.dg.lowerType(elem_ty);
- if (opt_abi_ty) |abi_ty| {
+ if (opt_abi_llvm_ty) |abi_llvm_ty| {
// operand needs widening and truncating
- const casted_ptr = self.builder.buildBitCast(ptr, abi_ty.pointerType(0), "");
- const load_inst = (try self.load(casted_ptr, ptr_ty)).?;
+ const casted_ptr = self.builder.buildBitCast(ptr, abi_llvm_ty.pointerType(0), "");
+ const load_inst = self.builder.buildLoad(abi_llvm_ty, casted_ptr, "");
+ load_inst.setAlignment(ptr_alignment);
+ load_inst.setVolatile(ptr_volatile);
load_inst.setOrdering(ordering);
- return self.builder.buildTrunc(load_inst, try self.dg.lowerType(operand_ty), "");
+ return self.builder.buildTrunc(load_inst, elem_llvm_ty, "");
}
- const load_inst = (try self.load(ptr, ptr_ty)).?;
+ const load_inst = self.builder.buildLoad(elem_llvm_ty, ptr, "");
+ load_inst.setAlignment(ptr_alignment);
+ load_inst.setVolatile(ptr_volatile);
load_inst.setOrdering(ordering);
return load_inst;
}
@@ -7997,8 +8171,9 @@ pub const FuncGen = struct {
_ = self.builder.buildStore(new_tag, union_ptr);
return null;
}
+ const un_llvm_ty = try self.dg.lowerType(un_ty);
const tag_index = @boolToInt(layout.tag_align < layout.payload_align);
- const tag_field_ptr = self.builder.buildStructGEP(union_ptr, tag_index, "");
+ const tag_field_ptr = self.builder.buildStructGEP(un_llvm_ty, union_ptr, tag_index, "");
// TODO alignment on this store
_ = self.builder.buildStore(new_tag, tag_field_ptr);
return null;
@@ -8014,12 +8189,13 @@ pub const FuncGen = struct {
if (layout.tag_size == 0) return null;
const union_handle = try self.resolveInst(ty_op.operand);
if (isByRef(un_ty)) {
+ const llvm_un_ty = try self.dg.lowerType(un_ty);
if (layout.payload_size == 0) {
- return self.builder.buildLoad(union_handle, "");
+ return self.builder.buildLoad(llvm_un_ty, union_handle, "");
}
const tag_index = @boolToInt(layout.tag_align < layout.payload_align);
- const tag_field_ptr = self.builder.buildStructGEP(union_handle, tag_index, "");
- return self.builder.buildLoad(tag_field_ptr, "");
+ const tag_field_ptr = self.builder.buildStructGEP(llvm_un_ty, union_handle, tag_index, "");
+ return self.builder.buildLoad(tag_field_ptr.getGEPResultElementType(), tag_field_ptr, "");
} else {
if (layout.payload_size == 0) {
return union_handle;
@@ -8062,7 +8238,7 @@ pub const FuncGen = struct {
const fn_val = self.getIntrinsic(llvm_fn_name, &.{operand_llvm_ty});
const params = [_]*const llvm.Value{ operand, llvm_i1.constNull() };
- const wrong_size_result = self.builder.buildCall(fn_val, &params, params.len, .C, .Auto, "");
+ const wrong_size_result = self.builder.buildCall(fn_val.globalGetValueType(), fn_val, &params, params.len, .C, .Auto, "");
const result_ty = self.air.typeOfIndex(inst);
const result_llvm_ty = try self.dg.lowerType(result_ty);
@@ -8089,7 +8265,7 @@ pub const FuncGen = struct {
const operand_llvm_ty = try self.dg.lowerType(operand_ty);
const fn_val = self.getIntrinsic(llvm_fn_name, &.{operand_llvm_ty});
- const wrong_size_result = self.builder.buildCall(fn_val, &params, params.len, .C, .Auto, "");
+ const wrong_size_result = self.builder.buildCall(fn_val.globalGetValueType(), fn_val, &params, params.len, .C, .Auto, "");
const result_ty = self.air.typeOfIndex(inst);
const result_llvm_ty = try self.dg.lowerType(result_ty);
@@ -8146,7 +8322,7 @@ pub const FuncGen = struct {
const params = [_]*const llvm.Value{operand};
const fn_val = self.getIntrinsic(llvm_fn_name, &.{operand_llvm_ty});
- const wrong_size_result = self.builder.buildCall(fn_val, &params, params.len, .C, .Auto, "");
+ const wrong_size_result = self.builder.buildCall(fn_val.globalGetValueType(), fn_val, &params, params.len, .C, .Auto, "");
const result_ty = self.air.typeOfIndex(inst);
const result_llvm_ty = try self.dg.lowerType(result_ty);
@@ -8216,7 +8392,7 @@ pub const FuncGen = struct {
const llvm_fn = try self.getIsNamedEnumValueFunction(enum_ty);
const params = [_]*const llvm.Value{operand};
- return self.builder.buildCall(llvm_fn, &params, params.len, .Fast, .Auto, "");
+ return self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &params, params.len, .Fast, .Auto, "");
}
fn getIsNamedEnumValueFunction(self: *FuncGen, enum_ty: Type) !*const llvm.Value {
@@ -8297,7 +8473,7 @@ pub const FuncGen = struct {
const llvm_fn = try self.getEnumTagNameFunction(enum_ty);
const params = [_]*const llvm.Value{operand};
- return self.builder.buildCall(llvm_fn, &params, params.len, .Fast, .Auto, "");
+ return self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &params, params.len, .Fast, .Auto, "");
}
fn getEnumTagNameFunction(self: *FuncGen, enum_ty: Type) !*const llvm.Value {
@@ -8358,7 +8534,8 @@ pub const FuncGen = struct {
for (fields.keys()) |name, field_index| {
const str_init = self.dg.context.constString(name.ptr, @intCast(c_uint, name.len), .False);
- const str_global = self.dg.object.llvm_module.addGlobal(str_init.typeOf(), "");
+ const str_init_llvm_ty = str_init.typeOf();
+ const str_global = self.dg.object.llvm_module.addGlobal(str_init_llvm_ty, "");
str_global.setInitializer(str_init);
str_global.setLinkage(.Private);
str_global.setGlobalConstant(.True);
@@ -8366,7 +8543,7 @@ pub const FuncGen = struct {
str_global.setAlignment(1);
const slice_fields = [_]*const llvm.Value{
- str_global.constInBoundsGEP(&array_ptr_indices, array_ptr_indices.len),
+ str_init_llvm_ty.constInBoundsGEP(str_global, &array_ptr_indices, array_ptr_indices.len),
usize_llvm_ty.constInt(name.len, .False),
};
const slice_init = llvm_ret_ty.constNamedStruct(&slice_fields, slice_fields.len);
@@ -8391,7 +8568,7 @@ pub const FuncGen = struct {
switch_instr.addCase(this_tag_int_value, return_block);
self.builder.positionBuilderAtEnd(return_block);
- const loaded = self.builder.buildLoad(slice_global, "");
+ const loaded = self.builder.buildLoad(llvm_ret_ty, slice_global, "");
loaded.setAlignment(slice_alignment);
_ = self.builder.buildRet(loaded);
}
@@ -8425,12 +8602,15 @@ pub const FuncGen = struct {
const un_op = self.air.instructions.items(.data)[inst].un_op;
const operand = try self.resolveInst(un_op);
+ const slice_ty = self.air.typeOfIndex(inst);
+ const slice_llvm_ty = try self.dg.lowerType(slice_ty);
const error_name_table_ptr = try self.getErrorNameTable();
- const error_name_table = self.builder.buildLoad(error_name_table_ptr, "");
+ const ptr_slice_llvm_ty = slice_llvm_ty.pointerType(0);
+ const error_name_table = self.builder.buildLoad(ptr_slice_llvm_ty, error_name_table_ptr, "");
const indices = [_]*const llvm.Value{operand};
- const error_name_ptr = self.builder.buildInBoundsGEP(error_name_table, &indices, indices.len, "");
- return self.builder.buildLoad(error_name_ptr, "");
+ const error_name_ptr = self.builder.buildInBoundsGEP(slice_llvm_ty, error_name_table, &indices, indices.len, "");
+ return self.builder.buildLoad(slice_llvm_ty, error_name_ptr, "");
}
fn airSplat(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
@@ -8607,7 +8787,7 @@ pub const FuncGen = struct {
const llvm_elem = try self.resolveInst(elem);
const llvm_i = llvmFieldIndex(result_ty, i, target, &ptr_ty_buf).?;
indices[1] = llvm_u32.constInt(llvm_i, .False);
- const field_ptr = self.builder.buildInBoundsGEP(alloca_inst, &indices, indices.len, "");
+ const field_ptr = self.builder.buildInBoundsGEP(llvm_result_ty, alloca_inst, &indices, indices.len, "");
var field_ptr_payload: Type.Payload.Pointer = .{
.data = .{
.pointee_type = self.air.typeOf(elem),
@@ -8653,7 +8833,7 @@ pub const FuncGen = struct {
llvm_usize.constNull(),
llvm_usize.constInt(@intCast(c_uint, i), .False),
};
- const elem_ptr = self.builder.buildInBoundsGEP(alloca_inst, &indices, indices.len, "");
+ const elem_ptr = self.builder.buildInBoundsGEP(llvm_result_ty, alloca_inst, &indices, indices.len, "");
const llvm_elem = try self.resolveInst(elem);
self.store(elem_ptr, elem_ptr_ty, llvm_elem, .NotAtomic);
}
@@ -8662,7 +8842,7 @@ pub const FuncGen = struct {
llvm_usize.constNull(),
llvm_usize.constInt(@intCast(c_uint, array_info.len), .False),
};
- const elem_ptr = self.builder.buildInBoundsGEP(alloca_inst, &indices, indices.len, "");
+ const elem_ptr = self.builder.buildInBoundsGEP(llvm_result_ty, alloca_inst, &indices, indices.len, "");
const llvm_elem = try self.dg.lowerValue(.{
.ty = array_info.elem_type,
.val = sent_val,
@@ -8775,7 +8955,7 @@ pub const FuncGen = struct {
index_type.constNull(),
};
const len: c_uint = if (field_size == layout.payload_size) 2 else 3;
- const field_ptr = self.builder.buildInBoundsGEP(casted_ptr, &indices, len, "");
+ const field_ptr = self.builder.buildInBoundsGEP(llvm_union_ty, casted_ptr, &indices, len, "");
self.store(field_ptr, field_ptr_ty, llvm_payload, .NotAtomic);
return result_ptr;
}
@@ -8787,7 +8967,7 @@ pub const FuncGen = struct {
index_type.constNull(),
};
const len: c_uint = if (field_size == layout.payload_size) 2 else 3;
- const field_ptr = self.builder.buildInBoundsGEP(casted_ptr, &indices, len, "");
+ const field_ptr = self.builder.buildInBoundsGEP(llvm_union_ty, casted_ptr, &indices, len, "");
self.store(field_ptr, field_ptr_ty, llvm_payload, .NotAtomic);
}
{
@@ -8795,7 +8975,7 @@ pub const FuncGen = struct {
index_type.constNull(),
index_type.constInt(@boolToInt(layout.tag_align < layout.payload_align), .False),
};
- const field_ptr = self.builder.buildInBoundsGEP(casted_ptr, &indices, indices.len, "");
+ const field_ptr = self.builder.buildInBoundsGEP(llvm_union_ty, casted_ptr, &indices, indices.len, "");
const tag_llvm_ty = try self.dg.lowerType(union_obj.tag_ty);
const llvm_tag = tag_llvm_ty.constInt(tag_int, .False);
const store_inst = self.builder.buildStore(llvm_tag, field_ptr);
@@ -8842,7 +9022,7 @@ pub const FuncGen = struct {
const llvm_ptr_u8 = llvm_u8.pointerType(0);
const llvm_u32 = self.context.intType(32);
- const llvm_fn_name = "llvm.prefetch.p0i8";
+ const llvm_fn_name = "llvm.prefetch.p0";
const fn_val = self.dg.object.llvm_module.getNamedFunction(llvm_fn_name) orelse blk: {
// declare void @llvm.prefetch(i8*, i32, i32, i32)
const llvm_void = self.context.voidType();
@@ -8862,7 +9042,7 @@ pub const FuncGen = struct {
llvm_u32.constInt(prefetch.locality, .False),
llvm_u32.constInt(@enumToInt(prefetch.cache), .False),
};
- _ = self.builder.buildCall(fn_val, &params, params.len, .C, .Auto, "");
+ _ = self.builder.buildCall(fn_val.globalGetValueType(), fn_val, &params, params.len, .C, .Auto, "");
return null;
}
@@ -8942,7 +9122,7 @@ pub const FuncGen = struct {
};
var args: [1]*const llvm.Value = .{arg};
- const result = self.builder.buildCall(llvm_fn, &args, args.len, .C, .Auto, "");
+ const result = self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &args, args.len, .C, .Auto, "");
const final_cast_llvm_ty = final_cast orelse return result;
return self.builder.buildBitCast(result, final_cast_llvm_ty, "");
}
@@ -8969,38 +9149,46 @@ pub const FuncGen = struct {
}
/// Assumes the optional is not pointer-like and payload has bits.
- fn optIsNonNull(self: *FuncGen, opt_handle: *const llvm.Value, is_by_ref: bool) *const llvm.Value {
+ fn optIsNonNull(
+ self: *FuncGen,
+ opt_llvm_ty: *const llvm.Type,
+ opt_handle: *const llvm.Value,
+ is_by_ref: bool,
+ ) *const llvm.Value {
+ const non_null_llvm_ty = self.context.intType(8);
const field = b: {
if (is_by_ref) {
- const field_ptr = self.builder.buildStructGEP(opt_handle, 1, "");
- break :b self.builder.buildLoad(field_ptr, "");
+ const field_ptr = self.builder.buildStructGEP(opt_llvm_ty, opt_handle, 1, "");
+ break :b self.builder.buildLoad(non_null_llvm_ty, field_ptr, "");
}
break :b self.builder.buildExtractValue(opt_handle, 1, "");
};
comptime assert(optional_layout_version == 3);
- return self.builder.buildICmp(.NE, field, self.context.intType(8).constInt(0, .False), "");
+ return self.builder.buildICmp(.NE, field, non_null_llvm_ty.constInt(0, .False), "");
}
/// Assumes the optional is not pointer-like and payload has bits.
fn optPayloadHandle(
fg: *FuncGen,
+ opt_llvm_ty: *const llvm.Type,
opt_handle: *const llvm.Value,
opt_ty: Type,
- ) *const llvm.Value {
+ ) !*const llvm.Value {
var buf: Type.Payload.ElemType = undefined;
const payload_ty = opt_ty.optionalChild(&buf);
if (isByRef(opt_ty)) {
// We have a pointer and we need to return a pointer to the first field.
- const payload_ptr = fg.builder.buildStructGEP(opt_handle, 0, "");
+ const payload_ptr = fg.builder.buildStructGEP(opt_llvm_ty, opt_handle, 0, "");
if (isByRef(payload_ty)) {
return payload_ptr;
}
const target = fg.dg.module.getTarget();
const payload_alignment = payload_ty.abiAlignment(target);
- const load_inst = fg.builder.buildLoad(payload_ptr, "");
+ const payload_llvm_ty = try fg.dg.lowerType(payload_ty);
+ const load_inst = fg.builder.buildLoad(payload_llvm_ty, payload_ptr, "");
load_inst.setAlignment(payload_alignment);
return load_inst;
}
@@ -9025,12 +9213,12 @@ pub const FuncGen = struct {
alloca_inst.setAlignment(payload_alignment);
{
- const field_ptr = self.builder.buildStructGEP(alloca_inst, 0, "");
+ const field_ptr = self.builder.buildStructGEP(optional_llvm_ty, alloca_inst, 0, "");
const store_inst = self.builder.buildStore(payload, field_ptr);
store_inst.setAlignment(payload_alignment);
}
{
- const field_ptr = self.builder.buildStructGEP(alloca_inst, 1, "");
+ const field_ptr = self.builder.buildStructGEP(optional_llvm_ty, alloca_inst, 1, "");
const store_inst = self.builder.buildStore(non_null_field, field_ptr);
store_inst.setAlignment(1);
}
@@ -9076,18 +9264,20 @@ pub const FuncGen = struct {
if (byte_offset == 0) {
return self.builder.buildBitCast(struct_ptr, result_llvm_ty, "");
}
- const llvm_bytes_ptr_ty = self.context.intType(8).pointerType(0);
- const ptr_as_bytes = self.builder.buildBitCast(struct_ptr, llvm_bytes_ptr_ty, "");
+ const byte_llvm_ty = self.context.intType(8);
+ const ptr_as_bytes = self.builder.buildBitCast(struct_ptr, byte_llvm_ty.pointerType(0), "");
const llvm_usize = try self.dg.lowerType(Type.usize);
const llvm_index = llvm_usize.constInt(byte_offset, .False);
const indices: [1]*const llvm.Value = .{llvm_index};
- const new_ptr = self.builder.buildInBoundsGEP(ptr_as_bytes, &indices, indices.len, "");
+ const new_ptr = self.builder.buildInBoundsGEP(byte_llvm_ty, ptr_as_bytes, &indices, indices.len, "");
return self.builder.buildBitCast(new_ptr, result_llvm_ty, "");
},
else => {
+ const struct_llvm_ty = try self.dg.lowerPtrElemTy(struct_ty);
+
var ty_buf: Type.Payload.Pointer = undefined;
if (llvmFieldIndex(struct_ty, field_index, target, &ty_buf)) |llvm_field_index| {
- return self.builder.buildStructGEP(struct_ptr, llvm_field_index, "");
+ return self.builder.buildStructGEP(struct_llvm_ty, struct_ptr, llvm_field_index, "");
} else {
// If we found no index then this means this is a zero sized field at the
// end of the struct. Treat our struct pointer as an array of two and get
@@ -9096,7 +9286,7 @@ pub const FuncGen = struct {
const llvm_usize = try self.dg.lowerType(Type.usize);
const llvm_index = llvm_usize.constInt(1, .False);
const indices: [1]*const llvm.Value = .{llvm_index};
- return self.builder.buildInBoundsGEP(struct_ptr, &indices, indices.len, "");
+ return self.builder.buildInBoundsGEP(struct_llvm_ty, struct_ptr, &indices, indices.len, "");
}
},
},
@@ -9111,27 +9301,18 @@ pub const FuncGen = struct {
union_ptr: *const llvm.Value,
union_ty: Type,
) !?*const llvm.Value {
- const result_llvm_ty = try self.dg.lowerType(self.air.typeOfIndex(inst));
const target = self.dg.module.getTarget();
const layout = union_ty.unionGetLayout(target);
+ const result_llvm_ty = try self.dg.lowerType(self.air.typeOfIndex(inst));
if (layout.payload_size == 0) {
return self.builder.buildBitCast(union_ptr, result_llvm_ty, "");
}
const payload_index = @boolToInt(layout.tag_align >= layout.payload_align);
- const union_field_ptr = self.builder.buildStructGEP(union_ptr, payload_index, "");
+ const union_llvm_ty = try self.dg.lowerType(union_ty);
+ const union_field_ptr = self.builder.buildStructGEP(union_llvm_ty, union_ptr, payload_index, "");
return self.builder.buildBitCast(union_field_ptr, result_llvm_ty, "");
}
- fn sliceElemPtr(
- self: *FuncGen,
- slice: *const llvm.Value,
- index: *const llvm.Value,
- ) *const llvm.Value {
- const base_ptr = self.builder.buildExtractValue(slice, 0, "");
- const indices: [1]*const llvm.Value = .{index};
- return self.builder.buildInBoundsGEP(base_ptr, &indices, indices.len, "");
- }
-
fn getIntrinsic(self: *FuncGen, name: []const u8, types: []const *const llvm.Type) *const llvm.Value {
const id = llvm.lookupIntrinsicID(name.ptr, name.len);
assert(id != 0);
@@ -9146,11 +9327,11 @@ pub const FuncGen = struct {
if (!info.pointee_type.hasRuntimeBitsIgnoreComptime()) return null;
const target = self.dg.module.getTarget();
- const ptr_alignment = ptr_ty.ptrAlignment(target);
+ const ptr_alignment = info.alignment(target);
const ptr_volatile = llvm.Bool.fromBool(ptr_ty.isVolatilePtr());
if (info.host_size == 0) {
+ const elem_llvm_ty = try self.dg.lowerType(info.pointee_type);
if (isByRef(info.pointee_type)) {
- const elem_llvm_ty = try self.dg.lowerType(info.pointee_type);
const result_align = info.pointee_type.abiAlignment(target);
const max_align = @maximum(result_align, ptr_alignment);
const result_ptr = self.buildAlloca(elem_llvm_ty);
@@ -9168,15 +9349,15 @@ pub const FuncGen = struct {
);
return result_ptr;
}
- const llvm_inst = self.builder.buildLoad(ptr, "");
+ const llvm_inst = self.builder.buildLoad(elem_llvm_ty, ptr, "");
llvm_inst.setAlignment(ptr_alignment);
llvm_inst.setVolatile(ptr_volatile);
return llvm_inst;
}
- const int_ptr_ty = self.context.intType(info.host_size * 8).pointerType(0);
- const int_ptr = self.builder.buildBitCast(ptr, int_ptr_ty, "");
- const containing_int = self.builder.buildLoad(int_ptr, "");
+ const int_elem_ty = self.context.intType(info.host_size * 8);
+ const int_ptr = self.builder.buildBitCast(ptr, int_elem_ty.pointerType(0), "");
+ const containing_int = self.builder.buildLoad(int_elem_ty, int_ptr, "");
containing_int.setAlignment(ptr_alignment);
containing_int.setVolatile(ptr_volatile);
@@ -9229,9 +9410,9 @@ pub const FuncGen = struct {
const ptr_alignment = ptr_ty.ptrAlignment(target);
const ptr_volatile = llvm.Bool.fromBool(info.@"volatile");
if (info.host_size != 0) {
- const int_ptr_ty = self.context.intType(info.host_size * 8).pointerType(0);
- const int_ptr = self.builder.buildBitCast(ptr, int_ptr_ty, "");
- const containing_int = self.builder.buildLoad(int_ptr, "");
+ const int_elem_ty = self.context.intType(info.host_size * 8);
+ const int_ptr = self.builder.buildBitCast(ptr, int_elem_ty.pointerType(0), "");
+ const containing_int = self.builder.buildLoad(int_elem_ty, int_ptr, "");
assert(ordering == .NotAtomic);
containing_int.setAlignment(ptr_alignment);
containing_int.setVolatile(ptr_volatile);
@@ -9310,8 +9491,9 @@ pub const FuncGen = struct {
switch (target.cpu.arch) {
.x86_64 => {
+ const array_llvm_ty = usize_llvm_ty.arrayType(6);
const array_ptr = fg.valgrind_client_request_array orelse a: {
- const array_ptr = fg.buildAlloca(usize_llvm_ty.arrayType(6));
+ const array_ptr = fg.buildAlloca(array_llvm_ty);
array_ptr.setAlignment(usize_alignment);
fg.valgrind_client_request_array = array_ptr;
break :a array_ptr;
@@ -9322,7 +9504,7 @@ pub const FuncGen = struct {
const indexes = [_]*const llvm.Value{
zero, usize_llvm_ty.constInt(@intCast(c_uint, i), .False),
};
- const elem_ptr = fg.builder.buildInBoundsGEP(array_ptr, &indexes, indexes.len, "");
+ const elem_ptr = fg.builder.buildInBoundsGEP(array_llvm_ty, array_ptr, &indexes, indexes.len, "");
const store_inst = fg.builder.buildStore(elem, elem_ptr);
store_inst.setAlignment(usize_alignment);
}
@@ -9352,6 +9534,7 @@ pub const FuncGen = struct {
);
const call = fg.builder.buildCall(
+ fn_llvm_ty,
asm_fn,
&args,
args.len,
@@ -9538,6 +9721,9 @@ fn initializeLLVMTarget(arch: std.Target.Cpu.Arch) void {
.kalimba,
.renderscript32,
.renderscript64,
+ .dxil,
+ .loongarch32,
+ .loongarch64,
=> {},
.spu_2 => unreachable, // LLVM does not support this backend
diff --git a/src/codegen/llvm/bindings.zig b/src/codegen/llvm/bindings.zig
index 38f794cfda..81e722bed8 100644
--- a/src/codegen/llvm/bindings.zig
+++ b/src/codegen/llvm/bindings.zig
@@ -31,6 +31,9 @@ pub const Context = opaque {
pub const createStringAttribute = LLVMCreateStringAttribute;
extern fn LLVMCreateStringAttribute(*const Context, Key: [*]const u8, Key_Len: c_uint, Value: [*]const u8, Value_Len: c_uint) *const Attribute;
+ pub const pointerType = LLVMPointerTypeInContext;
+ extern fn LLVMPointerTypeInContext(C: *const Context, AddressSpace: c_uint) *const Type;
+
pub const intType = LLVMIntTypeInContext;
extern fn LLVMIntTypeInContext(C: *const Context, NumBits: c_uint) *const Type;
@@ -141,13 +144,6 @@ pub const Value = opaque {
pub const setAliasee = LLVMAliasSetAliasee;
extern fn LLVMAliasSetAliasee(Alias: *const Value, Aliasee: *const Value) void;
- pub const constInBoundsGEP = LLVMConstInBoundsGEP;
- extern fn LLVMConstInBoundsGEP(
- ConstantVal: *const Value,
- ConstantIndices: [*]const *const Value,
- NumIndices: c_uint,
- ) *const Value;
-
pub const constBitCast = LLVMConstBitCast;
extern fn LLVMConstBitCast(ConstantVal: *const Value, ToType: *const Type) *const Value;
@@ -252,6 +248,9 @@ pub const Value = opaque {
pub const addFunctionAttr = ZigLLVMAddFunctionAttr;
extern fn ZigLLVMAddFunctionAttr(Fn: *const Value, attr_name: [*:0]const u8, attr_value: [*:0]const u8) void;
+ pub const getGEPResultElementType = ZigLLVMGetGEPResultElementType;
+ extern fn ZigLLVMGetGEPResultElementType(GEP: *const Value) *const Type;
+
pub const addByValAttr = ZigLLVMAddByValAttr;
extern fn ZigLLVMAddByValAttr(Fn: *const Value, ArgNo: c_uint, type: *const Type) void;
};
@@ -319,6 +318,14 @@ pub const Type = opaque {
pub const isSized = LLVMTypeIsSized;
extern fn LLVMTypeIsSized(Ty: *const Type) Bool;
+
+ pub const constInBoundsGEP = LLVMConstInBoundsGEP2;
+ extern fn LLVMConstInBoundsGEP2(
+ Ty: *const Type,
+ ConstantVal: *const Value,
+ ConstantIndices: [*]const *const Value,
+ NumIndices: c_uint,
+ ) *const Value;
};
pub const Module = opaque {
@@ -515,6 +522,7 @@ pub const Builder = opaque {
pub const buildCall = ZigLLVMBuildCall;
extern fn ZigLLVMBuildCall(
*const Builder,
+ *const Type,
Fn: *const Value,
Args: [*]const *const Value,
NumArgs: c_uint,
@@ -538,8 +546,8 @@ pub const Builder = opaque {
pub const buildStore = LLVMBuildStore;
extern fn LLVMBuildStore(*const Builder, Val: *const Value, Ptr: *const Value) *const Value;
- pub const buildLoad = LLVMBuildLoad;
- extern fn LLVMBuildLoad(*const Builder, PointerVal: *const Value, Name: [*:0]const u8) *const Value;
+ pub const buildLoad = LLVMBuildLoad2;
+ extern fn LLVMBuildLoad2(*const Builder, Ty: *const Type, PointerVal: *const Value, Name: [*:0]const u8) *const Value;
pub const buildNeg = LLVMBuildNeg;
extern fn LLVMBuildNeg(*const Builder, V: *const Value, Name: [*:0]const u8) *const Value;
@@ -664,16 +672,7 @@ pub const Builder = opaque {
pub const buildBitCast = LLVMBuildBitCast;
extern fn LLVMBuildBitCast(*const Builder, Val: *const Value, DestTy: *const Type, Name: [*:0]const u8) *const Value;
- pub const buildInBoundsGEP = LLVMBuildInBoundsGEP;
- extern fn LLVMBuildInBoundsGEP(
- B: *const Builder,
- Pointer: *const Value,
- Indices: [*]const *const Value,
- NumIndices: c_uint,
- Name: [*:0]const u8,
- ) *const Value;
-
- pub const buildInBoundsGEP2 = LLVMBuildInBoundsGEP2;
+ pub const buildInBoundsGEP = LLVMBuildInBoundsGEP2;
extern fn LLVMBuildInBoundsGEP2(
B: *const Builder,
Ty: *const Type,
@@ -750,9 +749,10 @@ pub const Builder = opaque {
Name: [*:0]const u8,
) *const Value;
- pub const buildStructGEP = LLVMBuildStructGEP;
- extern fn LLVMBuildStructGEP(
+ pub const buildStructGEP = LLVMBuildStructGEP2;
+ extern fn LLVMBuildStructGEP2(
B: *const Builder,
+ Ty: *const Type,
Pointer: *const Value,
Idx: c_uint,
Name: [*:0]const u8,
@@ -1221,9 +1221,11 @@ pub const LinkWasm = ZigLLDLinkWasm;
pub const ObjectFormatType = enum(c_int) {
Unknown,
COFF,
+ DXContainer,
ELF,
GOFF,
MachO,
+ SPIRV,
Wasm,
XCOFF,
};
@@ -1263,9 +1265,11 @@ pub const OSType = enum(c_int) {
NVCL,
AMDHSA,
PS4,
+ PS5,
ELFIAMCU,
TvOS,
WatchOS,
+ DriverKit,
Mesa3D,
Contiki,
AMDPAL,
@@ -1273,6 +1277,7 @@ pub const OSType = enum(c_int) {
Hurd,
WASI,
Emscripten,
+ ShaderModel,
};
pub const ArchType = enum(c_int) {
@@ -1287,7 +1292,10 @@ pub const ArchType = enum(c_int) {
bpfel,
bpfeb,
csky,
+ dxil,
hexagon,
+ loongarch32,
+ loongarch64,
m68k,
mips,
mipsel,
@@ -1323,6 +1331,8 @@ pub const ArchType = enum(c_int) {
hsail64,
spir,
spir64,
+ spirv32,
+ spirv64,
kalimba,
shave,
lanai,
@@ -1724,8 +1734,8 @@ pub const DIBuilder = opaque {
dib: *DIBuilder,
tag: c_uint,
name: [*:0]const u8,
- scope: *DIScope,
- file: *DIFile,
+ scope: ?*DIScope,
+ file: ?*DIFile,
line: c_uint,
) *DIType;
diff --git a/src/libcxx.zig b/src/libcxx.zig
index b19834f8c3..b0261aaed6 100644
--- a/src/libcxx.zig
+++ b/src/libcxx.zig
@@ -7,6 +7,13 @@ const Compilation = @import("Compilation.zig");
const build_options = @import("build_options");
const trace = @import("tracy.zig").trace;
+pub const AbiVersion = enum(u2) {
+ @"1" = 1,
+ @"2" = 2,
+
+ pub const default: AbiVersion = .@"1";
+};
+
const libcxxabi_files = [_][]const u8{
"src/abort_message.cpp",
"src/cxa_aux_runtime.cpp",
@@ -54,6 +61,7 @@ const libcxx_files = [_][]const u8{
"src/ios.cpp",
"src/ios.instantiations.cpp",
"src/iostream.cpp",
+ "src/legacy_debug_handler.cpp",
"src/legacy_pointer_safety.cpp",
"src/locale.cpp",
"src/memory.cpp",
@@ -85,6 +93,7 @@ const libcxx_files = [_][]const u8{
"src/valarray.cpp",
"src/variant.cpp",
"src/vector.cpp",
+ "src/verbose_abort.cpp",
};
pub fn buildLibCXX(comp: *Compilation) !void {
@@ -118,6 +127,12 @@ pub fn buildLibCXX(comp: *Compilation) !void {
const cxxabi_include_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libcxxabi", "include" });
const cxx_include_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libcxx", "include" });
const cxx_src_include_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libcxx", "src" });
+ const abi_version_arg = try std.fmt.allocPrint(arena, "-D_LIBCPP_ABI_VERSION={d}", .{
+ @enumToInt(comp.libcxx_abi_version),
+ });
+ const abi_namespace_arg = try std.fmt.allocPrint(arena, "-D_LIBCPP_ABI_NAMESPACE=__{d}", .{
+ @enumToInt(comp.libcxx_abi_version),
+ });
var c_source_files = try std.ArrayList(Compilation.CSourceFile).initCapacity(arena, libcxx_files.len);
for (libcxx_files) |cxx_src| {
@@ -150,6 +165,10 @@ pub fn buildLibCXX(comp: *Compilation) !void {
try cflags.append("-D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS");
try cflags.append("-D_LIBCPP_DISABLE_NEW_DELETE_DEFINITIONS");
try cflags.append("-D_LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS");
+
+ try cflags.append(abi_version_arg);
+ try cflags.append(abi_namespace_arg);
+
try cflags.append("-fvisibility=hidden");
try cflags.append("-fvisibility-inlines-hidden");
@@ -275,6 +294,12 @@ pub fn buildLibCXXABI(comp: *Compilation) !void {
const cxxabi_include_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libcxxabi", "include" });
const cxx_include_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libcxx", "include" });
const cxx_src_include_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libcxx", "src" });
+ const abi_version_arg = try std.fmt.allocPrint(arena, "-D_LIBCPP_ABI_VERSION={d}", .{
+ @enumToInt(comp.libcxx_abi_version),
+ });
+ const abi_namespace_arg = try std.fmt.allocPrint(arena, "-D_LIBCPP_ABI_NAMESPACE=__{d}", .{
+ @enumToInt(comp.libcxx_abi_version),
+ });
var c_source_files = try std.ArrayList(Compilation.CSourceFile).initCapacity(arena, libcxxabi_files.len);
for (libcxxabi_files) |cxxabi_src| {
@@ -304,6 +329,10 @@ pub fn buildLibCXXABI(comp: *Compilation) !void {
try cflags.append("-D_LIBCXXABI_BUILDING_LIBRARY");
try cflags.append("-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS");
try cflags.append("-D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS");
+
+ try cflags.append(abi_version_arg);
+ try cflags.append(abi_namespace_arg);
+
try cflags.append("-fvisibility=hidden");
try cflags.append("-fvisibility-inlines-hidden");
@@ -326,7 +355,7 @@ pub fn buildLibCXXABI(comp: *Compilation) !void {
try cflags.append("-nostdinc++");
try cflags.append("-fstrict-aliasing");
try cflags.append("-funwind-tables");
- try cflags.append("-std=c++11");
+ try cflags.append("-std=c++20");
c_source_files.appendAssumeCapacity(.{
.src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libcxxabi", cxxabi_src }),
diff --git a/src/libunwind.zig b/src/libunwind.zig
index fb4f93af02..11666eec3c 100644
--- a/src/libunwind.zig
+++ b/src/libunwind.zig
@@ -33,24 +33,13 @@ pub fn buildStaticLib(comp: *Compilation) !void {
.directory = null, // Put it in the cache directory.
.basename = basename,
};
- const unwind_src_list = [_][]const u8{
- "libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "libunwind.cpp",
- "libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "Unwind-EHABI.cpp",
- "libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "Unwind-seh.cpp",
- "libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "UnwindLevel1.c",
- "libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "UnwindLevel1-gcc-ext.c",
- "libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "Unwind-sjlj.c",
- "libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "UnwindRegistersRestore.S",
- "libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "UnwindRegistersSave.S",
- "libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "gcc_personality_v0.c",
- };
var c_source_files: [unwind_src_list.len]Compilation.CSourceFile = undefined;
for (unwind_src_list) |unwind_src, i| {
var cflags = std.ArrayList([]const u8).init(arena);
switch (Compilation.classifyFileExt(unwind_src)) {
.c => {
- try cflags.append("-std=c99");
+ try cflags.append("-std=c11");
},
.cpp => {
try cflags.appendSlice(&[_][]const u8{
@@ -120,7 +109,8 @@ pub fn buildStaticLib(comp: *Compilation) !void {
.want_tsan = false,
.want_pic = comp.bin_file.options.pic,
.want_pie = comp.bin_file.options.pie,
- .want_lto = comp.bin_file.options.lto,
+ // Disable LTO to avoid https://github.com/llvm/llvm-project/issues/56825
+ .want_lto = false,
.function_sections = comp.bin_file.options.function_sections,
.emit_h = null,
.strip = comp.compilerRtStrip(),
@@ -151,3 +141,16 @@ pub fn buildStaticLib(comp: *Compilation) !void {
.lock = sub_compilation.bin_file.toOwnedLock(),
};
}
+
+const unwind_src_list = [_][]const u8{
+ "libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "libunwind.cpp",
+ "libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "Unwind-EHABI.cpp",
+ "libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "Unwind-seh.cpp",
+ "libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "UnwindLevel1.c",
+ "libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "UnwindLevel1-gcc-ext.c",
+ "libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "Unwind-sjlj.c",
+ "libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "UnwindRegistersRestore.S",
+ "libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "UnwindRegistersSave.S",
+ "libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "Unwind_AIXExtras.cpp",
+ "libunwind" ++ path.sep_str ++ "src" ++ path.sep_str ++ "gcc_personality_v0.c",
+};
diff --git a/src/link.zig b/src/link.zig
index 5d20e98a32..fe7891a439 100644
--- a/src/link.zig
+++ b/src/link.zig
@@ -301,6 +301,7 @@ pub const File = struct {
.nvptx => &(try NvPtx.createEmpty(allocator, options)).base,
.hex => return error.HexObjectFormatUnimplemented,
.raw => return error.RawObjectFormatUnimplemented,
+ .dxcontainer => return error.DirectXContainerObjectFormatUnimplemented,
};
}
const emit = options.emit.?;
@@ -320,6 +321,7 @@ pub const File = struct {
.nvptx => &(try NvPtx.createEmpty(allocator, options)).base,
.hex => return error.HexObjectFormatUnimplemented,
.raw => return error.RawObjectFormatUnimplemented,
+ .dxcontainer => return error.DirectXContainerObjectFormatUnimplemented,
};
}
// Open a temporary object file, not the final output file because we
@@ -341,6 +343,7 @@ pub const File = struct {
.nvptx => &(try NvPtx.openPath(allocator, sub_path, options)).base,
.hex => return error.HexObjectFormatUnimplemented,
.raw => return error.RawObjectFormatUnimplemented,
+ .dxcontainer => return error.DirectXContainerObjectFormatUnimplemented,
};
if (use_lld) {
diff --git a/src/link/Elf.zig b/src/link/Elf.zig
index 1d49198937..a70473fe07 100644
--- a/src/link/Elf.zig
+++ b/src/link/Elf.zig
@@ -1427,7 +1427,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v
try argv.append("-r");
}
- try argv.append("-error-limit=0");
+ try argv.append("--error-limit=0");
if (self.base.options.sysroot) |sysroot| {
try argv.append(try std.fmt.allocPrint(arena, "--sysroot={s}", .{sysroot}));
diff --git a/src/link/Wasm.zig b/src/link/Wasm.zig
index 6dd3bc56ff..0e6fe5dcc2 100644
--- a/src/link/Wasm.zig
+++ b/src/link/Wasm.zig
@@ -2927,7 +2927,7 @@ fn linkWithLLD(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) !
// This is necessary because LLD does not behave properly as a library -
// it calls exit() and does not reset all global data between invocations.
try argv.appendSlice(&[_][]const u8{ comp.self_exe_path.?, "wasm-ld" });
- try argv.append("-error-limit=0");
+ try argv.append("--error-limit=0");
if (wasm.base.options.lto) {
switch (wasm.base.options.optimize_mode) {
diff --git a/src/stage1/all_types.hpp b/src/stage1/all_types.hpp
index 9f9a6151b8..5f216fe388 100644
--- a/src/stage1/all_types.hpp
+++ b/src/stage1/all_types.hpp
@@ -1595,6 +1595,7 @@ struct ZigTypeFnFrame {
struct ZigTypeAnyFrame {
ZigType *result_type; // null if `anyframe` instead of `anyframe->T`
+ LLVMTypeRef struct_llvm_ty;
};
struct ZigType {
@@ -2044,6 +2045,7 @@ struct CodeGen {
LLVMValueRef wasm_memory_grow;
LLVMValueRef prefetch;
LLVMTypeRef anyframe_fn_type;
+ LLVMTypeRef any_frame_header_llvm_ty;
// reminder: hash tables must be initialized before use
HashMap<Buf *, ZigType *, buf_hash, buf_eql_buf> import_table;
diff --git a/src/stage1/analyze.cpp b/src/stage1/analyze.cpp
index 90173f384e..f0cad841be 100644
--- a/src/stage1/analyze.cpp
+++ b/src/stage1/analyze.cpp
@@ -9753,6 +9753,7 @@ static void resolve_llvm_types_any_frame(CodeGen *g, ZigType *any_frame_type, Re
Buf *name = buf_sprintf("(%s header)", buf_ptr(&any_frame_type->name));
LLVMTypeRef frame_header_type = LLVMStructCreateNamed(LLVMGetGlobalContext(), buf_ptr(name));
any_frame_type->llvm_type = LLVMPointerType(frame_header_type, 0);
+ any_frame_type->data.any_frame.struct_llvm_ty = frame_header_type;
unsigned dwarf_kind = ZigLLVMTag_DW_structure_type();
ZigLLVMDIFile *di_file = nullptr;
@@ -9775,7 +9776,8 @@ static void resolve_llvm_types_any_frame(CodeGen *g, ZigType *any_frame_type, Re
const unsigned fn_addrspace = ZigLLVMDataLayoutGetProgramAddressSpace(g->target_data_ref);
LLVMTypeRef ptr_fn_llvm_type = LLVMPointerType(fn_type, fn_addrspace);
if (result_type == nullptr) {
- g->anyframe_fn_type = ptr_fn_llvm_type;
+ g->any_frame_header_llvm_ty = frame_header_type;
+ g->anyframe_fn_type = fn_type;
}
ZigList<LLVMTypeRef> field_types = {};
diff --git a/src/stage1/codegen.cpp b/src/stage1/codegen.cpp
index cc6c0f22a7..55aa73a3b7 100644
--- a/src/stage1/codegen.cpp
+++ b/src/stage1/codegen.cpp
@@ -88,8 +88,8 @@ static bool value_is_all_undef(CodeGen *g, ZigValue *const_val);
static void gen_undef_init(CodeGen *g, ZigType *ptr_type, ZigType *value_type, LLVMValueRef ptr);
static LLVMValueRef build_alloca(CodeGen *g, ZigType *type_entry, const char *name, uint32_t alignment);
static LLVMValueRef gen_await_early_return(CodeGen *g, Stage1AirInst *source_instr,
- LLVMValueRef target_frame_ptr, ZigType *result_type, ZigType *ptr_result_type,
- LLVMValueRef result_loc, bool non_async);
+ LLVMTypeRef target_frame_struct_llvm_ty, LLVMValueRef target_frame_ptr,
+ ZigType *result_type, ZigType *ptr_result_type, LLVMValueRef result_loc, bool non_async);
static void addLLVMAttr(LLVMValueRef val, LLVMAttributeIndex attr_index, const char *attr_name) {
unsigned kind_id = LLVMGetEnumAttributeKindForName(attr_name, strlen(attr_name));
@@ -223,7 +223,7 @@ static ZigLLVM_CallingConv get_llvm_cc(CodeGen *g, CallingConvention cc) {
static void add_uwtable_attr(CodeGen *g, LLVMValueRef fn_val) {
if (g->unwind_tables) {
- addLLVMFnAttr(fn_val, "uwtable");
+ addLLVMFnAttrStr(fn_val, "uwtable", "sync");
}
}
@@ -911,14 +911,12 @@ static LLVMValueRef gen_store(CodeGen *g, LLVMValueRef value, LLVMValueRef ptr,
return gen_store_untyped(g, value, ptr, alignment, ptr_type->data.pointer.is_volatile);
}
-static LLVMValueRef gen_load_untyped(CodeGen *g, LLVMValueRef ptr, uint32_t alignment, bool is_volatile,
- const char *name)
+static LLVMValueRef gen_load_untyped(CodeGen *g, LLVMTypeRef elem_llvm_ty, LLVMValueRef ptr,
+ uint32_t alignment, bool is_volatile, const char *name)
{
- LLVMValueRef result = LLVMBuildLoad(g->builder, ptr, name);
+ LLVMValueRef result = LLVMBuildLoad2(g->builder, elem_llvm_ty, ptr, name);
if (is_volatile) LLVMSetVolatile(result, true);
- if (alignment == 0) {
- LLVMSetAlignment(result, LLVMABIAlignmentOfType(g->target_data_ref, LLVMGetElementType(LLVMTypeOf(ptr))));
- } else {
+ if (alignment != 0) {
LLVMSetAlignment(result, alignment);
}
return result;
@@ -927,7 +925,9 @@ static LLVMValueRef gen_load_untyped(CodeGen *g, LLVMValueRef ptr, uint32_t alig
static LLVMValueRef gen_load(CodeGen *g, LLVMValueRef ptr, ZigType *ptr_type, const char *name) {
assert(ptr_type->id == ZigTypeIdPointer);
uint32_t alignment = get_ptr_align(g, ptr_type);
- return gen_load_untyped(g, ptr, alignment, ptr_type->data.pointer.is_volatile, name);
+ LLVMTypeRef elem_llvm_ty = get_llvm_type(g, ptr_type->data.pointer.child_type);
+ bool is_volatile = ptr_type->data.pointer.is_volatile;
+ return gen_load_untyped(g, elem_llvm_ty, ptr, alignment, is_volatile, name);
}
static LLVMValueRef get_handle_value(CodeGen *g, LLVMValueRef ptr, ZigType *type, ZigType *ptr_type) {
@@ -1090,7 +1090,7 @@ static void gen_panic(CodeGen *g, LLVMValueRef msg_arg, LLVMValueRef stack_trace
msg_arg,
stack_trace_arg,
};
- ZigLLVMBuildCall(g->builder, fn_val, args, 2, llvm_cc, ZigLLVM_CallAttrAuto, "");
+ ZigLLVMBuildCall(g->builder, LLVMGlobalGetValueType(fn_val), fn_val, args, 2, llvm_cc, ZigLLVM_CallAttrAuto, "");
if (!stack_trace_is_llvm_alloca) {
// The stack trace argument is not in the stack of the caller, so
// we'd like to set tail call here, but because slices (the type of msg_arg) are
@@ -1161,7 +1161,7 @@ static LLVMValueRef gen_prefetch(CodeGen *g) {
LLVMInt32Type(),
};
LLVMTypeRef fn_type = LLVMFunctionType(LLVMVoidType(), param_types, 4, false);
- g->prefetch = LLVMAddFunction(g->module, "llvm.prefetch.p0i8", fn_type);
+ g->prefetch = LLVMAddFunction(g->module, "llvm.prefetch.p0", fn_type);
assert(LLVMGetIntrinsicID(g->prefetch));
return g->prefetch;
@@ -1265,26 +1265,37 @@ static LLVMValueRef get_add_error_return_trace_addr_fn(CodeGen *g) {
LLVMValueRef address_value = LLVMGetParam(fn_val, 1);
size_t index_field_index = g->stack_trace_type->data.structure.fields[0]->gen_index;
- LLVMValueRef index_field_ptr = LLVMBuildStructGEP(g->builder, err_ret_trace_ptr, (unsigned)index_field_index, "");
+ LLVMValueRef index_field_ptr = LLVMBuildStructGEP2(g->builder,
+ get_llvm_type(g, g->stack_trace_type),
+ err_ret_trace_ptr, (unsigned)index_field_index, "");
size_t addresses_field_index = g->stack_trace_type->data.structure.fields[1]->gen_index;
- LLVMValueRef addresses_field_ptr = LLVMBuildStructGEP(g->builder, err_ret_trace_ptr, (unsigned)addresses_field_index, "");
+ LLVMValueRef addresses_field_ptr = LLVMBuildStructGEP2(g->builder,
+ get_llvm_type(g, g->stack_trace_type),
+ err_ret_trace_ptr, (unsigned)addresses_field_index, "");
ZigType *slice_type = g->stack_trace_type->data.structure.fields[1]->type_entry;
size_t ptr_field_index = slice_type->data.structure.fields[slice_ptr_index]->gen_index;
- LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, addresses_field_ptr, (unsigned)ptr_field_index, "");
+ LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP2(g->builder,
+ ZigLLVMGetGEPResultElementType(addresses_field_ptr),
+ addresses_field_ptr, (unsigned)ptr_field_index, "");
size_t len_field_index = slice_type->data.structure.fields[slice_len_index]->gen_index;
- LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, addresses_field_ptr, (unsigned)len_field_index, "");
-
- LLVMValueRef len_value = gen_load_untyped(g, len_field_ptr, 0, false, "");
- LLVMValueRef index_val = gen_load_untyped(g, index_field_ptr, 0, false, "");
+ LLVMValueRef len_field_ptr = LLVMBuildStructGEP2(g->builder,
+ ZigLLVMGetGEPResultElementType(addresses_field_ptr),
+ addresses_field_ptr, (unsigned)len_field_index, "");
+
+ LLVMValueRef len_value = gen_load_untyped(g, ZigLLVMGetGEPResultElementType(len_field_ptr),
+ len_field_ptr, 0, false, "");
+ LLVMValueRef index_val = gen_load_untyped(g, ZigLLVMGetGEPResultElementType(index_field_ptr),
+ index_field_ptr, 0, false, "");
LLVMValueRef len_val_minus_one = LLVMBuildSub(g->builder, len_value, LLVMConstInt(usize_type_ref, 1, false), "");
LLVMValueRef masked_val = LLVMBuildAnd(g->builder, index_val, len_val_minus_one, "");
LLVMValueRef address_indices[] = {
masked_val,
};
- LLVMValueRef ptr_value = gen_load_untyped(g, ptr_field_ptr, 0, false, "");
- LLVMValueRef address_slot = LLVMBuildInBoundsGEP(g->builder, ptr_value, address_indices, 1, "");
+ LLVMValueRef ptr_value = gen_load_untyped(g, ZigLLVMGetGEPResultElementType(ptr_field_ptr),
+ ptr_field_ptr, 0, false, "");
+ LLVMValueRef address_slot = LLVMBuildInBoundsGEP2(g->builder, usize_type_ref, ptr_value, address_indices, 1, "");
gen_store_untyped(g, address_value, address_slot, 0, false);
@@ -1340,7 +1351,8 @@ static LLVMValueRef get_return_err_fn(CodeGen *g) {
LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type;
LLVMValueRef zero = LLVMConstNull(get_llvm_type(g, g->builtin_types.entry_i32));
- LLVMValueRef return_address_ptr = LLVMBuildCall(g->builder, get_return_address_fn_val(g), &zero, 1, "");
+ LLVMValueRef return_address_ptr = LLVMBuildCall2(g->builder,
+ LLVMGlobalGetValueType(get_return_address_fn_val(g)), get_return_address_fn_val(g), &zero, 1, "");
LLVMValueRef return_address = LLVMBuildPtrToInt(g->builder, return_address_ptr, usize_type_ref, "");
LLVMBasicBlockRef return_block = LLVMAppendBasicBlock(fn_val, "Return");
@@ -1355,7 +1367,8 @@ static LLVMValueRef get_return_err_fn(CodeGen *g) {
LLVMPositionBuilderAtEnd(g->builder, dest_non_null_block);
LLVMValueRef args[] = { err_ret_trace_ptr, return_address };
- ZigLLVMBuildCall(g->builder, add_error_return_trace_addr_fn_val, args, 2,
+ ZigLLVMBuildCall(g->builder, LLVMGlobalGetValueType(add_error_return_trace_addr_fn_val),
+ add_error_return_trace_addr_fn_val, args, 2,
get_llvm_cc(g, CallingConventionUnspecified), ZigLLVM_CallAttrAlwaysInline, "");
LLVMBuildRetVoid(g->builder);
@@ -1446,25 +1459,32 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) {
LLVMConstNull(usize_ty->llvm_type),
err_val,
};
- LLVMValueRef err_name_val = LLVMBuildInBoundsGEP(g->builder, g->err_name_table, err_table_indices, 2, "");
+ LLVMValueRef err_name_val = LLVMBuildInBoundsGEP2(g->builder,
+ LLVMGlobalGetValueType(g->err_name_table),
+ g->err_name_table, err_table_indices, 2, "");
- LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, err_name_val, slice_ptr_index, "");
- LLVMValueRef err_name_ptr = gen_load_untyped(g, ptr_field_ptr, 0, false, "");
+ LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP2(g->builder,
+ ZigLLVMGetGEPResultElementType(err_name_val), err_name_val, slice_ptr_index, "");
+ LLVMValueRef err_name_ptr = gen_load_untyped(g, ZigLLVMGetGEPResultElementType(ptr_field_ptr),
+ ptr_field_ptr, 0, false, "");
- LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, err_name_val, slice_len_index, "");
- LLVMValueRef err_name_len = gen_load_untyped(g, len_field_ptr, 0, false, "");
+ LLVMValueRef len_field_ptr = LLVMBuildStructGEP2(g->builder,
+ ZigLLVMGetGEPResultElementType(err_name_val), err_name_val, slice_len_index, "");
+ LLVMValueRef err_name_len = gen_load_untyped(g, ZigLLVMGetGEPResultElementType(len_field_ptr),
+ len_field_ptr, 0, false, "");
LLVMValueRef msg_prefix_len = LLVMConstInt(usize_ty->llvm_type, strlen(unwrap_err_msg_text), false);
// Points to the beginning of msg_buffer
LLVMValueRef msg_buffer_ptr_indices[] = {
LLVMConstNull(usize_ty->llvm_type),
};
- LLVMValueRef msg_buffer_ptr = LLVMBuildInBoundsGEP(g->builder, msg_buffer, msg_buffer_ptr_indices, 1, "");
+ LLVMValueRef msg_buffer_ptr = LLVMBuildInBoundsGEP2(g->builder, LLVMInt8Type(), msg_buffer,
+ msg_buffer_ptr_indices, 1, "");
// Points to the beginning of the constant prefix message
LLVMValueRef msg_prefix_ptr_indices[] = {
LLVMConstNull(usize_ty->llvm_type),
};
- LLVMValueRef msg_prefix_ptr = LLVMConstInBoundsGEP(msg_prefix, msg_prefix_ptr_indices, 1);
+ LLVMValueRef msg_prefix_ptr = LLVMConstInBoundsGEP2(LLVMInt8Type(), msg_prefix, msg_prefix_ptr_indices, 1);
// Build the message using the prefix...
ZigLLVMBuildMemCpy(g->builder, msg_buffer_ptr, 1, msg_prefix_ptr, 1, msg_prefix_len, false);
@@ -1472,16 +1492,18 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) {
LLVMValueRef msg_buffer_ptr_after_indices[] = {
msg_prefix_len,
};
- LLVMValueRef msg_buffer_ptr_after = LLVMBuildInBoundsGEP(g->builder, msg_buffer, msg_buffer_ptr_after_indices, 1, "");
+ LLVMValueRef msg_buffer_ptr_after = LLVMBuildInBoundsGEP2(g->builder, LLVMInt8Type(), msg_buffer, msg_buffer_ptr_after_indices, 1, "");
ZigLLVMBuildMemCpy(g->builder, msg_buffer_ptr_after, 1, err_name_ptr, 1, err_name_len, false);
// Set the slice pointer
- LLVMValueRef msg_slice_ptr_field_ptr = LLVMBuildStructGEP(g->builder, msg_slice, slice_ptr_index, "");
+ LLVMValueRef msg_slice_ptr_field_ptr = LLVMBuildStructGEP2(g->builder,
+ get_llvm_type(g, str_type), msg_slice, slice_ptr_index, "");
gen_store_untyped(g, msg_buffer_ptr, msg_slice_ptr_field_ptr, 0, false);
// Set the slice length
LLVMValueRef slice_len = LLVMBuildNUWAdd(g->builder, msg_prefix_len, err_name_len, "");
- LLVMValueRef msg_slice_len_field_ptr = LLVMBuildStructGEP(g->builder, msg_slice, slice_len_index, "");
+ LLVMValueRef msg_slice_len_field_ptr = LLVMBuildStructGEP2(g->builder,
+ get_llvm_type(g, str_type), msg_slice, slice_len_index, "");
gen_store_untyped(g, slice_len, msg_slice_len_field_ptr, 0, false);
// Call panic()
@@ -1522,13 +1544,15 @@ static void gen_safety_crash_for_err(CodeGen *g, LLVMValueRef err_val, Scope *sc
err_ret_trace_val,
err_val,
};
- call_instruction = ZigLLVMBuildCall(g->builder, safety_crash_err_fn, args, 2,
+ call_instruction = ZigLLVMBuildCall(g->builder, LLVMGlobalGetValueType(safety_crash_err_fn),
+ safety_crash_err_fn, args, 2,
get_llvm_cc(g, CallingConventionUnspecified), ZigLLVM_CallAttrAuto, "");
} else {
LLVMValueRef args[] = {
err_val,
};
- call_instruction = ZigLLVMBuildCall(g->builder, safety_crash_err_fn, args, 1,
+ call_instruction = ZigLLVMBuildCall(g->builder, LLVMGlobalGetValueType(safety_crash_err_fn),
+ safety_crash_err_fn, args, 1,
get_llvm_cc(g, CallingConventionUnspecified), ZigLLVM_CallAttrAuto, "");
}
if (!is_llvm_alloca) {
@@ -1573,7 +1597,7 @@ static void add_bounds_check(CodeGen *g, LLVMValueRef target_val,
static void add_sentinel_check(CodeGen *g, LLVMValueRef sentinel_elem_ptr, ZigValue *sentinel) {
LLVMValueRef expected_sentinel = gen_const_val(g, sentinel, "");
- LLVMValueRef actual_sentinel = gen_load_untyped(g, sentinel_elem_ptr, 0, false, "");
+ LLVMValueRef actual_sentinel = gen_load_untyped(g, LLVMTypeOf(expected_sentinel), sentinel_elem_ptr, 0, false, "");
LLVMValueRef ok_bit;
if (sentinel->type->id == ZigTypeIdFloat) {
ok_bit = LLVMBuildFCmp(g->builder, LLVMRealOEQ, actual_sentinel, expected_sentinel, "");
@@ -1706,7 +1730,7 @@ static LLVMValueRef gen_soft_float_widen_or_shorten(CodeGen *g, ZigType *actual_
func_ref = LLVMAddFunction(g->module, fn_name, fn_type);
}
- result = LLVMBuildCall(g->builder, func_ref, &expr_val, 1, "");
+ result = LLVMBuildCall2(g->builder, LLVMGlobalGetValueType(func_ref), func_ref, &expr_val, 1, "");
// On non-Arm platforms we need to bitcast __trunc<>fhf2 result back to f16
if (castTruncatedToF16) {
@@ -1852,7 +1876,7 @@ static LLVMValueRef gen_overflow_op(CodeGen *g, ZigType *operand_type, AddSubMul
val1,
val2,
};
- LLVMValueRef result_struct = LLVMBuildCall(g->builder, fn_val, params, 2, "");
+ LLVMValueRef result_struct = LLVMBuildCall2(g->builder, LLVMGlobalGetValueType(fn_val), fn_val, params, 2, "");
LLVMValueRef result = LLVMBuildExtractValue(g->builder, result_struct, 0, "");
LLVMValueRef overflow_bit = LLVMBuildExtractValue(g->builder, result_struct, 1, "");
if (operand_type->id == ZigTypeIdVector) {
@@ -1944,7 +1968,10 @@ static void gen_assign_raw(CodeGen *g, LLVMValueRef ptr, ZigType *ptr_type,
if (ptr_type->data.pointer.vector_index != VECTOR_INDEX_NONE) {
LLVMValueRef index_val = LLVMConstInt(LLVMInt32Type(),
ptr_type->data.pointer.vector_index, false);
- LLVMValueRef loaded_vector = gen_load(g, ptr, ptr_type, "");
+ uint32_t vec_len = ptr_type->data.pointer.host_int_bytes;
+ LLVMTypeRef vec_llvm_ty = LLVMVectorType(get_llvm_type(g, ptr_type->data.pointer.child_type), vec_len);
+ LLVMValueRef loaded_vector = gen_load_untyped(g, vec_llvm_ty, ptr,
+ get_ptr_align(g, ptr_type), ptr_type->data.pointer.is_volatile, "");
LLVMValueRef new_vector = LLVMBuildInsertElement(g->builder, loaded_vector, value,
index_val, "");
gen_store(g, new_vector, ptr, ptr_type);
@@ -1961,7 +1988,8 @@ static void gen_assign_raw(CodeGen *g, LLVMValueRef ptr, ZigType *ptr_type,
LLVMTypeRef int_ptr_ty = LLVMPointerType(LLVMIntType(host_int_bytes * 8), 0);
LLVMValueRef int_ptr = LLVMBuildBitCast(g->builder, ptr, int_ptr_ty, "");
- LLVMValueRef containing_int = gen_load(g, int_ptr, ptr_type, "");
+ LLVMValueRef containing_int = gen_load_untyped(g, LLVMIntType(host_int_bytes * 8), int_ptr,
+ get_ptr_align(g, ptr_type), ptr_type->data.pointer.is_volatile, "");
uint32_t host_bit_count = LLVMGetIntTypeWidth(LLVMTypeOf(containing_int));
assert(host_bit_count == host_int_bytes * 8);
uint32_t size_in_bits = type_size_bits(g, child_type);
@@ -2272,9 +2300,9 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_
fn_walk->data.attrs.gen_i += 1;
break;
case FnWalkIdCall: {
- LLVMTypeRef ptr_to_int_type_ref = LLVMPointerType(LLVMIntType((unsigned)ty_size * 8), 0);
- LLVMValueRef bitcasted = LLVMBuildBitCast(g->builder, val, ptr_to_int_type_ref, "");
- LLVMValueRef loaded = LLVMBuildLoad(g->builder, bitcasted, "");
+ LLVMTypeRef int_type_ref = LLVMIntType((unsigned)ty_size * 8);
+ LLVMValueRef bitcasted = LLVMBuildBitCast(g->builder, val, LLVMPointerType(int_type_ref, 0), "");
+ LLVMValueRef loaded = LLVMBuildLoad2(g->builder, int_type_ref, bitcasted, "");
fn_walk->data.call.gen_param_values->append(loaded);
break;
}
@@ -2344,16 +2372,16 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_
case FnWalkIdCall: {
LLVMValueRef abi_ptr_to_struct = LLVMBuildBitCast(g->builder, val, LLVMPointerType(abi_type, 0), "");
if (number_of_regs == 1) {
- LLVMValueRef loaded = LLVMBuildLoad(g->builder, abi_ptr_to_struct, "");
+ LLVMValueRef loaded = LLVMBuildLoad2(g->builder, abi_type, abi_ptr_to_struct, "");
fn_walk->data.call.gen_param_values->append(loaded);
break;
}
for (uint32_t i = 0; i < number_of_regs; i += 1) {
- LLVMValueRef zero = LLVMConstInt(LLVMInt32Type(), 0, false);
- LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, false);
- LLVMValueRef indices[] = { zero, index };
- LLVMValueRef adjusted_ptr_to_struct = LLVMBuildInBoundsGEP(g->builder, abi_ptr_to_struct, indices, 2, "");
- LLVMValueRef loaded = LLVMBuildLoad(g->builder, adjusted_ptr_to_struct, "");
+ LLVMValueRef adjusted_ptr_to_struct = LLVMBuildStructGEP2(g->builder,
+ abi_type, abi_ptr_to_struct, i, "");
+ LLVMTypeRef field_llvm_ty = LLVMStructGetTypeAtIndex(abi_type, i);
+ LLVMValueRef loaded = LLVMBuildLoad2(g->builder, field_llvm_ty,
+ adjusted_ptr_to_struct, "");
fn_walk->data.call.gen_param_values->append(loaded);
}
break;
@@ -2394,7 +2422,8 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_
LLVMValueRef zero = LLVMConstInt(LLVMInt32Type(), 0, false);
LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, false);
LLVMValueRef indices[] = { zero, index };
- LLVMValueRef adjusted_ptr_to_struct = LLVMBuildInBoundsGEP(g->builder, abi_ptr_to_struct, indices, 2, "");
+ LLVMValueRef adjusted_ptr_to_struct = LLVMBuildInBoundsGEP2(g->builder,
+ abi_type, abi_ptr_to_struct, indices, 2, "");
LLVMBuildStore(g->builder, arg, adjusted_ptr_to_struct);
}
fn_walk->data.inits.gen_i += 1;
@@ -2573,8 +2602,9 @@ static LLVMValueRef get_merge_err_ret_traces_fn_val(CodeGen *g) {
LLVMBasicBlockRef return_block = LLVMAppendBasicBlock(fn_val, "Return");
LLVMBasicBlockRef non_null_block = LLVMAppendBasicBlock(fn_val, "NonNull");
- LLVMValueRef frame_index_ptr = LLVMBuildAlloca(g->builder, g->builtin_types.entry_usize->llvm_type, "frame_index");
- LLVMValueRef frames_left_ptr = LLVMBuildAlloca(g->builder, g->builtin_types.entry_usize->llvm_type, "frames_left");
+ LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type;
+ LLVMValueRef frame_index_ptr = LLVMBuildAlloca(g->builder, usize_type_ref, "frame_index");
+ LLVMValueRef frames_left_ptr = LLVMBuildAlloca(g->builder, usize_type_ref, "frames_left");
LLVMValueRef dest_stack_trace_ptr = LLVMGetParam(fn_val, 0);
LLVMValueRef src_stack_trace_ptr = LLVMGetParam(fn_val, 1);
@@ -2589,18 +2619,27 @@ static LLVMValueRef get_merge_err_ret_traces_fn_val(CodeGen *g) {
LLVMPositionBuilderAtEnd(g->builder, non_null_block);
size_t src_index_field_index = g->stack_trace_type->data.structure.fields[0]->gen_index;
size_t src_addresses_field_index = g->stack_trace_type->data.structure.fields[1]->gen_index;
- LLVMValueRef src_index_field_ptr = LLVMBuildStructGEP(g->builder, src_stack_trace_ptr,
+ LLVMValueRef src_index_field_ptr = LLVMBuildStructGEP2(g->builder,
+ get_llvm_type(g, g->stack_trace_type), src_stack_trace_ptr,
(unsigned)src_index_field_index, "");
- LLVMValueRef src_addresses_field_ptr = LLVMBuildStructGEP(g->builder, src_stack_trace_ptr,
+ LLVMValueRef src_addresses_field_ptr = LLVMBuildStructGEP2(g->builder,
+ get_llvm_type(g, g->stack_trace_type), src_stack_trace_ptr,
(unsigned)src_addresses_field_index, "");
ZigType *slice_type = g->stack_trace_type->data.structure.fields[1]->type_entry;
size_t ptr_field_index = slice_type->data.structure.fields[slice_ptr_index]->gen_index;
- LLVMValueRef src_ptr_field_ptr = LLVMBuildStructGEP(g->builder, src_addresses_field_ptr, (unsigned)ptr_field_index, "");
+ LLVMValueRef src_ptr_field_ptr = LLVMBuildStructGEP2(g->builder,
+ ZigLLVMGetGEPResultElementType(src_addresses_field_ptr),
+ src_addresses_field_ptr, (unsigned)ptr_field_index, "");
size_t len_field_index = slice_type->data.structure.fields[slice_len_index]->gen_index;
- LLVMValueRef src_len_field_ptr = LLVMBuildStructGEP(g->builder, src_addresses_field_ptr, (unsigned)len_field_index, "");
- LLVMValueRef src_index_val = LLVMBuildLoad(g->builder, src_index_field_ptr, "");
- LLVMValueRef src_ptr_val = LLVMBuildLoad(g->builder, src_ptr_field_ptr, "");
- LLVMValueRef src_len_val = LLVMBuildLoad(g->builder, src_len_field_ptr, "");
+ LLVMValueRef src_len_field_ptr = LLVMBuildStructGEP2(g->builder,
+ ZigLLVMGetGEPResultElementType(src_addresses_field_ptr),
+ src_addresses_field_ptr, (unsigned)len_field_index, "");
+ LLVMValueRef src_index_val = LLVMBuildLoad2(g->builder,
+ ZigLLVMGetGEPResultElementType(src_index_field_ptr), src_index_field_ptr, "");
+ LLVMValueRef src_ptr_val = LLVMBuildLoad2(g->builder,
+ ZigLLVMGetGEPResultElementType(src_ptr_field_ptr), src_ptr_field_ptr, "");
+ LLVMValueRef src_len_val = LLVMBuildLoad2(g->builder,
+ ZigLLVMGetGEPResultElementType(src_len_field_ptr), src_len_field_ptr, "");
LLVMValueRef no_wrap_bit = LLVMBuildICmp(g->builder, LLVMIntULT, src_index_val, src_len_val, "");
LLVMBasicBlockRef no_wrap_block = LLVMAppendBasicBlock(fn_val, "NoWrap");
LLVMBasicBlockRef yes_wrap_block = LLVMAppendBasicBlock(fn_val, "YesWrap");
@@ -2608,14 +2647,14 @@ static LLVMValueRef get_merge_err_ret_traces_fn_val(CodeGen *g) {
LLVMBuildCondBr(g->builder, no_wrap_bit, no_wrap_block, yes_wrap_block);
LLVMPositionBuilderAtEnd(g->builder, no_wrap_block);
- LLVMValueRef usize_zero = LLVMConstNull(g->builtin_types.entry_usize->llvm_type);
+ LLVMValueRef usize_zero = LLVMConstNull(usize_type_ref);
LLVMBuildStore(g->builder, usize_zero, frame_index_ptr);
LLVMBuildStore(g->builder, src_index_val, frames_left_ptr);
LLVMValueRef frames_left_eq_zero_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, src_index_val, usize_zero, "");
LLVMBuildCondBr(g->builder, frames_left_eq_zero_bit, return_block, loop_block);
LLVMPositionBuilderAtEnd(g->builder, yes_wrap_block);
- LLVMValueRef usize_one = LLVMConstInt(g->builtin_types.entry_usize->llvm_type, 1, false);
+ LLVMValueRef usize_one = LLVMConstInt(usize_type_ref, 1, false);
LLVMValueRef plus_one = LLVMBuildNUWAdd(g->builder, src_index_val, usize_one, "");
LLVMValueRef mod_len = LLVMBuildURem(g->builder, plus_one, src_len_val, "");
LLVMBuildStore(g->builder, mod_len, frame_index_ptr);
@@ -2623,12 +2662,15 @@ static LLVMValueRef get_merge_err_ret_traces_fn_val(CodeGen *g) {
LLVMBuildBr(g->builder, loop_block);
LLVMPositionBuilderAtEnd(g->builder, loop_block);
- LLVMValueRef ptr_index = LLVMBuildLoad(g->builder, frame_index_ptr, "");
- LLVMValueRef addr_ptr = LLVMBuildInBoundsGEP(g->builder, src_ptr_val, &ptr_index, 1, "");
- LLVMValueRef this_addr_val = LLVMBuildLoad(g->builder, addr_ptr, "");
+ LLVMValueRef ptr_index = LLVMBuildLoad2(g->builder, usize_type_ref, frame_index_ptr, "");
+ LLVMValueRef addr_ptr = LLVMBuildInBoundsGEP2(g->builder,
+ usize_type_ref, src_ptr_val, &ptr_index, 1, "");
+ LLVMValueRef this_addr_val = LLVMBuildLoad2(g->builder, ZigLLVMGetGEPResultElementType(addr_ptr),
+ addr_ptr, "");
LLVMValueRef args[] = {dest_stack_trace_ptr, this_addr_val};
- ZigLLVMBuildCall(g->builder, add_error_return_trace_addr_fn_val, args, 2, get_llvm_cc(g, CallingConventionUnspecified), ZigLLVM_CallAttrAlwaysInline, "");
- LLVMValueRef prev_frames_left = LLVMBuildLoad(g->builder, frames_left_ptr, "");
+ ZigLLVMBuildCall(g->builder, LLVMGlobalGetValueType(add_error_return_trace_addr_fn_val),
+ add_error_return_trace_addr_fn_val, args, 2, get_llvm_cc(g, CallingConventionUnspecified), ZigLLVM_CallAttrAlwaysInline, "");
+ LLVMValueRef prev_frames_left = LLVMBuildLoad2(g->builder, usize_type_ref, frames_left_ptr, "");
LLVMValueRef new_frames_left = LLVMBuildNUWSub(g->builder, prev_frames_left, usize_one, "");
LLVMValueRef done_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, new_frames_left, usize_zero, "");
LLVMBasicBlockRef continue_block = LLVMAppendBasicBlock(fn_val, "Continue");
@@ -2639,7 +2681,7 @@ static LLVMValueRef get_merge_err_ret_traces_fn_val(CodeGen *g) {
LLVMPositionBuilderAtEnd(g->builder, continue_block);
LLVMBuildStore(g->builder, new_frames_left, frames_left_ptr);
- LLVMValueRef prev_index = LLVMBuildLoad(g->builder, frame_index_ptr, "");
+ LLVMValueRef prev_index = LLVMBuildLoad2(g->builder, usize_type_ref, frame_index_ptr, "");
LLVMValueRef index_plus_one = LLVMBuildNUWAdd(g->builder, prev_index, usize_one, "");
LLVMValueRef index_mod_len = LLVMBuildURem(g->builder, index_plus_one, src_len_val, "");
LLVMBuildStore(g->builder, index_mod_len, frame_index_ptr);
@@ -2666,13 +2708,14 @@ static LLVMValueRef ir_render_save_err_ret_addr(CodeGen *g, Stage1Air *executabl
bool is_llvm_alloca;
LLVMValueRef my_err_trace_val = get_cur_err_ret_trace_val(g, save_err_ret_addr_instruction->base.scope,
&is_llvm_alloca);
- ZigLLVMBuildCall(g->builder, return_err_fn, &my_err_trace_val, 1,
+ ZigLLVMBuildCall(g->builder, LLVMGlobalGetValueType(return_err_fn), return_err_fn, &my_err_trace_val, 1,
get_llvm_cc(g, CallingConventionUnspecified), ZigLLVM_CallAttrAuto, "");
ZigType *ret_type = g->cur_fn->type_entry->data.fn.fn_type_id.return_type;
if (fn_is_async(g->cur_fn) && codegen_fn_has_err_ret_tracing_arg(g, ret_type)) {
- LLVMValueRef trace_ptr_ptr = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr,
- frame_index_trace_arg(g, ret_type), "");
+ ZigType *frame_type = get_fn_frame_type(g, g->cur_fn);
+ LLVMValueRef trace_ptr_ptr = LLVMBuildStructGEP2(g->builder, get_llvm_type(g, frame_type),
+ g->cur_frame_ptr, frame_index_trace_arg(g, ret_type), "");
LLVMBuildStore(g->builder, my_err_trace_val, trace_ptr_ptr);
}
@@ -2702,16 +2745,21 @@ static void gen_assert_resume_id(CodeGen *g, Stage1AirInst *source_instr, Resume
LLVMPositionBuilderAtEnd(g->builder, end_bb);
}
-static LLVMValueRef gen_resume(CodeGen *g, LLVMValueRef fn_val, LLVMValueRef target_frame_ptr, ResumeId resume_id) {
+static LLVMValueRef gen_resume(CodeGen *g, LLVMTypeRef fn_llvm_ty, LLVMValueRef fn_val,
+ LLVMValueRef target_frame_ptr, ResumeId resume_id)
+{
LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type;
if (fn_val == nullptr) {
- LLVMValueRef fn_ptr_ptr = LLVMBuildStructGEP(g->builder, target_frame_ptr, frame_fn_ptr_index, "");
- fn_val = LLVMBuildLoad(g->builder, fn_ptr_ptr, "");
+ LLVMValueRef fn_ptr_ptr = LLVMBuildStructGEP2(g->builder, g->any_frame_header_llvm_ty,
+ target_frame_ptr, frame_fn_ptr_index, "");
+ fn_val = LLVMBuildLoad2(g->builder, ZigLLVMGetGEPResultElementType(fn_ptr_ptr),
+ fn_ptr_ptr, "");
}
LLVMValueRef arg_val = LLVMConstSub(LLVMConstAllOnes(usize_type_ref),
LLVMConstInt(usize_type_ref, resume_id, false));
LLVMValueRef args[] = {target_frame_ptr, arg_val};
- return ZigLLVMBuildCall(g->builder, fn_val, args, 2, ZigLLVM_Fast, ZigLLVM_CallAttrAuto, "");
+ return ZigLLVMBuildCall(g->builder, fn_llvm_ty, fn_val, args, 2, ZigLLVM_Fast,
+ ZigLLVM_CallAttrAuto, "");
}
static LLVMBasicBlockRef gen_suspend_begin(CodeGen *g, const char *name_hint) {
@@ -2733,11 +2781,11 @@ static void set_tail_call_if_appropriate(CodeGen *g, LLVMValueRef call_inst) {
LLVMSetTailCall(call_inst, true);
}
-static LLVMValueRef gen_maybe_atomic_op(CodeGen *g, LLVMAtomicRMWBinOp op, LLVMValueRef ptr, LLVMValueRef val,
- LLVMAtomicOrdering order)
+static LLVMValueRef gen_maybe_atomic_op(CodeGen *g, LLVMAtomicRMWBinOp op, LLVMValueRef ptr,
+ LLVMValueRef val, LLVMAtomicOrdering order)
{
if (g->is_single_threaded) {
- LLVMValueRef loaded = LLVMBuildLoad(g->builder, ptr, "");
+ LLVMValueRef loaded = LLVMBuildLoad2(g->builder, LLVMTypeOf(val), ptr, "");
LLVMValueRef modified;
switch (op) {
case LLVMAtomicRMWBinOpXchg:
@@ -2811,8 +2859,11 @@ static void gen_async_return(CodeGen *g, Stage1AirInstReturn *instruction) {
// If the awaiter result pointer is non-null, we need to copy the result to there.
LLVMBasicBlockRef copy_block = LLVMAppendBasicBlock(g->cur_fn_val, "CopyResult");
LLVMBasicBlockRef copy_end_block = LLVMAppendBasicBlock(g->cur_fn_val, "CopyResultEnd");
- LLVMValueRef awaiter_ret_ptr_ptr = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr, frame_ret_start + 1, "");
- LLVMValueRef awaiter_ret_ptr = LLVMBuildLoad(g->builder, awaiter_ret_ptr_ptr, "");
+ LLVMValueRef awaiter_ret_ptr_ptr = LLVMBuildStructGEP2(g->builder,
+ get_llvm_type(g, get_fn_frame_type(g, g->cur_fn)),
+ g->cur_frame_ptr, frame_ret_start + 1, "");
+ LLVMValueRef awaiter_ret_ptr = LLVMBuildLoad2(g->builder,
+ ZigLLVMGetGEPResultElementType(awaiter_ret_ptr_ptr), awaiter_ret_ptr_ptr, "");
LLVMValueRef zero_ptr = LLVMConstNull(LLVMTypeOf(awaiter_ret_ptr));
LLVMValueRef need_copy_bit = LLVMBuildICmp(g->builder, LLVMIntNE, awaiter_ret_ptr, zero_ptr, "");
LLVMBuildCondBr(g->builder, need_copy_bit, copy_block, copy_end_block);
@@ -2831,21 +2882,26 @@ static void gen_async_return(CodeGen *g, Stage1AirInstReturn *instruction) {
LLVMPositionBuilderAtEnd(g->builder, copy_end_block);
if (codegen_fn_has_err_ret_tracing_arg(g, ret_type)) {
- LLVMValueRef awaiter_trace_ptr_ptr = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr,
- frame_index_trace_arg(g, ret_type) + 1, "");
- LLVMValueRef dest_trace_ptr = LLVMBuildLoad(g->builder, awaiter_trace_ptr_ptr, "");
+ LLVMValueRef awaiter_trace_ptr_ptr = LLVMBuildStructGEP2(g->builder,
+ get_llvm_type(g, get_fn_frame_type(g, g->cur_fn)),
+ g->cur_frame_ptr, frame_index_trace_arg(g, ret_type) + 1, "");
+ LLVMValueRef dest_trace_ptr = LLVMBuildLoad2(g->builder,
+ ZigLLVMGetGEPResultElementType(awaiter_trace_ptr_ptr),
+ awaiter_trace_ptr_ptr, "");
bool is_llvm_alloca;
LLVMValueRef my_err_trace_val = get_cur_err_ret_trace_val(g, instruction->base.scope, &is_llvm_alloca);
LLVMValueRef args[] = { dest_trace_ptr, my_err_trace_val };
- ZigLLVMBuildCall(g->builder, get_merge_err_ret_traces_fn_val(g), args, 2,
+ ZigLLVMBuildCall(g->builder, LLVMGlobalGetValueType(get_merge_err_ret_traces_fn_val(g)),
+ get_merge_err_ret_traces_fn_val(g), args, 2,
get_llvm_cc(g, CallingConventionUnspecified), ZigLLVM_CallAttrAuto, "");
}
}
// Resume the caller by tail calling them.
ZigType *any_frame_type = get_any_frame_type(g, ret_type);
- LLVMValueRef their_frame_ptr = LLVMBuildIntToPtr(g->builder, prev_val, get_llvm_type(g, any_frame_type), "");
- LLVMValueRef call_inst = gen_resume(g, nullptr, their_frame_ptr, ResumeIdReturn);
+ LLVMValueRef their_frame_ptr = LLVMBuildIntToPtr(g->builder, prev_val,
+ get_llvm_type(g, any_frame_type), "");
+ LLVMValueRef call_inst = gen_resume(g, g->anyframe_fn_type, nullptr, their_frame_ptr, ResumeIdReturn);
set_tail_call_if_appropriate(g, call_inst);
LLVMBuildRetVoid(g->builder);
}
@@ -2853,13 +2909,12 @@ static void gen_async_return(CodeGen *g, Stage1AirInstReturn *instruction) {
static LLVMValueRef gen_convert_to_c_abi(CodeGen *g, LLVMValueRef location, LLVMValueRef value) {
ZigType *return_type = g->cur_fn->type_entry->data.fn.gen_return_type;
size_t size = type_size(g, return_type);
-
LLVMTypeRef abi_return_type = get_llvm_c_abi_type(g, return_type);
LLVMTypeRef abi_return_type_pointer = LLVMPointerType(abi_return_type, 0);
if (size < 8) {
LLVMValueRef bitcast = LLVMBuildBitCast(g->builder, value, abi_return_type_pointer, "");
- return LLVMBuildLoad(g->builder, bitcast, "");
+ return LLVMBuildLoad2(g->builder, abi_return_type, bitcast, "");
} else {
LLVMTypeRef i8ptr = LLVMPointerType(LLVMInt8Type(), 0);
LLVMValueRef bc_location = LLVMBuildBitCast(g->builder, location, i8ptr, "");
@@ -2867,7 +2922,7 @@ static LLVMValueRef gen_convert_to_c_abi(CodeGen *g, LLVMValueRef location, LLVM
LLVMValueRef len = LLVMConstInt(LLVMInt64Type(), size, false);
ZigLLVMBuildMemCpy(g->builder, bc_location, 8, bc_value, return_type->abi_align, len, false);
- return LLVMBuildLoad(g->builder, location, "");
+ return LLVMBuildLoad2(g->builder, abi_return_type, location, "");
}
}
@@ -2903,19 +2958,21 @@ static LLVMValueRef ir_render_return(CodeGen *g, Stage1Air *executable, Stage1Ai
} else if (g->cur_fn->type_entry->data.fn.fn_type_id.cc != CallingConventionAsync &&
handle_is_ptr(g, g->cur_fn->type_entry->data.fn.fn_type_id.return_type))
{
+ LLVMTypeRef ret_llvm_ty = get_llvm_type(g, g->cur_fn->type_entry->data.fn.fn_type_id.return_type);
if (instruction->operand == nullptr) {
- LLVMValueRef by_val_value = gen_load_untyped(g, g->cur_ret_ptr, 0, false, "");
+ LLVMValueRef by_val_value = gen_load_untyped(g, ret_llvm_ty, g->cur_ret_ptr, 0, false, "");
LLVMBuildRet(g->builder, by_val_value);
} else {
LLVMValueRef value = ir_llvm_value(g, instruction->operand);
- LLVMValueRef by_val_value = gen_load_untyped(g, value, 0, false, "");
+ LLVMValueRef by_val_value = gen_load_untyped(g, ret_llvm_ty, value, 0, false, "");
LLVMBuildRet(g->builder, by_val_value);
}
} else if (instruction->operand == nullptr) {
if (g->cur_ret_ptr == nullptr) {
LLVMBuildRetVoid(g->builder);
} else {
- LLVMValueRef by_val_value = gen_load_untyped(g, g->cur_ret_ptr, 0, false, "");
+ LLVMTypeRef ret_llvm_ty = get_llvm_type(g, g->cur_fn->type_entry->data.fn.fn_type_id.return_type);
+ LLVMValueRef by_val_value = gen_load_untyped(g, ret_llvm_ty, g->cur_ret_ptr, 0, false, "");
LLVMBuildRet(g->builder, by_val_value);
}
} else {
@@ -3011,20 +3068,18 @@ static LLVMValueRef gen_soft_float_un_op(CodeGen *g, LLVMValueRef op, ZigType *o
float_un_op_to_name(op_id), libc_float_suffix(g, scalar_type));
LLVMValueRef func_ref = get_soft_float_fn(g, fn_name, 1, scalar_type->llvm_type, scalar_type->llvm_type);
- LLVMValueRef result;
if (vector_len == 0) {
- return LLVMBuildCall(g->builder, func_ref, &op, 1, "");
+ return LLVMBuildCall2(g->builder, LLVMGlobalGetValueType(func_ref), func_ref, &op, 1, "");
} else {
- result = build_alloca(g, operand_type, "", 0);
+ LLVMValueRef result = LLVMGetUndef(operand_type->llvm_type);
LLVMTypeRef usize_ref = g->builtin_types.entry_usize->llvm_type;
for (uint32_t i = 0; i < vector_len; i++) {
LLVMValueRef index_value = LLVMConstInt(usize_ref, i, false);
LLVMValueRef param = LLVMBuildExtractElement(g->builder, op, index_value, "");
- LLVMValueRef call_result = LLVMBuildCall(g->builder, func_ref, &param, 1, "");
- LLVMBuildInsertElement(g->builder, LLVMBuildLoad(g->builder, result, ""),
- call_result, index_value, "");
+ LLVMValueRef call_result = LLVMBuildCall2(g->builder, LLVMGlobalGetValueType(func_ref), func_ref, &param, 1, "");
+ result = LLVMBuildInsertElement(g->builder, result, call_result, index_value, "");
}
- return LLVMBuildLoad(g->builder, result, "");
+ return result;
}
}
@@ -3038,7 +3093,7 @@ static LLVMValueRef gen_float_un_op(CodeGen *g, LLVMValueRef operand, ZigType *o
return gen_soft_float_un_op(g, operand, operand_type, op);
}
LLVMValueRef float_op_fn = get_float_fn(g, operand_type, ZigLLVMFnIdFloatOp, op);
- return LLVMBuildCall(g->builder, float_op_fn, &operand, 1, "");
+ return LLVMBuildCall2(g->builder, LLVMGlobalGetValueType(float_op_fn), float_op_fn, &operand, 1, "");
}
enum DivKind {
@@ -3404,7 +3459,7 @@ static LLVMValueRef gen_soft_int_to_float_op(CodeGen *g, LLVMValueRef value_ref,
}
LLVMValueRef params[1] = {value_ref};
- return LLVMBuildCall(g->builder, func_ref, params, param_count, "");
+ return LLVMBuildCall2(g->builder, LLVMGlobalGetValueType(func_ref), func_ref, params, param_count, "");
}
static LLVMValueRef gen_soft_float_to_int_op(CodeGen *g, LLVMValueRef value_ref, ZigType *operand_type, ZigType *result_type) {
@@ -3440,7 +3495,7 @@ static LLVMValueRef gen_soft_float_to_int_op(CodeGen *g, LLVMValueRef value_ref,
}
LLVMValueRef params[1] = {value_ref};
- LLVMValueRef result = LLVMBuildCall(g->builder, func_ref, params, param_count, "");
+ LLVMValueRef result = LLVMBuildCall2(g->builder, LLVMGlobalGetValueType(func_ref), func_ref, params, param_count, "");
if ((wider_type->data.integral.bit_count == 128) && (g->zig_target->os == OsWindows) && (g->zig_target->arch == ZigLLVM_x86_64)) {
result = LLVMBuildBitCast(g->builder, result, wider_type->llvm_type, "");
@@ -3553,12 +3608,12 @@ static LLVMValueRef gen_soft_float_bin_op(CodeGen *g, LLVMValueRef op1_value, LL
LLVMValueRef result;
if (vector_len == 0) {
LLVMValueRef params[2] = {op1_value, op2_value};
- result = LLVMBuildCall(g->builder, func_ref, params, param_count, "");
+ result = LLVMBuildCall2(g->builder, LLVMGlobalGetValueType(func_ref), func_ref, params, param_count, "");
result = add_icmp(g, result, res_icmp);
} else {
ZigType *alloca_ty = operand_type;
if (res_icmp != NONE) alloca_ty = get_vector_type(g, vector_len, g->builtin_types.entry_bool);
- result = build_alloca(g, alloca_ty, "", 0);
+ result = LLVMGetUndef(alloca_ty->llvm_type);
LLVMTypeRef usize_ref = g->builtin_types.entry_usize->llvm_type;
for (uint32_t i = 0; i < vector_len; i++) {
@@ -3567,13 +3622,10 @@ static LLVMValueRef gen_soft_float_bin_op(CodeGen *g, LLVMValueRef op1_value, LL
LLVMBuildExtractElement(g->builder, op1_value, index_value, ""),
LLVMBuildExtractElement(g->builder, op2_value, index_value, ""),
};
- LLVMValueRef call_result = LLVMBuildCall(g->builder, func_ref, params, param_count, "");
+ LLVMValueRef call_result = LLVMBuildCall2(g->builder, LLVMGlobalGetValueType(func_ref), func_ref, params, param_count, "");
call_result = add_icmp(g, call_result, res_icmp);
- LLVMBuildInsertElement(g->builder, LLVMBuildLoad(g->builder, result, ""),
- call_result, index_value, "");
+ result = LLVMBuildInsertElement(g->builder, result, call_result, index_value, "");
}
-
- result = LLVMBuildLoad(g->builder, result, "");
}
// Some operations are implemented as compound ops and require us to perform some
@@ -3703,7 +3755,9 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, Stage1Air *executable,
}
// TODO runtime safety
- return LLVMBuildInBoundsGEP(g->builder, op1_value, &subscript_value, 1, "");
+ LLVMTypeRef elem_llvm_ty = get_llvm_type(g, scalar_type->data.pointer.child_type);
+ return LLVMBuildInBoundsGEP2(g->builder, elem_llvm_ty, op1_value,
+ &subscript_value, 1, "");
} else if (scalar_type->id == ZigTypeIdFloat) {
ZigLLVMSetFastMath(g->builder, ir_want_fast_math(g, &bin_op_instruction->base));
return float_op[add_sub_mul](g->builder, op1_value, op2_value, "");
@@ -4044,20 +4098,22 @@ static LLVMValueRef ir_render_ptr_of_array_to_slice(CodeGen *g, Stage1Air *execu
assert(array_type->id == ZigTypeIdArray);
if (type_has_bits(g, actual_type)) {
- LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, result_loc, ptr_index, "");
+ LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP2(g->builder, get_llvm_type(g, slice_type),
+ result_loc, ptr_index, "");
LLVMValueRef indices[] = {
LLVMConstNull(g->builtin_types.entry_usize->llvm_type),
LLVMConstInt(g->builtin_types.entry_usize->llvm_type, 0, false),
};
LLVMValueRef expr_val = ir_llvm_value(g, instruction->operand);
- LLVMValueRef slice_start_ptr = LLVMBuildInBoundsGEP(g->builder, expr_val, indices, 2, "");
+ LLVMValueRef slice_start_ptr = LLVMBuildInBoundsGEP2(g->builder,
+ get_llvm_type(g, array_type), expr_val, indices, 2, "");
gen_store_untyped(g, slice_start_ptr, ptr_field_ptr, 0, false);
} else if (ir_want_runtime_safety(g, &instruction->base) && ptr_index != SIZE_MAX) {
- LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, result_loc, ptr_index, "");
+ LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP2(g->builder, get_llvm_type(g, slice_type), result_loc, ptr_index, "");
gen_undef_init(g, slice_ptr_type, slice_ptr_type, ptr_field_ptr);
}
- LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, result_loc, len_index, "");
+ LLVMValueRef len_field_ptr = LLVMBuildStructGEP2(g->builder, get_llvm_type(g, slice_type), result_loc, len_index, "");
LLVMValueRef len_value = LLVMConstInt(g->builtin_types.entry_usize->llvm_type,
array_type->data.array.len, false);
gen_store_untyped(g, len_value, len_field_ptr, 0, false);
@@ -4107,10 +4163,11 @@ static LLVMValueRef ir_render_bit_cast(CodeGen *g, Stage1Air *executable,
return LLVMBuildBitCast(g->builder, value, wanted_type_ref, "");
} else if (actual_is_ptr) {
// A scalar is wanted but we got a pointer
- LLVMTypeRef wanted_ptr_type_ref = LLVMPointerType(get_llvm_type(g, wanted_type), 0);
- LLVMValueRef bitcasted_ptr = LLVMBuildBitCast(g->builder, value, wanted_ptr_type_ref, "");
+ LLVMTypeRef wanted_elem_type_ref = get_llvm_type(g, wanted_type);
+ LLVMValueRef bitcasted_ptr = LLVMBuildBitCast(g->builder, value,
+ LLVMPointerType(wanted_elem_type_ref, 0), "");
uint32_t alignment = get_abi_alignment(g, actual_type);
- return gen_load_untyped(g, bitcasted_ptr, alignment, false, "");
+ return gen_load_untyped(g, wanted_elem_type_ref, bitcasted_ptr, alignment, false, "");
} else {
// A pointer is wanted but we got a scalar
assert(actual_type->id == ZigTypeIdPointer);
@@ -4298,32 +4355,26 @@ static LLVMValueRef ir_render_binary_not(CodeGen *g, Stage1Air *executable,
static LLVMValueRef gen_soft_float_neg(CodeGen *g, ZigType *operand_type, LLVMValueRef operand) {
uint32_t vector_len = operand_type->id == ZigTypeIdVector ? operand_type->data.vector.len : 0;
- uint16_t num_bits = operand_type->data.floating.bit_count;
+ uint16_t num_bits = operand_type->id == ZigTypeIdVector ?
+ operand_type->data.vector.elem_type->data.floating.bit_count :
+ operand_type->data.floating.bit_count;
ZigType *iX_type = get_int_type(g, true, num_bits);
- LLVMValueRef sign_mask = LLVMConstInt(iX_type->llvm_type, 1, false);
- sign_mask = LLVMConstShl(sign_mask, LLVMConstInt(iX_type->llvm_type, num_bits - 1, false));
+ LLVMValueRef sign_mask = LLVMConstShl(
+ LLVMConstInt(iX_type->llvm_type, 1, false),
+ LLVMConstInt(iX_type->llvm_type, num_bits - 1, false));
- if (vector_len == 0) {
- LLVMValueRef bitcasted_operand = LLVMBuildBitCast(g->builder, operand, iX_type->llvm_type, "");
- LLVMValueRef result = LLVMBuildXor(g->builder, bitcasted_operand, sign_mask, "");
+ LLVMValueRef sign_mask_splat = (vector_len == 0) ? sign_mask :
+ LLVMBuildVectorSplat(g->builder, vector_len, sign_mask, "");
- return LLVMBuildBitCast(g->builder, result, operand_type->llvm_type, "");
- } else {
- LLVMTypeRef usize_ref = g->builtin_types.entry_usize->llvm_type;
- ZigType *iX_vector_type = get_vector_type(g, vector_len, iX_type);
+ LLVMValueRef bitcasted_operand = LLVMBuildBitCast(g->builder, operand,
+ (vector_len == 0) ?
+ iX_type->llvm_type :
+ get_vector_type(g, vector_len, iX_type)->llvm_type,
+ "");
- LLVMValueRef result = build_alloca(g, iX_vector_type, "", 0);
- LLVMValueRef bitcasted_operand = LLVMBuildBitCast(g->builder, operand, iX_vector_type->llvm_type, "");
- for (uint32_t i = 0; i < vector_len; i++) {
- LLVMValueRef index_value = LLVMConstInt(usize_ref, i, false);
- LLVMValueRef elem = LLVMBuildExtractElement(g->builder, bitcasted_operand, index_value, "");
- LLVMValueRef result_elem = LLVMBuildXor(g->builder, elem, sign_mask, "");
- LLVMBuildInsertElement(g->builder, LLVMBuildLoad(g->builder, result, ""),
- result_elem, index_value, "");
- }
- return LLVMBuildBitCast(g->builder, LLVMBuildLoad(g->builder, result, ""), operand_type->llvm_type, "");
- }
+ LLVMValueRef result = LLVMBuildXor(g->builder, bitcasted_operand, sign_mask_splat, "");
+ return LLVMBuildBitCast(g->builder, result, operand_type->llvm_type, "");
}
static LLVMValueRef gen_negation(CodeGen *g, Stage1AirInst *inst, Stage1AirInst *operand, bool wrapping) {
@@ -4398,7 +4449,9 @@ static LLVMValueRef ir_render_load_ptr(CodeGen *g, Stage1Air *executable,
if (ptr_type->data.pointer.vector_index != VECTOR_INDEX_NONE) {
LLVMValueRef index_val = LLVMConstInt(LLVMInt32Type(),
ptr_type->data.pointer.vector_index, false);
- LLVMValueRef loaded_vector = LLVMBuildLoad(g->builder, ptr, "");
+ uint32_t vec_len = ptr_type->data.pointer.host_int_bytes;
+ LLVMTypeRef vec_llvm_ty = LLVMVectorType(get_llvm_type(g, child_type), vec_len);
+ LLVMValueRef loaded_vector = LLVMBuildLoad2(g->builder, vec_llvm_ty, ptr, "");
return LLVMBuildExtractElement(g->builder, loaded_vector, index_val, "");
}
@@ -4410,10 +4463,11 @@ static LLVMValueRef ir_render_load_ptr(CodeGen *g, Stage1Air *executable,
LLVMTypeRef int_ptr_ty = LLVMPointerType(LLVMIntType(host_int_bytes * 8), 0);
LLVMValueRef int_ptr = LLVMBuildBitCast(g->builder, ptr, int_ptr_ty, "");
- LLVMValueRef containing_int = gen_load(g, int_ptr, ptr_type, "");
+ LLVMValueRef containing_int = gen_load_untyped(g, LLVMIntType(host_int_bytes * 8), int_ptr,
+ get_ptr_align(g, ptr_type), ptr_type->data.pointer.is_volatile, "");
uint32_t host_bit_count = LLVMGetIntTypeWidth(LLVMTypeOf(containing_int));
- assert(host_bit_count == host_int_bytes * 8);
+ ir_assert(host_bit_count == host_int_bytes * 8, &instruction->base);
uint32_t size_in_bits = type_size_bits(g, child_type);
uint32_t bit_offset = ptr_type->data.pointer.bit_offset_in_host;
@@ -4524,7 +4578,8 @@ static LLVMValueRef gen_valgrind_client_request(CodeGen *g, LLVMValueRef default
zero,
LLVMConstInt(usize_type_ref, i, false),
};
- LLVMValueRef elem_ptr = LLVMBuildInBoundsGEP(g->builder, array_ptr, indexes, 2, "");
+ LLVMValueRef elem_ptr = LLVMBuildInBoundsGEP2(g->builder,
+ LLVMGetAllocatedType(array_ptr), array_ptr, indexes, 2, "");
LLVMBuildStore(g->builder, array_elements[i], elem_ptr);
}
@@ -4545,7 +4600,7 @@ static LLVMValueRef gen_valgrind_client_request(CodeGen *g, LLVMValueRef default
LLVMValueRef asm_fn = LLVMGetInlineAsm(function_type, buf_ptr(asm_template), buf_len(asm_template),
buf_ptr(asm_constraints), buf_len(asm_constraints), asm_has_side_effects, asm_is_alignstack,
LLVMInlineAsmDialectATT, false);
- return LLVMBuildCall(g->builder, asm_fn, param_values, input_and_output_count, "");
+ return LLVMBuildCall2(g->builder, function_type, asm_fn, param_values, input_and_output_count, "");
}
}
zig_unreachable();
@@ -4719,10 +4774,9 @@ static LLVMValueRef ir_render_elem_ptr(CodeGen *g, Stage1Air *executable, Stage1
LLVMValueRef elem_size_bytes = LLVMConstInt(g->builtin_types.entry_usize->llvm_type,
size_in_bits / 8, false);
LLVMValueRef byte_offset = LLVMBuildNUWMul(g->builder, subscript_value, elem_size_bytes, "");
- LLVMValueRef indices[] = {
- byte_offset
- };
- LLVMValueRef elem_byte_ptr = LLVMBuildInBoundsGEP(g->builder, u8_array_ptr, indices, 1, "");
+ LLVMValueRef indices[] = { byte_offset };
+ LLVMValueRef elem_byte_ptr = LLVMBuildInBoundsGEP2(g->builder, LLVMInt8Type(),
+ u8_array_ptr, indices, 1, "");
return LLVMBuildBitCast(g->builder, elem_byte_ptr, LLVMPointerType(get_llvm_type(g, child_type), 0), "");
}
}
@@ -4730,14 +4784,14 @@ static LLVMValueRef ir_render_elem_ptr(CodeGen *g, Stage1Air *executable, Stage1
LLVMConstNull(g->builtin_types.entry_usize->llvm_type),
subscript_value
};
- return LLVMBuildInBoundsGEP(g->builder, array_ptr, indices, 2, "");
+ return LLVMBuildInBoundsGEP2(g->builder, get_llvm_type(g, array_type), array_ptr,
+ indices, 2, "");
} else if (array_type->id == ZigTypeIdPointer) {
LLVMValueRef array_ptr = get_handle_value(g, array_ptr_ptr, array_type, array_ptr_type);
assert(LLVMGetTypeKind(LLVMTypeOf(array_ptr)) == LLVMPointerTypeKind);
- LLVMValueRef indices[] = {
- subscript_value
- };
- return LLVMBuildInBoundsGEP(g->builder, array_ptr, indices, 1, "");
+ LLVMValueRef indices[] = { subscript_value };
+ LLVMTypeRef elem_llvm_ty = get_llvm_type(g, array_type->data.pointer.child_type);
+ return LLVMBuildInBoundsGEP2(g->builder, elem_llvm_ty, array_ptr, indices, 1, "");
} else if (array_type->id == ZigTypeIdStruct) {
LLVMValueRef array_ptr = get_handle_value(g, array_ptr_ptr, array_type, array_ptr_type);
assert(array_type->data.structure.special == StructSpecialSlice);
@@ -4752,22 +4806,26 @@ static LLVMValueRef ir_render_elem_ptr(CodeGen *g, Stage1Air *executable, Stage1
}
assert(LLVMGetTypeKind(LLVMTypeOf(array_ptr)) == LLVMPointerTypeKind);
- assert(LLVMGetTypeKind(LLVMGetElementType(LLVMTypeOf(array_ptr))) == LLVMStructTypeKind);
if (safety_check_on) {
size_t len_index = array_type->data.structure.fields[slice_len_index]->gen_index;
assert(len_index != SIZE_MAX);
- LLVMValueRef len_ptr = LLVMBuildStructGEP(g->builder, array_ptr, (unsigned)len_index, "");
- LLVMValueRef len = gen_load_untyped(g, len_ptr, 0, false, "");
+ LLVMValueRef len_ptr = LLVMBuildStructGEP2(g->builder, get_llvm_type(g, array_type),
+ array_ptr, (unsigned)len_index, "");
+ LLVMValueRef len = gen_load_untyped(g, ZigLLVMGetGEPResultElementType(len_ptr), len_ptr,
+ 0, false, "");
LLVMIntPredicate upper_op = (ptr_type->data.pointer.sentinel != nullptr) ? LLVMIntULE : LLVMIntULT;
add_bounds_check(g, subscript_value, LLVMIntEQ, nullptr, upper_op, len);
}
size_t ptr_index = array_type->data.structure.fields[slice_ptr_index]->gen_index;
assert(ptr_index != SIZE_MAX);
- LLVMValueRef ptr_ptr = LLVMBuildStructGEP(g->builder, array_ptr, (unsigned)ptr_index, "");
- LLVMValueRef ptr = gen_load_untyped(g, ptr_ptr, 0, false, "");
- return LLVMBuildInBoundsGEP(g->builder, ptr, &subscript_value, 1, "");
+ LLVMValueRef ptr_ptr = LLVMBuildStructGEP2(g->builder, get_llvm_type(g, array_type),
+ array_ptr, (unsigned)ptr_index, "");
+ LLVMValueRef ptr = gen_load_untyped(g,
+ LLVMPointerTypeInContext(LLVMGetGlobalContext(), 0), ptr_ptr, 0, false, "");
+ LLVMTypeRef elem_llvm_ty = get_llvm_type(g, ptr_type->data.pointer.child_type);
+ return LLVMBuildInBoundsGEP2(g->builder, elem_llvm_ty, ptr, &subscript_value, 1, "");
} else if (array_type->id == ZigTypeIdVector) {
return array_ptr_ptr;
} else {
@@ -4775,12 +4833,16 @@ static LLVMValueRef ir_render_elem_ptr(CodeGen *g, Stage1Air *executable, Stage1
}
}
-static LLVMValueRef get_new_stack_addr(CodeGen *g, LLVMValueRef new_stack) {
- LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, new_stack, (unsigned)slice_ptr_index, "");
- LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, new_stack, (unsigned)slice_len_index, "");
+static LLVMValueRef get_new_stack_addr(CodeGen *g, LLVMTypeRef new_stack_llvm_ty,
+ LLVMValueRef new_stack)
+{
+ LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP2(g->builder, new_stack_llvm_ty, new_stack, (unsigned)slice_ptr_index, "");
+ LLVMValueRef len_field_ptr = LLVMBuildStructGEP2(g->builder, new_stack_llvm_ty, new_stack, (unsigned)slice_len_index, "");
- LLVMValueRef ptr_value = gen_load_untyped(g, ptr_field_ptr, 0, false, "");
- LLVMValueRef len_value = gen_load_untyped(g, len_field_ptr, 0, false, "");
+ LLVMValueRef ptr_value = gen_load_untyped(g, ZigLLVMGetGEPResultElementType(ptr_field_ptr),
+ ptr_field_ptr, 0, false, "");
+ LLVMValueRef len_value = gen_load_untyped(g, ZigLLVMGetGEPResultElementType(len_field_ptr),
+ len_field_ptr, 0, false, "");
LLVMValueRef ptr_addr = LLVMBuildPtrToInt(g->builder, ptr_value, LLVMTypeOf(len_value), "");
LLVMValueRef end_addr = LLVMBuildNUWAdd(g->builder, ptr_addr, len_value, "");
@@ -4804,7 +4866,7 @@ static void gen_set_stack_pointer(CodeGen *g, LLVMValueRef aligned_end_addr) {
aligned_end_addr,
};
- LLVMBuildCall(g->builder, write_register_fn_val, params, 2, "");
+ LLVMBuildCall2(g->builder, LLVMGlobalGetValueType(write_register_fn_val), write_register_fn_val, params, 2, "");
}
static void render_async_spills(CodeGen *g) {
@@ -4834,7 +4896,9 @@ static void render_async_spills(CodeGen *g) {
}
calc_llvm_field_index_add(g, &arg_calc, var->var_type);
- var->value_ref = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr, arg_calc.field_index - 1, var->name);
+ var->value_ref = LLVMBuildStructGEP2(g->builder,
+ get_llvm_type(g, get_fn_frame_type(g, g->cur_fn)),
+ g->cur_frame_ptr, arg_calc.field_index - 1, var->name);
if (var->decl_node) {
var->di_loc_var = ZigLLVMCreateAutoVariable(g->dbuilder, get_di_scope(g, var->parent_scope),
var->name, import->data.structure.root_struct->di_file,
@@ -4852,7 +4916,9 @@ static void render_async_spills(CodeGen *g) {
continue;
size_t gen_index = frame_type->data.structure.fields[instruction->field_index]->gen_index;
- instruction->base.llvm_value = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr, gen_index,
+ instruction->base.llvm_value = LLVMBuildStructGEP2(g->builder,
+ get_llvm_type(g, get_fn_frame_type(g, g->cur_fn)),
+ g->cur_frame_ptr, gen_index,
instruction->name_hint);
}
}
@@ -4895,8 +4961,8 @@ static LLVMValueRef gen_frame_size(CodeGen *g, LLVMValueRef fn_val) {
LLVMTypeRef ptr_usize_llvm_type = LLVMPointerType(usize_llvm_type, 0);
LLVMValueRef casted_fn_val = LLVMBuildBitCast(g->builder, fn_val, ptr_usize_llvm_type, "");
LLVMValueRef negative_one = LLVMConstInt(LLVMInt32Type(), -1, true);
- LLVMValueRef prefix_ptr = LLVMBuildInBoundsGEP(g->builder, casted_fn_val, &negative_one, 1, "");
- LLVMValueRef load_inst = LLVMBuildLoad(g->builder, prefix_ptr, "");
+ LLVMValueRef prefix_ptr = LLVMBuildInBoundsGEP2(g->builder, usize_llvm_type, casted_fn_val, &negative_one, 1, "");
+ LLVMValueRef load_inst = LLVMBuildLoad2(g->builder, usize_llvm_type, prefix_ptr, "");
// Some architectures (e.g SPARCv9) has different alignment requirements between a
// function/usize pointer and also require all loads to be aligned.
@@ -4910,17 +4976,23 @@ static LLVMValueRef gen_frame_size(CodeGen *g, LLVMValueRef fn_val) {
static void gen_init_stack_trace(CodeGen *g, LLVMValueRef trace_field_ptr, LLVMValueRef addrs_field_ptr) {
LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type;
LLVMValueRef zero = LLVMConstNull(usize_type_ref);
+ LLVMTypeRef stack_trace_llvm_ty = get_llvm_type(g, get_stack_trace_type(g));
- LLVMValueRef index_ptr = LLVMBuildStructGEP(g->builder, trace_field_ptr, 0, "");
+ LLVMValueRef index_ptr = LLVMBuildStructGEP2(g->builder, stack_trace_llvm_ty, trace_field_ptr, 0, "");
LLVMBuildStore(g->builder, zero, index_ptr);
- LLVMValueRef addrs_slice_ptr = LLVMBuildStructGEP(g->builder, trace_field_ptr, 1, "");
- LLVMValueRef addrs_ptr_ptr = LLVMBuildStructGEP(g->builder, addrs_slice_ptr, slice_ptr_index, "");
+ LLVMValueRef addrs_slice_ptr = LLVMBuildStructGEP2(g->builder, stack_trace_llvm_ty, trace_field_ptr, 1, "");
+ LLVMValueRef addrs_ptr_ptr = LLVMBuildStructGEP2(g->builder,
+ ZigLLVMGetGEPResultElementType(addrs_slice_ptr),
+ addrs_slice_ptr, slice_ptr_index, "");
LLVMValueRef indices[] = { LLVMConstNull(usize_type_ref), LLVMConstNull(usize_type_ref) };
- LLVMValueRef trace_field_addrs_as_ptr = LLVMBuildInBoundsGEP(g->builder, addrs_field_ptr, indices, 2, "");
+ LLVMValueRef trace_field_addrs_as_ptr = LLVMBuildInBoundsGEP2(g->builder,
+ ZigLLVMGetGEPResultElementType(addrs_field_ptr), addrs_field_ptr, indices, 2, "");
LLVMBuildStore(g->builder, trace_field_addrs_as_ptr, addrs_ptr_ptr);
- LLVMValueRef addrs_len_ptr = LLVMBuildStructGEP(g->builder, addrs_slice_ptr, slice_len_index, "");
+ LLVMValueRef addrs_len_ptr = LLVMBuildStructGEP2(g->builder,
+ ZigLLVMGetGEPResultElementType(addrs_slice_ptr),
+ addrs_slice_ptr, slice_len_index, "");
LLVMBuildStore(g->builder, LLVMConstInt(usize_type_ref, stack_trace_ptr_count, false), addrs_len_ptr);
}
@@ -4930,17 +5002,20 @@ static LLVMValueRef ir_render_call(CodeGen *g, Stage1Air *executable, Stage1AirI
LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type;
LLVMValueRef fn_val;
+ LLVMTypeRef fn_llvm_ty;
ZigType *fn_type;
bool callee_is_async;
if (instruction->fn_entry) {
fn_val = fn_llvm_value(g, instruction->fn_entry);
fn_type = instruction->fn_entry->type_entry;
callee_is_async = fn_is_async(instruction->fn_entry);
+ fn_llvm_ty = LLVMGlobalGetValueType(fn_val);
} else {
assert(instruction->fn_ref);
fn_val = ir_llvm_value(g, instruction->fn_ref);
fn_type = instruction->fn_ref->value->type;
callee_is_async = fn_type->data.fn.fn_type_id.cc == CallingConventionAsync;
+ fn_llvm_ty = fn_type->data.fn.raw_type_ref;
}
FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id;
@@ -4961,29 +5036,40 @@ static LLVMValueRef ir_render_call(CodeGen *g, Stage1Air *executable, Stage1AirI
ZigType *anyframe_type = nullptr;
LLVMValueRef frame_result_loc_uncasted = nullptr;
LLVMValueRef frame_result_loc;
+ LLVMTypeRef frame_struct_llvm_ty;
LLVMValueRef awaiter_init_val;
LLVMValueRef ret_ptr;
if (callee_is_async) {
if (instruction->new_stack == nullptr) {
if (instruction->modifier == CallModifierAsync) {
frame_result_loc = result_loc;
+ if (result_loc != nullptr) {
+ ir_assert(instruction->result_loc->value->type->id == ZigTypeIdPointer, &instruction->base);
+ frame_struct_llvm_ty = get_llvm_type(g, instruction->result_loc->value->type->data.pointer.child_type);
+ } else {
+ frame_struct_llvm_ty = nullptr;
+ }
} else {
ir_assert(instruction->frame_result_loc != nullptr, &instruction->base);
frame_result_loc_uncasted = ir_llvm_value(g, instruction->frame_result_loc);
ir_assert(instruction->fn_entry != nullptr, &instruction->base);
+ frame_struct_llvm_ty = get_llvm_type(g, instruction->fn_entry->frame_type);
frame_result_loc = LLVMBuildBitCast(g->builder, frame_result_loc_uncasted,
- LLVMPointerType(get_llvm_type(g, instruction->fn_entry->frame_type), 0), "");
+ LLVMPointerType(frame_struct_llvm_ty, 0), "");
}
} else {
if (instruction->new_stack->value->type->id == ZigTypeIdPointer &&
instruction->new_stack->value->type->data.pointer.child_type->id == ZigTypeIdFnFrame)
{
frame_result_loc = ir_llvm_value(g, instruction->new_stack);
+ frame_struct_llvm_ty = get_llvm_type(g, instruction->new_stack->value->type->data.pointer.child_type);
} else {
LLVMValueRef frame_slice_ptr = ir_llvm_value(g, instruction->new_stack);
+ LLVMTypeRef frame_slice_llvm_ty = get_llvm_type(g, instruction->new_stack->value->type);
if (ir_want_runtime_safety(g, &instruction->base)) {
- LLVMValueRef given_len_ptr = LLVMBuildStructGEP(g->builder, frame_slice_ptr, slice_len_index, "");
- LLVMValueRef given_frame_len = LLVMBuildLoad(g->builder, given_len_ptr, "");
+ LLVMValueRef given_len_ptr = LLVMBuildStructGEP2(g->builder,
+ frame_slice_llvm_ty, frame_slice_ptr, slice_len_index, "");
+ LLVMValueRef given_frame_len = LLVMBuildLoad2(g->builder, usize_type_ref, given_len_ptr, "");
LLVMValueRef actual_frame_len = gen_frame_size(g, fn_val);
LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "FrameSizeCheckFail");
@@ -4998,11 +5084,14 @@ static LLVMValueRef ir_render_call(CodeGen *g, Stage1Air *executable, Stage1AirI
LLVMPositionBuilderAtEnd(g->builder, ok_block);
}
need_frame_ptr_ptr_spill = true;
- LLVMValueRef frame_ptr_ptr = LLVMBuildStructGEP(g->builder, frame_slice_ptr, slice_ptr_index, "");
- LLVMValueRef frame_ptr = LLVMBuildLoad(g->builder, frame_ptr_ptr, "");
+ LLVMValueRef frame_ptr_ptr = LLVMBuildStructGEP2(g->builder, frame_slice_llvm_ty,
+ frame_slice_ptr, slice_ptr_index, "");
+ LLVMValueRef frame_ptr = LLVMBuildLoad2(g->builder,
+ ZigLLVMGetGEPResultElementType(frame_ptr_ptr), frame_ptr_ptr, "");
if (instruction->fn_entry == nullptr) {
anyframe_type = get_any_frame_type(g, src_return_type);
frame_result_loc = LLVMBuildBitCast(g->builder, frame_ptr, get_llvm_type(g, anyframe_type), "");
+ frame_struct_llvm_ty = anyframe_type->data.any_frame.struct_llvm_ty;
} else {
ZigType *frame_type = get_fn_frame_type(g, instruction->fn_entry);
if ((err = type_resolve(g, frame_type, ResolveStatusLLVMFull)))
@@ -5010,6 +5099,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, Stage1Air *executable, Stage1AirI
ZigType *ptr_frame_type = get_pointer_to_type(g, frame_type, false);
frame_result_loc = LLVMBuildBitCast(g->builder, frame_ptr,
get_llvm_type(g, ptr_frame_type), "");
+ frame_struct_llvm_ty = get_llvm_type(g, frame_type);
}
}
}
@@ -5019,7 +5109,8 @@ static LLVMValueRef ir_render_call(CodeGen *g, Stage1Air *executable, Stage1AirI
if (ret_has_bits) {
// Use the result location which is inside the frame if this is an async call.
- ret_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc, frame_ret_start + 2, "");
+ ret_ptr = LLVMBuildStructGEP2(g->builder, frame_struct_llvm_ty,
+ frame_result_loc, frame_ret_start + 2, "");
}
} else {
awaiter_init_val = zero;
@@ -5030,7 +5121,8 @@ static LLVMValueRef ir_render_call(CodeGen *g, Stage1Air *executable, Stage1AirI
ret_ptr = result_loc;
} else {
// no result location provided to @asyncCall - use the one inside the frame.
- ret_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc, frame_ret_start + 2, "");
+ ret_ptr = LLVMBuildStructGEP2(g->builder, frame_struct_llvm_ty,
+ frame_result_loc, frame_ret_start + 2, "");
}
}
}
@@ -5050,20 +5142,20 @@ static LLVMValueRef ir_render_call(CodeGen *g, Stage1Air *executable, Stage1AirI
if (ret_has_bits) {
if (result_loc == nullptr) {
// return type is a scalar, but we still need a pointer to it. Use the async fn frame.
- ret_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc, frame_ret_start + 2, "");
+ ret_ptr = LLVMBuildStructGEP2(g->builder, frame_struct_llvm_ty, frame_result_loc, frame_ret_start + 2, "");
} else {
// Use the call instruction's result location.
ret_ptr = result_loc;
}
// Store a zero in the awaiter's result ptr to indicate we do not need a copy made.
- LLVMValueRef awaiter_ret_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc, frame_ret_start + 1, "");
- LLVMValueRef zero_ptr = LLVMConstNull(LLVMGetElementType(LLVMTypeOf(awaiter_ret_ptr)));
+ LLVMValueRef awaiter_ret_ptr = LLVMBuildStructGEP2(g->builder, frame_struct_llvm_ty, frame_result_loc, frame_ret_start + 1, "");
+ LLVMValueRef zero_ptr = LLVMConstNull(ZigLLVMGetGEPResultElementType(awaiter_ret_ptr));
LLVMBuildStore(g->builder, zero_ptr, awaiter_ret_ptr);
}
if (prefix_arg_err_ret_stack) {
- LLVMValueRef err_ret_trace_ptr_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc,
+ LLVMValueRef err_ret_trace_ptr_ptr = LLVMBuildStructGEP2(g->builder, frame_struct_llvm_ty, frame_result_loc,
frame_index_trace_arg(g, src_return_type) + 1, "");
bool is_llvm_alloca;
LLVMValueRef my_err_ret_trace_val = get_cur_err_ret_trace_val(g, instruction->base.scope,
@@ -5074,19 +5166,19 @@ static LLVMValueRef ir_render_call(CodeGen *g, Stage1Air *executable, Stage1AirI
assert(frame_result_loc != nullptr);
- LLVMValueRef fn_ptr_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc, frame_fn_ptr_index, "");
+ LLVMValueRef fn_ptr_ptr = LLVMBuildStructGEP2(g->builder, frame_struct_llvm_ty, frame_result_loc, frame_fn_ptr_index, "");
LLVMValueRef bitcasted_fn_val = LLVMBuildBitCast(g->builder, fn_val,
- LLVMGetElementType(LLVMTypeOf(fn_ptr_ptr)), "");
+ LLVMPointerTypeInContext(LLVMGetGlobalContext(), 0), "");
LLVMBuildStore(g->builder, bitcasted_fn_val, fn_ptr_ptr);
- LLVMValueRef resume_index_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc, frame_resume_index, "");
+ LLVMValueRef resume_index_ptr = LLVMBuildStructGEP2(g->builder, frame_struct_llvm_ty, frame_result_loc, frame_resume_index, "");
LLVMBuildStore(g->builder, zero, resume_index_ptr);
- LLVMValueRef awaiter_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc, frame_awaiter_index, "");
+ LLVMValueRef awaiter_ptr = LLVMBuildStructGEP2(g->builder, frame_struct_llvm_ty, frame_result_loc, frame_awaiter_index, "");
LLVMBuildStore(g->builder, awaiter_init_val, awaiter_ptr);
if (ret_has_bits) {
- LLVMValueRef ret_ptr_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc, frame_ret_start, "");
+ LLVMValueRef ret_ptr_ptr = LLVMBuildStructGEP2(g->builder, frame_struct_llvm_ty, frame_result_loc, frame_ret_start, "");
LLVMBuildStore(g->builder, ret_ptr, ret_ptr_ptr);
}
} else if (instruction->modifier == CallModifierAsync) {
@@ -5095,14 +5187,20 @@ static LLVMValueRef ir_render_call(CodeGen *g, Stage1Air *executable, Stage1AirI
zig_panic("TODO @asyncCall of non-async function");
}
frame_result_loc = result_loc;
+ if (result_loc != nullptr) {
+ ir_assert(instruction->result_loc->value->type->id == ZigTypeIdPointer, &instruction->base);
+ frame_struct_llvm_ty = get_llvm_type(g, instruction->result_loc->value->type->data.pointer.child_type);
+ } else {
+ frame_struct_llvm_ty = nullptr;
+ }
awaiter_init_val = LLVMConstAllOnes(usize_type_ref);
- LLVMValueRef awaiter_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc, frame_awaiter_index, "");
+ LLVMValueRef awaiter_ptr = LLVMBuildStructGEP2(g->builder, frame_struct_llvm_ty, frame_result_loc, frame_awaiter_index, "");
LLVMBuildStore(g->builder, awaiter_init_val, awaiter_ptr);
if (ret_has_bits) {
- ret_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc, frame_ret_start + 2, "");
- LLVMValueRef ret_ptr_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc, frame_ret_start, "");
+ ret_ptr = LLVMBuildStructGEP2(g->builder, frame_struct_llvm_ty, frame_result_loc, frame_ret_start + 2, "");
+ LLVMValueRef ret_ptr_ptr = LLVMBuildStructGEP2(g->builder, frame_struct_llvm_ty, frame_result_loc, frame_ret_start, "");
LLVMBuildStore(g->builder, ret_ptr, ret_ptr_ptr);
if (first_arg_ret) {
@@ -5113,11 +5211,11 @@ static LLVMValueRef ir_render_call(CodeGen *g, Stage1Air *executable, Stage1AirI
// Then we have to wire up the StackTrace pointers.
// Await is responsible for merging error return traces.
uint32_t trace_field_index_start = frame_index_trace_arg(g, src_return_type);
- LLVMValueRef callee_trace_ptr_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc,
+ LLVMValueRef callee_trace_ptr_ptr = LLVMBuildStructGEP2(g->builder, frame_struct_llvm_ty, frame_result_loc,
trace_field_index_start, "");
- LLVMValueRef trace_field_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc,
+ LLVMValueRef trace_field_ptr = LLVMBuildStructGEP2(g->builder, frame_struct_llvm_ty, frame_result_loc,
trace_field_index_start + 2, "");
- LLVMValueRef addrs_field_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc,
+ LLVMValueRef addrs_field_ptr = LLVMBuildStructGEP2(g->builder, frame_struct_llvm_ty, frame_result_loc,
trace_field_index_start + 3, "");
LLVMBuildStore(g->builder, trace_field_ptr, callee_trace_ptr_ptr);
@@ -5178,6 +5276,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, Stage1Air *executable, Stage1AirI
frame_index_arg_calc(g, &arg_calc_start, fn_type->data.fn.fn_type_id.return_type);
LLVMValueRef casted_frame;
+ LLVMTypeRef casted_frame_llvm_ty;
if (instruction->new_stack != nullptr && instruction->fn_entry == nullptr) {
// We need the frame type to be a pointer to a struct that includes the args
@@ -5189,8 +5288,8 @@ static LLVMValueRef ir_render_call(CodeGen *g, Stage1Air *executable, Stage1AirI
size_t field_count = arg_calc.field_index;
LLVMTypeRef *field_types = heap::c_allocator.allocate_nonzero<LLVMTypeRef>(field_count);
- LLVMGetStructElementTypes(LLVMGetElementType(LLVMTypeOf(frame_result_loc)), field_types);
- assert(LLVMCountStructElementTypes(LLVMGetElementType(LLVMTypeOf(frame_result_loc))) == arg_calc_start.field_index);
+ LLVMGetStructElementTypes(frame_struct_llvm_ty, field_types);
+ assert(LLVMCountStructElementTypes(frame_struct_llvm_ty) == arg_calc_start.field_index);
arg_calc = arg_calc_start;
for (size_t arg_i = 0; arg_i < gen_param_values.length; arg_i += 1) {
@@ -5211,32 +5310,34 @@ static LLVMValueRef ir_render_call(CodeGen *g, Stage1Air *executable, Stage1AirI
LLVMTypeRef ptr_frame_with_args_type = LLVMPointerType(frame_with_args_type, 0);
casted_frame = LLVMBuildBitCast(g->builder, frame_result_loc, ptr_frame_with_args_type, "");
+ casted_frame_llvm_ty = frame_with_args_type;
} else {
casted_frame = frame_result_loc;
+ casted_frame_llvm_ty = frame_struct_llvm_ty;
}
CalcLLVMFieldIndex arg_calc = arg_calc_start;
for (size_t arg_i = 0; arg_i < gen_param_values.length; arg_i += 1) {
calc_llvm_field_index_add(g, &arg_calc, gen_param_types.at(arg_i));
- LLVMValueRef arg_ptr = LLVMBuildStructGEP(g->builder, casted_frame, arg_calc.field_index - 1, "");
+ LLVMValueRef arg_ptr = LLVMBuildStructGEP2(g->builder, casted_frame_llvm_ty, casted_frame, arg_calc.field_index - 1, "");
gen_assign_raw(g, arg_ptr, get_pointer_to_type(g, gen_param_types.at(arg_i), true),
gen_param_values.at(arg_i));
}
gen_param_types.deinit();
if (instruction->modifier == CallModifierAsync) {
- gen_resume(g, fn_val, frame_result_loc, ResumeIdCall);
+ gen_resume(g, fn_llvm_ty, fn_val, frame_result_loc, ResumeIdCall);
if (instruction->new_stack != nullptr) {
return LLVMBuildBitCast(g->builder, frame_result_loc,
get_llvm_type(g, instruction->base.value->type), "");
}
return nullptr;
} else if (instruction->modifier == CallModifierNoSuspend && !fn_is_async(g->cur_fn)) {
- gen_resume(g, fn_val, frame_result_loc, ResumeIdCall);
+ gen_resume(g, fn_llvm_ty, fn_val, frame_result_loc, ResumeIdCall);
if (ir_want_runtime_safety(g, &instruction->base)) {
- LLVMValueRef awaiter_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc,
- frame_awaiter_index, "");
+ LLVMValueRef awaiter_ptr = LLVMBuildStructGEP2(g->builder, frame_struct_llvm_ty,
+ frame_result_loc, frame_awaiter_index, "");
LLVMValueRef all_ones = LLVMConstAllOnes(usize_type_ref);
LLVMValueRef prev_val = gen_maybe_atomic_op(g, LLVMAtomicRMWBinOpXchg, awaiter_ptr,
all_ones, LLVMAtomicOrderingRelease);
@@ -5255,14 +5356,15 @@ static LLVMValueRef ir_render_call(CodeGen *g, Stage1Air *executable, Stage1AirI
ZigType *result_type = instruction->base.value->type;
ZigType *ptr_result_type = get_pointer_to_type(g, result_type, true);
- return gen_await_early_return(g, &instruction->base, frame_result_loc,
+ return gen_await_early_return(g, &instruction->base,
+ frame_struct_llvm_ty, frame_result_loc,
result_type, ptr_result_type, result_loc, true);
} else {
ZigType *ptr_result_type = get_pointer_to_type(g, src_return_type, true);
LLVMBasicBlockRef call_bb = gen_suspend_begin(g, "CallResume");
- LLVMValueRef call_inst = gen_resume(g, fn_val, frame_result_loc, ResumeIdCall);
+ LLVMValueRef call_inst = gen_resume(g, fn_llvm_ty, fn_val, frame_result_loc, ResumeIdCall);
set_tail_call_if_appropriate(g, call_inst);
LLVMBuildRetVoid(g->builder);
@@ -5284,44 +5386,52 @@ static LLVMValueRef ir_render_call(CodeGen *g, Stage1Air *executable, Stage1AirI
if (need_frame_ptr_ptr_spill) {
LLVMValueRef frame_slice_ptr = ir_llvm_value(g, instruction->new_stack);
- LLVMValueRef frame_ptr_ptr = LLVMBuildStructGEP(g->builder, frame_slice_ptr, slice_ptr_index, "");
- frame_result_loc_uncasted = LLVMBuildLoad(g->builder, frame_ptr_ptr, "");
+ LLVMValueRef frame_ptr_ptr = LLVMBuildStructGEP2(g->builder,
+ get_llvm_type(g, instruction->new_stack->value->type),
+ frame_slice_ptr, slice_ptr_index, "");
+ frame_result_loc_uncasted = LLVMBuildLoad2(g->builder,
+ ZigLLVMGetGEPResultElementType(frame_ptr_ptr), frame_ptr_ptr, "");
}
if (frame_result_loc_uncasted != nullptr) {
if (instruction->fn_entry != nullptr) {
+ frame_struct_llvm_ty = get_llvm_type(g, instruction->fn_entry->frame_type);
frame_result_loc = LLVMBuildBitCast(g->builder, frame_result_loc_uncasted,
- LLVMPointerType(get_llvm_type(g, instruction->fn_entry->frame_type), 0), "");
+ LLVMPointerType(frame_struct_llvm_ty, 0), "");
} else {
frame_result_loc = LLVMBuildBitCast(g->builder, frame_result_loc_uncasted,
get_llvm_type(g, anyframe_type), "");
+ frame_struct_llvm_ty = anyframe_type->data.any_frame.struct_llvm_ty;
}
}
- LLVMValueRef result_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc, frame_ret_start + 2, "");
- return LLVMBuildLoad(g->builder, result_ptr, "");
+ LLVMValueRef result_ptr = LLVMBuildStructGEP2(g->builder, frame_struct_llvm_ty,
+ frame_result_loc, frame_ret_start + 2, "");
+ return LLVMBuildLoad2(g->builder, get_llvm_type(g, src_return_type), result_ptr, "");
}
} else {
gen_param_types.deinit();
}
if (instruction->new_stack == nullptr || instruction->is_async_call_builtin) {
- result = ZigLLVMBuildCall(g->builder, fn_val,
+ result = ZigLLVMBuildCall(g->builder, fn_llvm_ty, fn_val,
gen_param_values.items, (unsigned)gen_param_values.length, llvm_cc, call_attr, "");
} else if (instruction->modifier == CallModifierAsync) {
zig_panic("TODO @asyncCall of non-async function");
} else {
- LLVMValueRef new_stack_addr = get_new_stack_addr(g, ir_llvm_value(g, instruction->new_stack));
+ LLVMValueRef new_stack_addr = get_new_stack_addr(g,
+ get_llvm_type(g, instruction->new_stack->value->type),
+ ir_llvm_value(g, instruction->new_stack));
LLVMValueRef old_stack_ref;
if (src_return_type->id != ZigTypeIdUnreachable) {
LLVMValueRef stacksave_fn_val = get_stacksave_fn_val(g);
- old_stack_ref = LLVMBuildCall(g->builder, stacksave_fn_val, nullptr, 0, "");
+ old_stack_ref = LLVMBuildCall2(g->builder, LLVMGlobalGetValueType(stacksave_fn_val), stacksave_fn_val, nullptr, 0, "");
}
gen_set_stack_pointer(g, new_stack_addr);
- result = ZigLLVMBuildCall(g->builder, fn_val,
+ result = ZigLLVMBuildCall(g->builder, fn_llvm_ty, fn_val,
gen_param_values.items, (unsigned)gen_param_values.length, llvm_cc, call_attr, "");
if (src_return_type->id != ZigTypeIdUnreachable) {
LLVMValueRef stackrestore_fn_val = get_stackrestore_fn_val(g);
- LLVMBuildCall(g->builder, stackrestore_fn_val, &old_stack_ref, 1, "");
+ LLVMBuildCall2(g->builder, LLVMGlobalGetValueType(stackrestore_fn_val), stackrestore_fn_val, &old_stack_ref, 1, "");
}
}
@@ -5387,7 +5497,8 @@ static LLVMValueRef ir_render_struct_field_ptr(CodeGen *g, Stage1Air *executable
codegen_report_errors_and_exit(g);
ir_assert(field->gen_index != SIZE_MAX, &instruction->base);
- LLVMValueRef field_ptr_val = LLVMBuildStructGEP(g->builder, struct_ptr, (unsigned)field->gen_index, "");
+ LLVMValueRef field_ptr_val = LLVMBuildStructGEP2(g->builder,
+ get_llvm_type(g, struct_type), struct_ptr, (unsigned)field->gen_index, "");
ZigType *res_type = instruction->base.value->type;
ir_assert(res_type->id == ZigTypeIdPointer, &instruction->base);
if (res_type->data.pointer.host_int_bytes != 0) {
@@ -5432,8 +5543,9 @@ static LLVMValueRef ir_render_union_field_ptr(CodeGen *g, Stage1Air *executable,
LLVMPointerType(tag_type_ref, 0), "");
} else {
assert(union_type->data.unionation.gen_tag_index != SIZE_MAX);
- tag_field_ptr = LLVMBuildStructGEP(g->builder, union_ptr,
- union_type->data.unionation.gen_tag_index, "");
+ tag_field_ptr = LLVMBuildStructGEP2(g->builder,
+ get_llvm_type(g, union_type),
+ union_ptr, union_type->data.unionation.gen_tag_index, "");
}
LLVMValueRef tag_value = bigint_to_llvm_const(tag_type_ref,
@@ -5448,19 +5560,25 @@ static LLVMValueRef ir_render_union_field_ptr(CodeGen *g, Stage1Air *executable,
LLVMTypeRef field_type_ref = LLVMPointerType(get_llvm_type(g, field->type_entry), 0);
if (union_type->data.unionation.gen_tag_index == SIZE_MAX) {
- LLVMValueRef union_field_ptr = LLVMBuildStructGEP(g->builder, union_ptr, 0, "");
+ LLVMValueRef union_field_ptr = LLVMBuildStructGEP2(g->builder,
+ get_llvm_type(g, union_type), union_ptr, 0, "");
LLVMValueRef bitcasted_union_field_ptr = LLVMBuildBitCast(g->builder, union_field_ptr, field_type_ref, "");
return bitcasted_union_field_ptr;
}
if (instruction->initializing) {
- LLVMValueRef tag_field_ptr = LLVMBuildStructGEP(g->builder, union_ptr, union_type->data.unionation.gen_tag_index, "");
+ LLVMValueRef tag_field_ptr = LLVMBuildStructGEP2(g->builder,
+ get_llvm_type(g, union_type),
+ union_ptr, union_type->data.unionation.gen_tag_index, "");
LLVMValueRef tag_value = bigint_to_llvm_const(get_llvm_type(g, union_type->data.unionation.tag_type),
&field->enum_field->value);
gen_store_untyped(g, tag_value, tag_field_ptr, 0, false);
} else if (instruction->safety_check_on && ir_want_runtime_safety(g, &instruction->base)) {
- LLVMValueRef tag_field_ptr = LLVMBuildStructGEP(g->builder, union_ptr, union_type->data.unionation.gen_tag_index, "");
- LLVMValueRef tag_value = gen_load_untyped(g, tag_field_ptr, 0, false, "");
+ LLVMValueRef tag_field_ptr = LLVMBuildStructGEP2(g->builder,
+ get_llvm_type(g, union_type),
+ union_ptr, union_type->data.unionation.gen_tag_index, "");
+ LLVMValueRef tag_value = gen_load_untyped(g, ZigLLVMGetGEPResultElementType(tag_field_ptr),
+ tag_field_ptr, 0, false, "");
LLVMValueRef expected_tag_value = bigint_to_llvm_const(get_llvm_type(g, union_type->data.unionation.tag_type),
@@ -5476,8 +5594,8 @@ static LLVMValueRef ir_render_union_field_ptr(CodeGen *g, Stage1Air *executable,
LLVMPositionBuilderAtEnd(g->builder, ok_block);
}
- LLVMValueRef union_field_ptr = LLVMBuildStructGEP(g->builder, union_ptr,
- union_type->data.unionation.gen_union_index, "");
+ LLVMValueRef union_field_ptr = LLVMBuildStructGEP2(g->builder, get_llvm_type(g, union_type),
+ union_ptr, union_type->data.unionation.gen_union_index, "");
LLVMValueRef bitcasted_union_field_ptr = LLVMBuildBitCast(g->builder, union_field_ptr, field_type_ref, "");
return bitcasted_union_field_ptr;
}
@@ -5555,7 +5673,7 @@ static LLVMValueRef ir_render_asm_gen(CodeGen *g, Stage1Air *executable, Stage1A
size_t param_index = 0;
LLVMTypeRef *param_types = heap::c_allocator.allocate<LLVMTypeRef>(input_and_output_count);
LLVMValueRef *param_values = heap::c_allocator.allocate<LLVMValueRef>(input_and_output_count);
- bool *param_needs_attr = heap::c_allocator.allocate<bool>(input_and_output_count);
+ LLVMTypeRef *param_needs_attr = heap::c_allocator.allocate<LLVMTypeRef>(input_and_output_count);
for (size_t i = 0; i < asm_expr->output_list.length; i += 1, total_index += 1) {
AsmOutput *asm_output = asm_expr->output_list.at(i);
bool is_return = (asm_output->return_type != nullptr);
@@ -5571,7 +5689,8 @@ static LLVMValueRef ir_render_asm_gen(CodeGen *g, Stage1Air *executable, Stage1A
buf_appendf(&constraint_buf, "=%s", buf_ptr(asm_output->constraint) + 1);
} else {
buf_appendf(&constraint_buf, "=*%s", buf_ptr(asm_output->constraint) + 1);
- param_needs_attr[param_index] = true;
+ ZigVar *variable = instruction->output_vars[i];
+ param_needs_attr[param_index] = get_llvm_type(g, variable->var_type);
}
if (total_index + 1 < total_constraint_count) {
buf_append_char(&constraint_buf, ',');
@@ -5597,6 +5716,7 @@ static LLVMValueRef ir_render_asm_gen(CodeGen *g, Stage1Air *executable, Stage1A
ZigType *const type = ir_input->value->type;
LLVMTypeRef type_ref = get_llvm_type(g, type);
LLVMValueRef value_ref = ir_llvm_value(g, ir_input);
+ LLVMTypeRef elem_type_ref = nullptr;
// Handle integers of non pot bitsize by widening them.
if (type->id == ZigTypeIdInt) {
const size_t bitsize = type->data.integral.bit_count;
@@ -5608,6 +5728,7 @@ static LLVMValueRef ir_render_asm_gen(CodeGen *g, Stage1Air *executable, Stage1A
value_ref = gen_widen_or_shorten(g, false, type, wider_type, value_ref);
}
} else if (handle_is_ptr(g, type)) {
+ elem_type_ref = type_ref;
ZigType *gen_type = get_pointer_to_type(g, type, true);
type_ref = get_llvm_type(g, gen_type);
}
@@ -5615,7 +5736,10 @@ static LLVMValueRef ir_render_asm_gen(CodeGen *g, Stage1Air *executable, Stage1A
param_types[param_index] = type_ref;
param_values[param_index] = value_ref;
// In the case of indirect inputs, LLVM requires the callsite to have an elementtype(<ty>) attribute.
- param_needs_attr[param_index] = buf_ptr(asm_input->constraint)[0] == '*';
+ if (buf_ptr(asm_input->constraint)[0] == '*') {
+ param_needs_attr[param_index] = elem_type_ref ? elem_type_ref :
+ get_llvm_type(g, type->data.pointer.child_type);
+ }
}
for (size_t i = 0; i < asm_expr->clobber_list.length; i += 1, total_index += 1) {
Buf *clobber_buf = asm_expr->clobber_list.at(i);
@@ -5660,11 +5784,12 @@ static LLVMValueRef ir_render_asm_gen(CodeGen *g, Stage1Air *executable, Stage1A
LLVMValueRef asm_fn = LLVMGetInlineAsm(function_type, buf_ptr(&llvm_template), buf_len(&llvm_template),
buf_ptr(&constraint_buf), buf_len(&constraint_buf), is_volatile, false, LLVMInlineAsmDialectATT, false);
- LLVMValueRef built_call = LLVMBuildCall(g->builder, asm_fn, param_values, (unsigned)input_and_output_count, "");
+ LLVMValueRef built_call = LLVMBuildCall2(g->builder, function_type,
+ asm_fn, param_values, (unsigned)input_and_output_count, "");
for (size_t i = 0; i < input_and_output_count; i += 1) {
- if (param_needs_attr[i]) {
- LLVMTypeRef elem_ty = LLVMGetElementType(param_types[i]);
+ if (param_needs_attr[i] != nullptr) {
+ LLVMTypeRef elem_ty = param_needs_attr[i];
ZigLLVMSetCallElemTypeAttr(built_call, i, elem_ty);
}
}
@@ -5689,8 +5814,9 @@ static LLVMValueRef gen_non_null_bit(CodeGen *g, ZigType *maybe_type, LLVMValueR
if (is_scalar)
return LLVMBuildICmp(g->builder, LLVMIntNE, maybe_handle, LLVMConstNull(get_llvm_type(g, maybe_type)), "");
- LLVMValueRef maybe_field_ptr = LLVMBuildStructGEP(g->builder, maybe_handle, maybe_null_index, "");
- return gen_load_untyped(g, maybe_field_ptr, 0, false, "");
+ LLVMValueRef maybe_field_ptr = LLVMBuildStructGEP2(g->builder,
+ get_llvm_type(g, maybe_type), maybe_handle, maybe_null_index, "");
+ return gen_load_untyped(g, ZigLLVMGetGEPResultElementType(maybe_field_ptr), maybe_field_ptr, 0, false, "");
}
static LLVMValueRef ir_render_test_non_null(CodeGen *g, Stage1Air *executable,
@@ -5736,12 +5862,13 @@ static LLVMValueRef ir_render_optional_unwrap_ptr(CodeGen *g, Stage1Air *executa
} else {
LLVMValueRef optional_struct_ref = get_handle_value(g, base_ptr, maybe_type, ptr_type);
if (instruction->initializing) {
- LLVMValueRef non_null_bit_ptr = LLVMBuildStructGEP(g->builder, optional_struct_ref,
- maybe_null_index, "");
+ LLVMValueRef non_null_bit_ptr = LLVMBuildStructGEP2(g->builder,
+ get_llvm_type(g, maybe_type), optional_struct_ref, maybe_null_index, "");
LLVMValueRef non_null_bit = LLVMConstInt(LLVMInt1Type(), 1, false);
gen_store_untyped(g, non_null_bit, non_null_bit_ptr, 0, false);
}
- return LLVMBuildStructGEP(g->builder, optional_struct_ref, maybe_child_index, "");
+ return LLVMBuildStructGEP2(g->builder,
+ get_llvm_type(g, maybe_type), optional_struct_ref, maybe_child_index, "");
}
}
}
@@ -5818,7 +5945,7 @@ static LLVMValueRef ir_render_clz(CodeGen *g, Stage1Air *executable, Stage1AirIn
operand,
LLVMConstNull(LLVMInt1Type()),
};
- LLVMValueRef wrong_size_int = LLVMBuildCall(g->builder, fn_val, params, 2, "");
+ LLVMValueRef wrong_size_int = LLVMBuildCall2(g->builder, LLVMGlobalGetValueType(fn_val), fn_val, params, 2, "");
return gen_widen_or_shorten(g, false, int_type, instruction->base.value->type, wrong_size_int);
}
@@ -5830,7 +5957,7 @@ static LLVMValueRef ir_render_ctz(CodeGen *g, Stage1Air *executable, Stage1AirIn
operand,
LLVMConstNull(LLVMInt1Type()),
};
- LLVMValueRef wrong_size_int = LLVMBuildCall(g->builder, fn_val, params, 2, "");
+ LLVMValueRef wrong_size_int = LLVMBuildCall2(g->builder, LLVMGlobalGetValueType(fn_val), fn_val, params, 2, "");
return gen_widen_or_shorten(g, false, int_type, instruction->base.value->type, wrong_size_int);
}
@@ -5887,7 +6014,7 @@ static LLVMValueRef ir_render_pop_count(CodeGen *g, Stage1Air *executable, Stage
ZigType *int_type = instruction->op->value->type;
LLVMValueRef fn_val = get_int_builtin_fn(g, int_type, BuiltinFnIdPopCount);
LLVMValueRef operand = ir_llvm_value(g, instruction->op);
- LLVMValueRef wrong_size_int = LLVMBuildCall(g->builder, fn_val, &operand, 1, "");
+ LLVMValueRef wrong_size_int = LLVMBuildCall2(g->builder, LLVMGlobalGetValueType(fn_val), fn_val, &operand, 1, "");
return gen_widen_or_shorten(g, false, int_type, instruction->base.value->type, wrong_size_int);
}
@@ -5978,7 +6105,9 @@ static LLVMValueRef ir_render_err_name(CodeGen *g, Stage1Air *executable, Stage1
LLVMConstNull(g->builtin_types.entry_usize->llvm_type),
err_val,
};
- return LLVMBuildInBoundsGEP(g->builder, g->err_name_table, indices, 2, "");
+ return LLVMBuildInBoundsGEP2(g->builder,
+ LLVMGlobalGetValueType(g->err_name_table),
+ g->err_name_table, indices, 2, "");
}
static LLVMValueRef get_enum_tag_name_function(CodeGen *g, ZigType *enum_type) {
@@ -6050,7 +6179,7 @@ static LLVMValueRef get_enum_tag_name_function(CodeGen *g, ZigType *enum_type) {
LLVMSetAlignment(str_global, LLVMABIAlignmentOfType(g->target_data_ref, LLVMTypeOf(str_init)));
LLVMValueRef fields[] = {
- LLVMConstGEP(str_global, array_ptr_indices, 2),
+ LLVMConstInBoundsGEP2(LLVMGlobalGetValueType(str_global), str_global, array_ptr_indices, 2),
LLVMConstInt(g->builtin_types.entry_usize->llvm_type, buf_len(name), false),
};
LLVMValueRef slice_init_value = LLVMConstNamedStruct(get_llvm_type(g, u8_slice_type), fields, 2);
@@ -6099,7 +6228,8 @@ static LLVMValueRef ir_render_enum_tag_name(CodeGen *g, Stage1Air *executable,
LLVMValueRef enum_name_function = get_enum_tag_name_function(g, enum_type);
LLVMValueRef enum_tag_value = ir_llvm_value(g, instruction->target);
- return ZigLLVMBuildCall(g->builder, enum_name_function, &enum_tag_value, 1,
+ return ZigLLVMBuildCall(g->builder, LLVMGlobalGetValueType(enum_name_function), enum_name_function,
+ &enum_tag_value, 1,
get_llvm_cc(g, CallingConventionUnspecified), ZigLLVM_CallAttrAuto, "");
}
@@ -6166,8 +6296,10 @@ static LLVMValueRef ir_render_align_cast(CodeGen *g, Stage1Air *executable, Stag
align_bytes = get_ptr_align(g, slice_ptr_type);
size_t ptr_index = target_type->data.structure.fields[slice_ptr_index]->gen_index;
- LLVMValueRef ptr_val_ptr = LLVMBuildStructGEP(g->builder, target_val, (unsigned)ptr_index, "");
- ptr_val = gen_load_untyped(g, ptr_val_ptr, 0, false, "");
+ LLVMValueRef ptr_val_ptr = LLVMBuildStructGEP2(g->builder,
+ get_llvm_type(g, target_type),
+ target_val, (unsigned)ptr_index, "");
+ ptr_val = gen_load_untyped(g, ZigLLVMGetGEPResultElementType(ptr_val_ptr), ptr_val_ptr, 0, false, "");
} else {
zig_unreachable();
}
@@ -6319,12 +6451,16 @@ static LLVMValueRef ir_render_cmpxchg(CodeGen *g, Stage1Air *executable, Stage1A
if (actual_abi_type != nullptr) {
payload_val = LLVMBuildTrunc(g->builder, payload_val, get_llvm_type(g, operand_type), "");
}
- LLVMValueRef val_ptr = LLVMBuildStructGEP(g->builder, result_loc, maybe_child_index, "");
+ LLVMTypeRef result_loc_struct_llvm_ty = get_llvm_type(g,
+ instruction->result_loc->value->type->data.pointer.child_type);
+ LLVMValueRef val_ptr = LLVMBuildStructGEP2(g->builder,
+ result_loc_struct_llvm_ty, result_loc, maybe_child_index, "");
gen_assign_raw(g, val_ptr, get_pointer_to_type(g, child_type, false), payload_val);
LLVMValueRef success_bit = LLVMBuildExtractValue(g->builder, result_val, 1, "");
LLVMValueRef nonnull_bit = LLVMBuildNot(g->builder, success_bit, "");
- LLVMValueRef maybe_ptr = LLVMBuildStructGEP(g->builder, result_loc, maybe_null_index, "");
+ LLVMValueRef maybe_ptr = LLVMBuildStructGEP2(g->builder, result_loc_struct_llvm_ty, result_loc,
+ maybe_null_index, "");
gen_store_untyped(g, nonnull_bit, maybe_ptr, 0, false);
return result_loc;
}
@@ -6469,7 +6605,7 @@ static LLVMValueRef ir_render_memcpy(CodeGen *g, Stage1Air *executable, Stage1Ai
static LLVMValueRef ir_render_wasm_memory_size(CodeGen *g, Stage1Air *executable, Stage1AirInstWasmMemorySize *instruction) {
// TODO adjust for wasm64
LLVMValueRef param = ir_llvm_value(g, instruction->index);
- LLVMValueRef val = LLVMBuildCall(g->builder, gen_wasm_memory_size(g), &param, 1, "");
+ LLVMValueRef val = LLVMBuildCall2(g->builder, LLVMGlobalGetValueType(gen_wasm_memory_size(g)), gen_wasm_memory_size(g), &param, 1, "");
return val;
}
@@ -6479,7 +6615,7 @@ static LLVMValueRef ir_render_wasm_memory_grow(CodeGen *g, Stage1Air *executable
ir_llvm_value(g, instruction->index),
ir_llvm_value(g, instruction->delta),
};
- LLVMValueRef val = LLVMBuildCall(g->builder, gen_wasm_memory_grow(g), params, 2, "");
+ LLVMValueRef val = LLVMBuildCall2(g->builder, LLVMGlobalGetValueType(gen_wasm_memory_grow(g)), gen_wasm_memory_grow(g), params, 2, "");
return val;
}
@@ -6525,7 +6661,7 @@ static LLVMValueRef ir_render_prefetch(CodeGen *g, Stage1Air *executable, Stage1
LLVMConstInt(LLVMInt32Type(), instruction->locality, false),
LLVMConstInt(LLVMInt32Type(), instruction->cache, false),
};
- LLVMValueRef val = LLVMBuildCall(g->builder, gen_prefetch(g), params, 4, "");
+ LLVMValueRef val = LLVMBuildCall2(g->builder, LLVMGlobalGetValueType(gen_prefetch(g)), gen_prefetch(g), params, 4, "");
return val;
}
@@ -6591,12 +6727,14 @@ static LLVMValueRef ir_render_slice(CodeGen *g, Stage1Air *executable, Stage1Air
codegen_report_errors_and_exit(g);
if (value_has_bits) {
+ LLVMTypeRef array_llvm_ty = get_llvm_type(g, array_type);
if (want_runtime_safety && sentinel != nullptr) {
LLVMValueRef indices[] = {
LLVMConstNull(g->builtin_types.entry_usize->llvm_type),
end_val,
};
- LLVMValueRef sentinel_elem_ptr = LLVMBuildInBoundsGEP(g->builder, array_ptr, indices, 2, "");
+ LLVMValueRef sentinel_elem_ptr = LLVMBuildInBoundsGEP2(g->builder,
+ array_llvm_ty, array_ptr, indices, 2, "");
add_sentinel_check(g, sentinel_elem_ptr, sentinel);
}
@@ -6604,7 +6742,7 @@ static LLVMValueRef ir_render_slice(CodeGen *g, Stage1Air *executable, Stage1Air
LLVMConstNull(g->builtin_types.entry_usize->llvm_type),
start_val,
};
- slice_start_ptr = LLVMBuildInBoundsGEP(g->builder, array_ptr, indices, 2, "");
+ slice_start_ptr = LLVMBuildInBoundsGEP2(g->builder, array_llvm_ty, array_ptr, indices, 2, "");
}
len_value = LLVMBuildNUWSub(g->builder, end_val, start_val, "");
@@ -6623,27 +6761,30 @@ static LLVMValueRef ir_render_slice(CodeGen *g, Stage1Air *executable, Stage1Air
codegen_report_errors_and_exit(g);
if (value_has_bits) {
+ LLVMTypeRef elem_llvm_ty = get_llvm_type(g, array_type->data.pointer.child_type);
if (want_runtime_safety && sentinel != nullptr) {
- LLVMValueRef sentinel_elem_ptr = LLVMBuildInBoundsGEP(g->builder, array_ptr, &end_val, 1, "");
+ LLVMValueRef sentinel_elem_ptr = LLVMBuildInBoundsGEP2(g->builder, elem_llvm_ty,
+ array_ptr, &end_val, 1, "");
add_sentinel_check(g, sentinel_elem_ptr, sentinel);
}
- slice_start_ptr = LLVMBuildInBoundsGEP(g->builder, array_ptr, &start_val, 1, "");
+ slice_start_ptr = LLVMBuildInBoundsGEP2(g->builder, elem_llvm_ty, array_ptr,
+ &start_val, 1, "");
}
len_value = LLVMBuildNUWSub(g->builder, end_val, start_val, "");
} else if (array_type->id == ZigTypeIdStruct) {
assert(array_type->data.structure.special == StructSpecialSlice);
assert(LLVMGetTypeKind(LLVMTypeOf(array_ptr)) == LLVMPointerTypeKind);
- assert(LLVMGetTypeKind(LLVMGetElementType(LLVMTypeOf(array_ptr))) == LLVMStructTypeKind);
const size_t gen_len_index = array_type->data.structure.fields[slice_len_index]->gen_index;
assert(gen_len_index != SIZE_MAX);
LLVMValueRef prev_end = nullptr;
if (!instruction->end || want_runtime_safety) {
- LLVMValueRef src_len_ptr = LLVMBuildStructGEP(g->builder, array_ptr, gen_len_index, "");
- prev_end = gen_load_untyped(g, src_len_ptr, 0, false, "");
+ LLVMValueRef src_len_ptr = LLVMBuildStructGEP2(g->builder,
+ get_llvm_type(g, array_type), array_ptr, gen_len_index, "");
+ prev_end = gen_load_untyped(g, ZigLLVMGetGEPResultElementType(src_len_ptr), src_len_ptr, 0, false, "");
}
LLVMValueRef start_val = ir_llvm_value(g, instruction->start);
@@ -6682,18 +6823,22 @@ static LLVMValueRef ir_render_slice(CodeGen *g, Stage1Air *executable, Stage1Air
codegen_report_errors_and_exit(g);
if (ptr_has_bits) {
+ LLVMTypeRef elem_llvm_ty = get_llvm_type(g, ptr_field_type->data.pointer.child_type);
const size_t gen_ptr_index = array_type->data.structure.fields[slice_ptr_index]->gen_index;
assert(gen_ptr_index != SIZE_MAX);
- LLVMValueRef src_ptr_ptr = LLVMBuildStructGEP(g->builder, array_ptr, gen_ptr_index, "");
- LLVMValueRef src_ptr = gen_load_untyped(g, src_ptr_ptr, 0, false, "");
+ LLVMValueRef src_ptr_ptr = LLVMBuildStructGEP2(g->builder,
+ get_llvm_type(g, array_type), array_ptr, gen_ptr_index, "");
+ LLVMValueRef src_ptr = gen_load_untyped(g, ZigLLVMGetGEPResultElementType(src_ptr_ptr),
+ src_ptr_ptr, 0, false, "");
if (sentinel != nullptr) {
- LLVMValueRef sentinel_elem_ptr = LLVMBuildInBoundsGEP(g->builder, src_ptr, &end_val, 1, "");
+ LLVMValueRef sentinel_elem_ptr = LLVMBuildInBoundsGEP2(g->builder, elem_llvm_ty,
+ src_ptr, &end_val, 1, "");
add_sentinel_check(g, sentinel_elem_ptr, sentinel);
}
- slice_start_ptr = LLVMBuildInBoundsGEP(g->builder, src_ptr, &start_val, 1, "");
+ slice_start_ptr = LLVMBuildInBoundsGEP2(g->builder, elem_llvm_ty, src_ptr, &start_val, 1, "");
}
len_value = LLVMBuildNUWSub(g->builder, end_val, start_val, "");
@@ -6735,7 +6880,8 @@ static LLVMValueRef ir_render_slice(CodeGen *g, Stage1Air *executable, Stage1Air
// The slice may not have a pointer at all if it points to a zero-sized type
const size_t gen_ptr_index = result_type->data.structure.fields[slice_ptr_index]->gen_index;
if (gen_ptr_index != SIZE_MAX) {
- LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, gen_ptr_index, "");
+ LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP2(g->builder,
+ get_llvm_type(g, result_type), tmp_struct_ptr, gen_ptr_index, "");
if (slice_start_ptr != nullptr) {
gen_store_untyped(g, slice_start_ptr, ptr_field_ptr, 0, false);
} else if (want_runtime_safety) {
@@ -6748,7 +6894,8 @@ static LLVMValueRef ir_render_slice(CodeGen *g, Stage1Air *executable, Stage1Air
const size_t gen_len_index = result_type->data.structure.fields[slice_len_index]->gen_index;
assert(gen_len_index != SIZE_MAX);
- LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, gen_len_index, "");
+ LLVMValueRef len_field_ptr = LLVMBuildStructGEP2(g->builder,
+ get_llvm_type(g, result_type), tmp_struct_ptr, gen_len_index, "");
gen_store_untyped(g, len_value, len_field_ptr, 0, false);
return tmp_struct_ptr;
@@ -6767,7 +6914,7 @@ static LLVMValueRef get_trap_fn_val(CodeGen *g) {
static LLVMValueRef ir_render_breakpoint(CodeGen *g, Stage1Air *executable, Stage1AirInstBreakpoint *instruction) {
- LLVMBuildCall(g->builder, get_trap_fn_val(g), nullptr, 0, "");
+ LLVMBuildCall2(g->builder, LLVMGlobalGetValueType(get_trap_fn_val(g)), get_trap_fn_val(g), nullptr, 0, "");
return nullptr;
}
@@ -6781,7 +6928,7 @@ static LLVMValueRef ir_render_return_address(CodeGen *g, Stage1Air *executable,
}
LLVMValueRef zero = LLVMConstNull(g->builtin_types.entry_i32->llvm_type);
- LLVMValueRef ptr_val = LLVMBuildCall(g->builder, get_return_address_fn_val(g), &zero, 1, "");
+ LLVMValueRef ptr_val = LLVMBuildCall2(g->builder, LLVMGlobalGetValueType(get_return_address_fn_val(g)), get_return_address_fn_val(g), &zero, 1, "");
return LLVMBuildPtrToInt(g->builder, ptr_val, g->builtin_types.entry_usize->llvm_type, "");
}
@@ -6793,7 +6940,7 @@ static LLVMValueRef get_frame_address_fn_val(CodeGen *g) {
LLVMTypeRef fn_type = LLVMFunctionType(get_llvm_type(g, return_type),
&g->builtin_types.entry_i32->llvm_type, 1, false);
- g->frame_address_fn_val = LLVMAddFunction(g->module, "llvm.frameaddress.p0i8", fn_type);
+ g->frame_address_fn_val = LLVMAddFunction(g->module, "llvm.frameaddress.p0", fn_type);
assert(LLVMGetIntrinsicID(g->frame_address_fn_val));
return g->frame_address_fn_val;
@@ -6803,7 +6950,7 @@ static LLVMValueRef ir_render_frame_address(CodeGen *g, Stage1Air *executable,
Stage1AirInstFrameAddress *instruction)
{
LLVMValueRef zero = LLVMConstNull(g->builtin_types.entry_i32->llvm_type);
- LLVMValueRef ptr_val = LLVMBuildCall(g->builder, get_frame_address_fn_val(g), &zero, 1, "");
+ LLVMValueRef ptr_val = LLVMBuildCall2(g->builder, LLVMGlobalGetValueType(get_frame_address_fn_val(g)), get_frame_address_fn_val(g), &zero, 1, "");
return LLVMBuildPtrToInt(g->builder, ptr_val, g->builtin_types.entry_usize->llvm_type, "");
}
@@ -6866,7 +7013,7 @@ static LLVMValueRef ir_render_overflow_op(CodeGen *g, Stage1Air *executable, Sta
op2,
};
- LLVMValueRef result_struct = LLVMBuildCall(g->builder, fn_val, params, 2, "");
+ LLVMValueRef result_struct = LLVMBuildCall2(g->builder, LLVMGlobalGetValueType(fn_val), fn_val, params, 2, "");
LLVMValueRef result = LLVMBuildExtractValue(g->builder, result_struct, 0, "");
LLVMValueRef overflow_bit = LLVMBuildExtractValue(g->builder, result_struct, 1, "");
gen_store(g, result, ptr_result, instruction->result_ptr->value->type);
@@ -6881,8 +7028,9 @@ static LLVMValueRef ir_render_test_err(CodeGen *g, Stage1Air *executable, Stage1
LLVMValueRef err_val;
if (type_has_bits(g, payload_type)) {
- LLVMValueRef err_val_ptr = LLVMBuildStructGEP(g->builder, err_union_handle, err_union_err_index, "");
- err_val = gen_load_untyped(g, err_val_ptr, 0, false, "");
+ LLVMValueRef err_val_ptr = LLVMBuildStructGEP2(g->builder,
+ get_llvm_type(g, err_union_type), err_union_handle, err_union_err_index, "");
+ err_val = gen_load_untyped(g, ZigLLVMGetGEPResultElementType(err_val_ptr), err_val_ptr, 0, false, "");
} else {
err_val = err_union_handle;
}
@@ -6907,7 +7055,8 @@ static LLVMValueRef ir_render_unwrap_err_code(CodeGen *g, Stage1Air *executable,
} else {
// TODO assign undef to the payload
LLVMValueRef err_union_handle = get_handle_value(g, err_union_ptr, err_union_type, ptr_type);
- return LLVMBuildStructGEP(g->builder, err_union_handle, err_union_err_index, "");
+ return LLVMBuildStructGEP2(g->builder, get_llvm_type(g, err_union_type), err_union_handle,
+ err_union_err_index, "");
}
}
@@ -6946,11 +7095,14 @@ static LLVMValueRef ir_render_unwrap_err_payload(CodeGen *g, Stage1Air *executab
return err_union_handle;
}
+ LLVMTypeRef err_union_llvm_ty = get_llvm_type(g, err_union_type);
+
if (want_safety) {
LLVMValueRef err_val;
if (type_has_bits(g, payload_type)) {
- LLVMValueRef err_val_ptr = LLVMBuildStructGEP(g->builder, err_union_handle, err_union_err_index, "");
- err_val = gen_load_untyped(g, err_val_ptr, 0, false, "");
+ LLVMValueRef err_val_ptr = LLVMBuildStructGEP2(g->builder, err_union_llvm_ty,
+ err_union_handle, err_union_err_index, "");
+ err_val = gen_load_untyped(g, ZigLLVMGetGEPResultElementType(err_val_ptr), err_val_ptr, 0, false, "");
} else {
err_val = err_union_handle;
}
@@ -6967,11 +7119,13 @@ static LLVMValueRef ir_render_unwrap_err_payload(CodeGen *g, Stage1Air *executab
if (type_has_bits(g, payload_type)) {
if (instruction->initializing) {
- LLVMValueRef err_tag_ptr = LLVMBuildStructGEP(g->builder, err_union_handle, err_union_err_index, "");
+ LLVMValueRef err_tag_ptr = LLVMBuildStructGEP2(g->builder, err_union_llvm_ty,
+ err_union_handle, err_union_err_index, "");
LLVMValueRef ok_err_val = LLVMConstNull(get_llvm_type(g, g->err_tag_type));
gen_store_untyped(g, ok_err_val, err_tag_ptr, 0, false);
}
- return LLVMBuildStructGEP(g->builder, err_union_handle, err_union_payload_index, "");
+ return LLVMBuildStructGEP2(g->builder, err_union_llvm_ty, err_union_handle,
+ err_union_payload_index, "");
} else {
if (instruction->initializing) {
gen_store_untyped(g, zero, err_union_ptr, 0, false);
@@ -7006,11 +7160,14 @@ static LLVMValueRef ir_render_optional_wrap(CodeGen *g, Stage1Air *executable, S
}
LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc);
+ LLVMTypeRef result_llvm_struct_ty = get_llvm_type(g, wanted_type);
- LLVMValueRef val_ptr = LLVMBuildStructGEP(g->builder, result_loc, maybe_child_index, "");
+ LLVMValueRef val_ptr = LLVMBuildStructGEP2(g->builder, result_llvm_struct_ty, result_loc,
+ maybe_child_index, "");
// child_type and instruction->value->value->type may differ by constness
gen_assign_raw(g, val_ptr, get_pointer_to_type(g, child_type, false), payload_val);
- LLVMValueRef maybe_ptr = LLVMBuildStructGEP(g->builder, result_loc, maybe_null_index, "");
+ LLVMValueRef maybe_ptr = LLVMBuildStructGEP2(g->builder, result_llvm_struct_ty, result_loc,
+ maybe_null_index, "");
gen_store_untyped(g, LLVMConstAllOnes(LLVMInt1Type()), maybe_ptr, 0, false);
return result_loc;
@@ -7028,7 +7185,8 @@ static LLVMValueRef ir_render_err_wrap_code(CodeGen *g, Stage1Air *executable, S
LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc);
- LLVMValueRef err_tag_ptr = LLVMBuildStructGEP(g->builder, result_loc, err_union_err_index, "");
+ LLVMValueRef err_tag_ptr = LLVMBuildStructGEP2(g->builder, get_llvm_type(g, wanted_type),
+ result_loc, err_union_err_index, "");
gen_store_untyped(g, err_val, err_tag_ptr, 0, false);
// TODO store undef to the payload
@@ -7057,11 +7215,14 @@ static LLVMValueRef ir_render_err_wrap_payload(CodeGen *g, Stage1Air *executable
LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc);
LLVMValueRef payload_val = ir_llvm_value(g, instruction->operand);
+ LLVMTypeRef result_struct_llvm_ty = get_llvm_type(g, wanted_type);
- LLVMValueRef err_tag_ptr = LLVMBuildStructGEP(g->builder, result_loc, err_union_err_index, "");
+ LLVMValueRef err_tag_ptr = LLVMBuildStructGEP2(g->builder, result_struct_llvm_ty, result_loc,
+ err_union_err_index, "");
gen_store_untyped(g, ok_err_val, err_tag_ptr, 0, false);
- LLVMValueRef payload_ptr = LLVMBuildStructGEP(g->builder, result_loc, err_union_payload_index, "");
+ LLVMValueRef payload_ptr = LLVMBuildStructGEP2(g->builder, result_struct_llvm_ty, result_loc,
+ err_union_payload_index, "");
gen_assign_raw(g, payload_ptr, get_pointer_to_type(g, payload_type, false), payload_val);
return result_loc;
@@ -7079,7 +7240,8 @@ static LLVMValueRef ir_render_union_tag(CodeGen *g, Stage1Air *executable, Stage
return union_val;
assert(union_type->data.unionation.gen_tag_index != SIZE_MAX);
- LLVMValueRef tag_field_ptr = LLVMBuildStructGEP(g->builder, union_val,
+ LLVMValueRef tag_field_ptr = LLVMBuildStructGEP2(g->builder,
+ get_llvm_type(g, union_type), union_val,
union_type->data.unionation.gen_tag_index, "");
ZigType *ptr_type = get_pointer_to_type(g, tag_type, false);
return get_handle_value(g, tag_field_ptr, tag_type, ptr_type);
@@ -7154,9 +7316,10 @@ static LLVMValueRef ir_render_atomic_load(CodeGen *g, Stage1Air *executable,
LLVMTypeRef actual_abi_type = get_atomic_abi_type(g, instruction->ptr, false);
if (actual_abi_type != nullptr) {
// operand needs widening and truncating
- ptr = LLVMBuildBitCast(g->builder, ptr,
- LLVMPointerType(actual_abi_type, 0), "");
- LLVMValueRef load_inst = gen_load(g, ptr, instruction->ptr->value->type, "");
+ ptr = LLVMBuildBitCast(g->builder, ptr, LLVMPointerType(actual_abi_type, 0), "");
+ LLVMValueRef load_inst = gen_load_untyped(g, actual_abi_type, ptr,
+ get_ptr_align(g, instruction->ptr->value->type),
+ instruction->ptr->value->type->data.pointer.is_volatile, "");
LLVMSetOrdering(load_inst, ordering);
return LLVMBuildTrunc(g->builder, load_inst, get_llvm_type(g, operand_type), "");
}
@@ -7221,14 +7384,12 @@ static LLVMValueRef ir_render_soft_mul_add(CodeGen *g, Stage1Air *executable, St
LLVMValueRef op1 = ir_llvm_value(g, instruction->op1);
LLVMValueRef op2 = ir_llvm_value(g, instruction->op2);
LLVMValueRef op3 = ir_llvm_value(g, instruction->op3);
- LLVMValueRef result;
if (vector_len == 0) {
LLVMValueRef params[3] = { op1, op2, op3 };
- result = LLVMBuildCall(g->builder, func_ref, params, 3, "");
- } else {
- result = build_alloca(g, instruction->op1->value->type, "", 0);
+ return LLVMBuildCall2(g->builder, LLVMGlobalGetValueType(func_ref), func_ref, params, 3, "");
}
+ LLVMValueRef result = LLVMGetUndef(get_llvm_type(g, instruction->op1->value->type));
LLVMTypeRef usize_ref = g->builtin_types.entry_usize->llvm_type;
for (uint32_t i = 0; i < vector_len; i++) {
LLVMValueRef index_value = LLVMConstInt(usize_ref, i, false);
@@ -7238,12 +7399,8 @@ static LLVMValueRef ir_render_soft_mul_add(CodeGen *g, Stage1Air *executable, St
LLVMBuildExtractElement(g->builder, op2, index_value, ""),
LLVMBuildExtractElement(g->builder, op3, index_value, ""),
};
- LLVMValueRef call_result = LLVMBuildCall(g->builder, func_ref, params, 3, "");
- LLVMBuildInsertElement(g->builder, LLVMBuildLoad(g->builder, result, ""),
- call_result, index_value, "");
- }
- if (vector_len != 0) {
- result = LLVMBuildLoad(g->builder, result, "");
+ LLVMValueRef call_result = LLVMBuildCall2(g->builder, LLVMGlobalGetValueType(func_ref), func_ref, params, 3, "");
+ result = LLVMBuildInsertElement(g->builder, result, call_result, index_value, "");
}
return result;
}
@@ -7262,7 +7419,7 @@ static LLVMValueRef ir_render_mul_add(CodeGen *g, Stage1Air *executable, Stage1A
instruction->base.value->type->id == ZigTypeIdVector);
LLVMValueRef fn_val = get_float_fn(g, instruction->base.value->type, ZigLLVMFnIdFMA, BuiltinFnIdMulAdd);
LLVMValueRef args[3] = { op1, op2, op3 };
- return LLVMBuildCall(g->builder, fn_val, args, 3, "");
+ return LLVMBuildCall2(g->builder, LLVMGlobalGetValueType(fn_val), fn_val, args, 3, "");
}
static LLVMValueRef ir_render_bswap(CodeGen *g, Stage1Air *executable, Stage1AirInstBswap *instruction) {
@@ -7273,7 +7430,7 @@ static LLVMValueRef ir_render_bswap(CodeGen *g, Stage1Air *executable, Stage1Air
assert(int_type->id == ZigTypeIdInt);
if (int_type->data.integral.bit_count % 16 == 0) {
LLVMValueRef fn_val = get_int_builtin_fn(g, expr_type, BuiltinFnIdBswap);
- return LLVMBuildCall(g->builder, fn_val, &op, 1, "");
+ return LLVMBuildCall2(g->builder, LLVMGlobalGetValueType(fn_val), fn_val, &op, 1, "");
}
// Not an even number of bytes, so we zext 1 byte, then bswap, shift right 1 byte, truncate
ZigType *extended_type = get_int_type(g, int_type->data.integral.is_signed,
@@ -7292,7 +7449,7 @@ static LLVMValueRef ir_render_bswap(CodeGen *g, Stage1Air *executable, Stage1Air
LLVMValueRef extended = LLVMBuildZExt(g->builder, op, get_llvm_type(g, extended_type), "");
// 00aabbcc
LLVMValueRef fn_val = get_int_builtin_fn(g, extended_type, BuiltinFnIdBswap);
- LLVMValueRef swapped = LLVMBuildCall(g->builder, fn_val, &extended, 1, "");
+ LLVMValueRef swapped = LLVMBuildCall2(g->builder, LLVMGlobalGetValueType(fn_val), fn_val, &extended, 1, "");
// ccbbaa00
LLVMValueRef shifted = ZigLLVMBuildLShrExact(g->builder, swapped, shift_amt, "");
// 00ccbbaa
@@ -7328,7 +7485,7 @@ static LLVMValueRef ir_render_bit_reverse(CodeGen *g, Stage1Air *executable, Sta
ZigType *int_type = instruction->base.value->type;
assert(int_type->id == ZigTypeIdInt);
LLVMValueRef fn_val = get_int_builtin_fn(g, instruction->base.value->type, BuiltinFnIdBitReverse);
- return LLVMBuildCall(g->builder, fn_val, &op, 1, "");
+ return LLVMBuildCall2(g->builder, LLVMGlobalGetValueType(fn_val), fn_val, &op, 1, "");
}
static LLVMValueRef ir_render_vector_to_array(CodeGen *g, Stage1Air *executable,
@@ -7353,11 +7510,12 @@ static LLVMValueRef ir_render_vector_to_array(CodeGen *g, Stage1Air *executable,
LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type;
LLVMTypeRef u32_type_ref = LLVMInt32Type();
LLVMValueRef zero = LLVMConstInt(usize_type_ref, 0, false);
+ LLVMTypeRef array_llvm_ty = get_llvm_type(g, array_type);
for (uintptr_t i = 0; i < instruction->vector->value->type->data.vector.len; i++) {
LLVMValueRef index_usize = LLVMConstInt(usize_type_ref, i, false);
LLVMValueRef index_u32 = LLVMConstInt(u32_type_ref, i, false);
LLVMValueRef indexes[] = { zero, index_usize };
- LLVMValueRef elem_ptr = LLVMBuildInBoundsGEP(g->builder, result_loc, indexes, 2, "");
+ LLVMValueRef elem_ptr = LLVMBuildInBoundsGEP2(g->builder, array_llvm_ty, result_loc, indexes, 2, "");
LLVMValueRef elem = LLVMBuildExtractElement(g->builder, vector, index_u32, "");
LLVMBuildStore(g->builder, elem, elem_ptr);
}
@@ -7376,13 +7534,13 @@ static LLVMValueRef ir_render_array_to_vector(CodeGen *g, Stage1Air *executable,
ZigType *elem_type = vector_type->data.vector.elem_type;
bool bitcast_ok = elem_type->size_in_bits == elem_type->abi_size * 8;
+ ZigType *array_type = instruction->array->value->type;
+ ir_assert(array_type->id == ZigTypeIdArray, &instruction->base);
if (bitcast_ok) {
LLVMValueRef casted_ptr = LLVMBuildBitCast(g->builder, array_ptr,
LLVMPointerType(vector_type_ref, 0), "");
- ZigType *array_type = instruction->array->value->type;
- assert(array_type->id == ZigTypeIdArray);
uint32_t alignment = get_abi_alignment(g, array_type->data.array.child_type);
- return gen_load_untyped(g, casted_ptr, alignment, false, "");
+ return gen_load_untyped(g, vector_type_ref, casted_ptr, alignment, false, "");
} else {
// If the ABI size of the element type is not evenly divisible by size_in_bits, a simple bitcast
// will not work, and we fall back to insertelement.
@@ -7390,12 +7548,15 @@ static LLVMValueRef ir_render_array_to_vector(CodeGen *g, Stage1Air *executable,
LLVMTypeRef u32_type_ref = LLVMInt32Type();
LLVMValueRef zero = LLVMConstInt(usize_type_ref, 0, false);
LLVMValueRef vector = LLVMGetUndef(vector_type_ref);
+ LLVMTypeRef array_llvm_ty = get_llvm_type(g, array_type);
+ LLVMTypeRef elem_llvm_ty = get_llvm_type(g, elem_type);
for (uintptr_t i = 0; i < instruction->base.value->type->data.vector.len; i++) {
LLVMValueRef index_usize = LLVMConstInt(usize_type_ref, i, false);
LLVMValueRef index_u32 = LLVMConstInt(u32_type_ref, i, false);
LLVMValueRef indexes[] = { zero, index_usize };
- LLVMValueRef elem_ptr = LLVMBuildInBoundsGEP(g->builder, array_ptr, indexes, 2, "");
- LLVMValueRef elem = LLVMBuildLoad(g->builder, elem_ptr, "");
+ LLVMValueRef elem_ptr = LLVMBuildInBoundsGEP2(g->builder, array_llvm_ty, array_ptr,
+ indexes, 2, "");
+ LLVMValueRef elem = LLVMBuildLoad2(g->builder, elem_llvm_ty, elem_ptr, "");
vector = LLVMBuildInsertElement(g->builder, vector, elem, index_u32, "");
}
return vector;
@@ -7461,14 +7622,16 @@ static LLVMValueRef ir_render_suspend_finish(CodeGen *g, Stage1Air *executable,
}
static LLVMValueRef gen_await_early_return(CodeGen *g, Stage1AirInst *source_instr,
- LLVMValueRef target_frame_ptr, ZigType *result_type, ZigType *ptr_result_type,
- LLVMValueRef result_loc, bool non_async)
+ LLVMTypeRef target_frame_struct_llvm_ty, LLVMValueRef target_frame_ptr,
+ ZigType *result_type, ZigType *ptr_result_type, LLVMValueRef result_loc, bool non_async)
{
LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type;
LLVMValueRef their_result_ptr = nullptr;
if (type_has_bits(g, result_type) && (non_async || result_loc != nullptr)) {
- LLVMValueRef their_result_ptr_ptr = LLVMBuildStructGEP(g->builder, target_frame_ptr, frame_ret_start, "");
- their_result_ptr = LLVMBuildLoad(g->builder, their_result_ptr_ptr, "");
+ LLVMValueRef their_result_ptr_ptr = LLVMBuildStructGEP2(g->builder,
+ target_frame_struct_llvm_ty, target_frame_ptr, frame_ret_start, "");
+ their_result_ptr = LLVMBuildLoad2(g->builder,
+ ZigLLVMGetGEPResultElementType(their_result_ptr_ptr), their_result_ptr_ptr, "");
if (result_loc != nullptr) {
LLVMTypeRef ptr_u8 = LLVMPointerType(LLVMInt8Type(), 0);
LLVMValueRef dest_ptr_casted = LLVMBuildBitCast(g->builder, result_loc, ptr_u8, "");
@@ -7482,13 +7645,16 @@ static LLVMValueRef gen_await_early_return(CodeGen *g, Stage1AirInst *source_ins
}
}
if (codegen_fn_has_err_ret_tracing_arg(g, result_type)) {
- LLVMValueRef their_trace_ptr_ptr = LLVMBuildStructGEP(g->builder, target_frame_ptr,
+ LLVMValueRef their_trace_ptr_ptr = LLVMBuildStructGEP2(g->builder,
+ target_frame_struct_llvm_ty, target_frame_ptr,
frame_index_trace_arg(g, result_type), "");
- LLVMValueRef src_trace_ptr = LLVMBuildLoad(g->builder, their_trace_ptr_ptr, "");
+ LLVMValueRef src_trace_ptr = LLVMBuildLoad2(g->builder,
+ ZigLLVMGetGEPResultElementType(their_trace_ptr_ptr), their_trace_ptr_ptr, "");
bool is_llvm_alloca;
LLVMValueRef dest_trace_ptr = get_cur_err_ret_trace_val(g, source_instr->scope, &is_llvm_alloca);
LLVMValueRef args[] = { dest_trace_ptr, src_trace_ptr };
- ZigLLVMBuildCall(g->builder, get_merge_err_ret_traces_fn_val(g), args, 2,
+ ZigLLVMBuildCall(g->builder, LLVMGlobalGetValueType(get_merge_err_ret_traces_fn_val(g)),
+ get_merge_err_ret_traces_fn_val(g), args, 2,
get_llvm_cc(g, CallingConventionUnspecified), ZigLLVM_CallAttrAuto, "");
}
if (non_async && type_has_bits(g, result_type)) {
@@ -7503,6 +7669,8 @@ static LLVMValueRef ir_render_await(CodeGen *g, Stage1Air *executable, Stage1Air
LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type;
LLVMValueRef zero = LLVMConstNull(usize_type_ref);
LLVMValueRef target_frame_ptr = ir_llvm_value(g, instruction->frame);
+ ir_assert(instruction->frame->value->type->id == ZigTypeIdAnyFrame, &instruction->base);
+ LLVMTypeRef target_frame_llvm_ty = instruction->frame->value->type->data.any_frame.struct_llvm_ty;
ZigType *result_type = instruction->base.value->type;
ZigType *ptr_result_type = get_pointer_to_type(g, result_type, true);
@@ -7512,8 +7680,8 @@ static LLVMValueRef ir_render_await(CodeGen *g, Stage1Air *executable, Stage1Air
if (instruction->is_nosuspend ||
(instruction->target_fn != nullptr && !fn_is_async(instruction->target_fn)))
{
- return gen_await_early_return(g, &instruction->base, target_frame_ptr, result_type,
- ptr_result_type, result_loc, true);
+ return gen_await_early_return(g, &instruction->base, target_frame_llvm_ty,
+ target_frame_ptr, result_type, ptr_result_type, result_loc, true);
}
// Prepare to be suspended
@@ -7525,10 +7693,11 @@ static LLVMValueRef ir_render_await(CodeGen *g, Stage1Air *executable, Stage1Air
// supply the awaiter return pointer
if (type_has_bits(g, result_type)) {
- LLVMValueRef awaiter_ret_ptr_ptr = LLVMBuildStructGEP(g->builder, target_frame_ptr, frame_ret_start + 1, "");
+ LLVMValueRef awaiter_ret_ptr_ptr = LLVMBuildStructGEP2(g->builder, target_frame_llvm_ty,
+ target_frame_ptr, frame_ret_start + 1, "");
if (result_loc == nullptr) {
// no copy needed
- LLVMBuildStore(g->builder, LLVMConstNull(LLVMGetElementType(LLVMTypeOf(awaiter_ret_ptr_ptr))),
+ LLVMBuildStore(g->builder, LLVMConstNull(ZigLLVMGetGEPResultElementType(awaiter_ret_ptr_ptr)),
awaiter_ret_ptr_ptr);
} else {
LLVMBuildStore(g->builder, result_loc, awaiter_ret_ptr_ptr);
@@ -7540,14 +7709,15 @@ static LLVMValueRef ir_render_await(CodeGen *g, Stage1Air *executable, Stage1Air
bool is_llvm_alloca;
LLVMValueRef my_err_ret_trace_val = get_cur_err_ret_trace_val(g, instruction->base.scope, &is_llvm_alloca);
assert(my_err_ret_trace_val != nullptr);
- LLVMValueRef err_ret_trace_ptr_ptr = LLVMBuildStructGEP(g->builder, target_frame_ptr,
- frame_index_trace_arg(g, result_type) + 1, "");
+ LLVMValueRef err_ret_trace_ptr_ptr = LLVMBuildStructGEP2(g->builder, target_frame_llvm_ty,
+ target_frame_ptr, frame_index_trace_arg(g, result_type) + 1, "");
LLVMBuildStore(g->builder, my_err_ret_trace_val, err_ret_trace_ptr_ptr);
}
// caller's own frame pointer
LLVMValueRef awaiter_init_val = LLVMBuildPtrToInt(g->builder, g->cur_frame_ptr, usize_type_ref, "");
- LLVMValueRef awaiter_ptr = LLVMBuildStructGEP(g->builder, target_frame_ptr, frame_awaiter_index, "");
+ LLVMValueRef awaiter_ptr = LLVMBuildStructGEP2(g->builder, target_frame_llvm_ty,
+ target_frame_ptr, frame_awaiter_index, "");
LLVMValueRef prev_val = gen_maybe_atomic_op(g, LLVMAtomicRMWBinOpXchg, awaiter_ptr, awaiter_init_val,
LLVMAtomicOrderingRelease);
@@ -7572,8 +7742,8 @@ static LLVMValueRef ir_render_await(CodeGen *g, Stage1Air *executable, Stage1Air
// Early return: The async function has already completed. We must copy the result and
// the error return trace if applicable.
LLVMPositionBuilderAtEnd(g->builder, early_return_block);
- gen_await_early_return(g, &instruction->base, target_frame_ptr, result_type, ptr_result_type,
- result_loc, false);
+ gen_await_early_return(g, &instruction->base, target_frame_llvm_ty, target_frame_ptr,
+ result_type, ptr_result_type, result_loc, false);
LLVMBuildBr(g->builder, end_bb);
LLVMPositionBuilderAtEnd(g->builder, resume_bb);
@@ -7591,7 +7761,7 @@ static LLVMValueRef ir_render_resume(CodeGen *g, Stage1Air *executable, Stage1Ai
ZigType *frame_type = instruction->frame->value->type;
assert(frame_type->id == ZigTypeIdAnyFrame);
- gen_resume(g, nullptr, frame, ResumeIdManual);
+ gen_resume(g, g->anyframe_fn_type, nullptr, frame, ResumeIdManual);
return nullptr;
}
@@ -7631,7 +7801,8 @@ static LLVMValueRef ir_render_spill_end(CodeGen *g, Stage1Air *executable, Stage
zig_unreachable();
case SpillIdRetErrCode: {
LLVMValueRef ptr = ir_llvm_value(g, g->cur_fn->err_code_spill);
- return LLVMBuildLoad(g->builder, ptr, "");
+ LLVMTypeRef llvm_ty = g->builtin_types.entry_global_error_set->llvm_type;
+ return LLVMBuildLoad2(g->builder, llvm_ty, ptr, "");
}
}
@@ -7923,43 +8094,33 @@ static LLVMValueRef gen_const_ptr_array_recursive(CodeGen *g, ZigValue *array_co
ConstParent *parent = &array_const_val->parent;
LLVMValueRef base_ptr = gen_parent_ptr(g, array_const_val, parent);
- LLVMTypeKind el_type = LLVMGetTypeKind(LLVMGetElementType(LLVMTypeOf(base_ptr)));
- if (el_type == LLVMArrayTypeKind) {
- ZigType *usize = g->builtin_types.entry_usize;
- LLVMValueRef indices[] = {
- LLVMConstNull(usize->llvm_type),
- LLVMConstInt(usize->llvm_type, index, false),
- };
- return LLVMConstInBoundsGEP(base_ptr, indices, 2);
- } else if (el_type == LLVMStructTypeKind) {
- ZigType *u32 = g->builtin_types.entry_u32;
- LLVMValueRef indices[] = {
- LLVMConstNull(get_llvm_type(g, u32)),
- LLVMConstInt(get_llvm_type(g, u32), index, false),
- };
- return LLVMConstInBoundsGEP(base_ptr, indices, 2);
- } else {
- return base_ptr;
- }
+ ZigType *usize = g->builtin_types.entry_usize;
+ LLVMTypeRef array_llvm_ty = get_llvm_type(g, array_const_val->type);
+ LLVMValueRef casted_base_ptr = LLVMConstBitCast(base_ptr, LLVMPointerType(array_llvm_ty, 0));
+ LLVMValueRef indices[] = {
+ LLVMConstNull(usize->llvm_type),
+ LLVMConstInt(usize->llvm_type, index, false),
+ };
+ return LLVMConstInBoundsGEP2(array_llvm_ty, casted_base_ptr, indices, 2);
}
static LLVMValueRef gen_const_ptr_struct_recursive(CodeGen *g, ZigValue *struct_const_val, size_t field_index) {
ConstParent *parent = &struct_const_val->parent;
LLVMValueRef base_ptr = gen_parent_ptr(g, struct_const_val, parent);
- ZigType *u32 = g->builtin_types.entry_u32;
LLVMValueRef indices[] = {
- LLVMConstNull(get_llvm_type(g, u32)),
- LLVMConstInt(get_llvm_type(g, u32), field_index, false),
+ LLVMConstNull(LLVMInt32Type()),
+ LLVMConstInt(LLVMInt32Type(), field_index, false),
};
// The structure pointed by base_ptr may include trailing padding for
// alignment purposes and have the following LLVM type: <{ %T, [N x i8] }>.
// Add an extra bitcast as we're only interested in the %T part.
assert(handle_is_ptr(g, struct_const_val->type));
- LLVMValueRef casted_base_ptr = LLVMConstBitCast(base_ptr,
- LLVMPointerType(get_llvm_type(g, struct_const_val->type), 0));
- return LLVMConstInBoundsGEP(casted_base_ptr, indices, 2);
+
+ LLVMTypeRef struct_llvm_ty = get_llvm_type(g, struct_const_val->type);
+ LLVMValueRef casted_base_ptr = LLVMConstBitCast(base_ptr, LLVMPointerType(struct_llvm_ty, 0));
+ return LLVMConstInBoundsGEP2(struct_llvm_ty, casted_base_ptr, indices, 2);
}
static LLVMValueRef gen_const_ptr_err_union_code_recursive(CodeGen *g, ZigValue *err_union_const_val) {
@@ -7971,7 +8132,7 @@ static LLVMValueRef gen_const_ptr_err_union_code_recursive(CodeGen *g, ZigValue
LLVMConstNull(get_llvm_type(g, u32)),
LLVMConstInt(get_llvm_type(g, u32), err_union_err_index, false),
};
- return LLVMConstInBoundsGEP(base_ptr, indices, 2);
+ return LLVMConstInBoundsGEP2(get_llvm_type(g, err_union_const_val->type), base_ptr, indices, 2);
}
static LLVMValueRef gen_const_ptr_err_union_payload_recursive(CodeGen *g, ZigValue *err_union_const_val) {
@@ -7983,7 +8144,7 @@ static LLVMValueRef gen_const_ptr_err_union_payload_recursive(CodeGen *g, ZigVal
LLVMConstNull(get_llvm_type(g, u32)),
LLVMConstInt(get_llvm_type(g, u32), err_union_payload_index, false),
};
- return LLVMConstInBoundsGEP(base_ptr, indices, 2);
+ return LLVMConstInBoundsGEP2(get_llvm_type(g, err_union_const_val->type), base_ptr, indices, 2);
}
static LLVMValueRef gen_const_ptr_optional_payload_recursive(CodeGen *g, ZigValue *optional_const_val) {
@@ -7995,7 +8156,7 @@ static LLVMValueRef gen_const_ptr_optional_payload_recursive(CodeGen *g, ZigValu
LLVMConstNull(get_llvm_type(g, u32)),
LLVMConstInt(get_llvm_type(g, u32), maybe_child_index, false),
};
- return LLVMConstInBoundsGEP(base_ptr, indices, 2);
+ return LLVMConstInBoundsGEP2(get_llvm_type(g, optional_const_val->type), base_ptr, indices, 2);
}
static LLVMValueRef gen_const_ptr_union_recursive(CodeGen *g, ZigValue *union_const_val) {
@@ -8012,7 +8173,7 @@ static LLVMValueRef gen_const_ptr_union_recursive(CodeGen *g, ZigValue *union_co
LLVMConstNull(get_llvm_type(g, u32)),
LLVMConstInt(get_llvm_type(g, u32), union_payload_index, false),
};
- return LLVMConstInBoundsGEP(base_ptr, indices, (union_payload_index != SIZE_MAX) ? 2 : 1);
+ return LLVMConstInBoundsGEP2(get_llvm_type(g, union_const_val->type), base_ptr, indices, (union_payload_index != SIZE_MAX) ? 2 : 1);
}
static LLVMValueRef pack_const_int(CodeGen *g, LLVMTypeRef big_int_type_ref, ZigValue *const_val) {
@@ -9206,28 +9367,38 @@ static void do_code_gen(CodeGen *g) {
}
}
+ LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type;
+
// finishing error return trace setup. we have to do this after all the allocas.
if (have_err_ret_trace_stack) {
ZigType *usize = g->builtin_types.entry_usize;
size_t index_field_index = g->stack_trace_type->data.structure.fields[0]->gen_index;
- LLVMValueRef index_field_ptr = LLVMBuildStructGEP(g->builder, g->cur_err_ret_trace_val_stack, (unsigned)index_field_index, "");
+ LLVMValueRef index_field_ptr = LLVMBuildStructGEP2(g->builder,
+ get_llvm_type(g, g->stack_trace_type),
+ g->cur_err_ret_trace_val_stack, (unsigned)index_field_index, "");
gen_store_untyped(g, LLVMConstNull(usize->llvm_type), index_field_ptr, 0, false);
size_t addresses_field_index = g->stack_trace_type->data.structure.fields[1]->gen_index;
- LLVMValueRef addresses_field_ptr = LLVMBuildStructGEP(g->builder, g->cur_err_ret_trace_val_stack, (unsigned)addresses_field_index, "");
+ LLVMValueRef addresses_field_ptr = LLVMBuildStructGEP2(g->builder,
+ get_llvm_type(g, g->stack_trace_type),
+ g->cur_err_ret_trace_val_stack, (unsigned)addresses_field_index, "");
ZigType *slice_type = g->stack_trace_type->data.structure.fields[1]->type_entry;
size_t ptr_field_index = slice_type->data.structure.fields[slice_ptr_index]->gen_index;
- LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, addresses_field_ptr, (unsigned)ptr_field_index, "");
+ LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP2(g->builder,
+ ZigLLVMGetGEPResultElementType(addresses_field_ptr),
+ addresses_field_ptr, (unsigned)ptr_field_index, "");
LLVMValueRef zero = LLVMConstNull(usize->llvm_type);
LLVMValueRef indices[] = {zero, zero};
- LLVMValueRef err_ret_array_val_elem0_ptr = LLVMBuildInBoundsGEP(g->builder, err_ret_array_val,
- indices, 2, "");
+ LLVMValueRef err_ret_array_val_elem0_ptr = LLVMBuildInBoundsGEP2(g->builder,
+ LLVMGetAllocatedType(err_ret_array_val), err_ret_array_val, indices, 2, "");
ZigType *ptr_ptr_usize_type = get_pointer_to_type(g, get_pointer_to_type(g, usize, false), false);
gen_store(g, err_ret_array_val_elem0_ptr, ptr_field_ptr, ptr_ptr_usize_type);
size_t len_field_index = slice_type->data.structure.fields[slice_len_index]->gen_index;
- LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, addresses_field_ptr, (unsigned)len_field_index, "");
+ LLVMValueRef len_field_ptr = LLVMBuildStructGEP2(g->builder,
+ ZigLLVMGetGEPResultElementType(addresses_field_ptr),
+ addresses_field_ptr, (unsigned)len_field_index, "");
gen_store(g, LLVMConstInt(usize->llvm_type, stack_trace_ptr_count, false), len_field_ptr, get_pointer_to_type(g, usize, false));
}
@@ -9235,7 +9406,6 @@ static void do_code_gen(CodeGen *g) {
(void)get_llvm_type(g, fn_table_entry->frame_type);
g->cur_resume_block_count = 0;
- LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type;
LLVMValueRef size_val = LLVMConstInt(usize_type_ref, fn_table_entry->frame_type->abi_size, false);
if (g->need_frame_size_prefix_data) {
ZigLLVMFunctionSetPrefixData(fn_table_entry->llvm_value, size_val);
@@ -9254,22 +9424,31 @@ static void do_code_gen(CodeGen *g) {
LLVMPositionBuilderAtEnd(g->builder, g->cur_preamble_llvm_block);
render_async_spills(g);
- g->cur_async_awaiter_ptr = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr, frame_awaiter_index, "");
- LLVMValueRef resume_index_ptr = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr, frame_resume_index, "");
+ g->cur_async_awaiter_ptr = LLVMBuildStructGEP2(g->builder,
+ get_llvm_type(g, get_fn_frame_type(g, g->cur_fn)),
+ g->cur_frame_ptr, frame_awaiter_index, "");
+ LLVMValueRef resume_index_ptr = LLVMBuildStructGEP2(g->builder,
+ get_llvm_type(g, get_fn_frame_type(g, g->cur_fn)),
+ g->cur_frame_ptr, frame_resume_index, "");
g->cur_async_resume_index_ptr = resume_index_ptr;
if (type_has_bits(g, fn_type_id->return_type)) {
- LLVMValueRef cur_ret_ptr_ptr = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr, frame_ret_start, "");
- g->cur_ret_ptr = LLVMBuildLoad(g->builder, cur_ret_ptr_ptr, "");
+ LLVMValueRef cur_ret_ptr_ptr = LLVMBuildStructGEP2(g->builder,
+ get_llvm_type(g, get_fn_frame_type(g, g->cur_fn)),
+ g->cur_frame_ptr, frame_ret_start, "");
+ g->cur_ret_ptr = LLVMBuildLoad2(g->builder,
+ ZigLLVMGetGEPResultElementType(cur_ret_ptr_ptr), cur_ret_ptr_ptr, "");
}
uint32_t trace_field_index_stack = UINT32_MAX;
if (codegen_fn_has_err_ret_tracing_stack(g, fn_table_entry, true)) {
trace_field_index_stack = frame_index_trace_stack(g, fn_table_entry);
- g->cur_err_ret_trace_val_stack = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr,
+ g->cur_err_ret_trace_val_stack = LLVMBuildStructGEP2(g->builder,
+ get_llvm_type(g, get_fn_frame_type(g, g->cur_fn)),
+ g->cur_frame_ptr,
trace_field_index_stack, "");
}
- LLVMValueRef resume_index = LLVMBuildLoad(g->builder, resume_index_ptr, "");
+ LLVMValueRef resume_index = LLVMBuildLoad2(g->builder, usize_type_ref, resume_index_ptr, "");
LLVMValueRef switch_instr = LLVMBuildSwitch(g->builder, resume_index, bad_resume_block, 4);
g->cur_async_switch_instr = switch_instr;
@@ -9293,15 +9472,21 @@ static void do_code_gen(CodeGen *g) {
LLVMBuildStore(g->builder, g->cur_bad_not_suspended_index, g->cur_async_resume_index_ptr);
if (trace_field_index_stack != UINT32_MAX) {
if (codegen_fn_has_err_ret_tracing_arg(g, fn_type_id->return_type)) {
- LLVMValueRef trace_ptr_ptr = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr,
+ LLVMValueRef trace_ptr_ptr = LLVMBuildStructGEP2(g->builder,
+ get_llvm_type(g, get_fn_frame_type(g, g->cur_fn)),
+ g->cur_frame_ptr,
frame_index_trace_arg(g, fn_type_id->return_type), "");
- LLVMValueRef zero_ptr = LLVMConstNull(LLVMGetElementType(LLVMTypeOf(trace_ptr_ptr)));
+ LLVMValueRef zero_ptr = LLVMConstNull(ZigLLVMGetGEPResultElementType(trace_ptr_ptr));
LLVMBuildStore(g->builder, zero_ptr, trace_ptr_ptr);
}
- LLVMValueRef trace_field_ptr = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr,
+ LLVMValueRef trace_field_ptr = LLVMBuildStructGEP2(g->builder,
+ get_llvm_type(g, get_fn_frame_type(g, g->cur_fn)),
+ g->cur_frame_ptr,
trace_field_index_stack, "");
- LLVMValueRef addrs_field_ptr = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr,
+ LLVMValueRef addrs_field_ptr = LLVMBuildStructGEP2(g->builder,
+ get_llvm_type(g, get_fn_frame_type(g, g->cur_fn)),
+ g->cur_frame_ptr,
trace_field_index_stack + 1, "");
gen_init_stack_trace(g, trace_field_ptr, addrs_field_ptr);
diff --git a/src/stage1/stage1.h b/src/stage1/stage1.h
index 26b36db879..c8af8b9688 100644
--- a/src/stage1/stage1.h
+++ b/src/stage1/stage1.h
@@ -83,9 +83,11 @@ enum Os {
OsNVCL, // NVIDIA OpenCL
OsAMDHSA, // AMD HSA Runtime
OsPS4,
+ OsPS5,
OsELFIAMCU,
OsTvOS, // Apple tvOS
OsWatchOS, // Apple watchOS
+ OsDriverKit, // Apple DriverKit
OsMesa3D,
OsContiki,
OsAMDPAL,
@@ -93,6 +95,7 @@ enum Os {
OsHurd,
OsWASI,
OsEmscripten,
+ OsShaderModel, // DirectX ShaderModel
OsUefi,
OsOpenCL,
OsGLSL450,
diff --git a/src/stage1/target.cpp b/src/stage1/target.cpp
index 7c4587cdaa..3031b7e588 100644
--- a/src/stage1/target.cpp
+++ b/src/stage1/target.cpp
@@ -24,7 +24,10 @@ static const ZigLLVM_ArchType arch_list[] = {
ZigLLVM_bpfel, // eBPF or extended BPF or 64-bit BPF (little endian)
ZigLLVM_bpfeb, // eBPF or extended BPF or 64-bit BPF (big endian)
ZigLLVM_csky, // CSKY: csky
+ ZigLLVM_dxil, // DXIL 32-bit DirectX bytecode
ZigLLVM_hexagon, // Hexagon: hexagon
+ ZigLLVM_loongarch32, // LoongArch (32-bit): loongarch32
+ ZigLLVM_loongarch64, // LoongArch (64-bit): loongarch64
ZigLLVM_m68k, // M68k: Motorola 680x0 family
ZigLLVM_mips, // MIPS: mips, mipsallegrex, mipsr6
ZigLLVM_mipsel, // MIPSEL: mipsel, mipsallegrexe, mipsr6el
@@ -114,9 +117,11 @@ static const Os os_list[] = {
OsNVCL, // NVIDIA OpenCL
OsAMDHSA, // AMD HSA Runtime
OsPS4,
+ OsPS5,
OsELFIAMCU,
OsTvOS, // Apple tvOS
OsWatchOS, // Apple watchOS
+ OsDriverKit, // Apple DriverKit
OsMesa3D,
OsContiki,
OsAMDPAL,
@@ -124,6 +129,7 @@ static const Os os_list[] = {
OsHurd,
OsWASI,
OsEmscripten,
+ OsShaderModel, // DirectX ShaderModel
OsUefi,
OsOpenCL,
OsGLSL450,
@@ -156,16 +162,34 @@ static const ZigLLVM_EnvironmentType abi_list[] = {
ZigLLVM_Itanium,
ZigLLVM_Cygnus,
ZigLLVM_CoreCLR,
- ZigLLVM_Simulator,
- ZigLLVM_MacABI,
+ ZigLLVM_Simulator, // Simulator variants of other systems, e.g., Apple's iOS
+ ZigLLVM_MacABI, // Mac Catalyst variant of Apple's iOS deployment target.
+
+ ZigLLVM_Pixel,
+ ZigLLVM_Vertex,
+ ZigLLVM_Geometry,
+ ZigLLVM_Hull,
+ ZigLLVM_Domain,
+ ZigLLVM_Compute,
+ ZigLLVM_Library,
+ ZigLLVM_RayGeneration,
+ ZigLLVM_Intersection,
+ ZigLLVM_AnyHit,
+ ZigLLVM_ClosestHit,
+ ZigLLVM_Miss,
+ ZigLLVM_Callable,
+ ZigLLVM_Mesh,
+ ZigLLVM_Amplification,
};
static const ZigLLVM_ObjectFormatType oformat_list[] = {
ZigLLVM_UnknownObjectFormat,
ZigLLVM_COFF,
+ ZigLLVM_DXContainer,
ZigLLVM_ELF,
ZigLLVM_GOFF,
ZigLLVM_MachO,
+ ZigLLVM_SPIRV,
ZigLLVM_Wasm,
ZigLLVM_XCOFF,
};
@@ -183,9 +207,11 @@ const char *target_oformat_name(ZigLLVM_ObjectFormatType oformat) {
switch (oformat) {
case ZigLLVM_UnknownObjectFormat: return "unknown";
case ZigLLVM_COFF: return "coff";
+ case ZigLLVM_DXContainer: return "dxcontainer";
case ZigLLVM_ELF: return "elf";
case ZigLLVM_GOFF: return "goff";
case ZigLLVM_MachO: return "macho";
+ case ZigLLVM_SPIRV: return "spirv";
case ZigLLVM_Wasm: return "wasm";
case ZigLLVM_XCOFF: return "xcoff";
}
@@ -276,12 +302,16 @@ ZigLLVM_OSType get_llvm_os_type(Os os_type) {
return ZigLLVM_AMDHSA;
case OsPS4:
return ZigLLVM_PS4;
+ case OsPS5:
+ return ZigLLVM_PS5;
case OsELFIAMCU:
return ZigLLVM_ELFIAMCU;
case OsTvOS:
return ZigLLVM_TvOS;
case OsWatchOS:
return ZigLLVM_WatchOS;
+ case OsDriverKit:
+ return ZigLLVM_DriverKit;
case OsMesa3D:
return ZigLLVM_Mesa3D;
case OsContiki:
@@ -296,6 +326,8 @@ ZigLLVM_OSType get_llvm_os_type(Os os_type) {
return ZigLLVM_WASI;
case OsEmscripten:
return ZigLLVM_Emscripten;
+ case OsShaderModel:
+ return ZigLLVM_ShaderModel;
}
zig_unreachable();
}
@@ -334,9 +366,11 @@ const char *target_os_name(Os os_type) {
case OsNVCL: // NVIDIA OpenCL
case OsAMDHSA: // AMD HSA Runtime
case OsPS4:
+ case OsPS5:
case OsELFIAMCU:
case OsTvOS: // Apple tvOS
case OsWatchOS: // Apple watchOS
+ case OsDriverKit:
case OsMesa3D:
case OsContiki:
case OsAMDPAL:
@@ -344,6 +378,7 @@ const char *target_os_name(Os os_type) {
case OsHurd:
case OsWASI:
case OsEmscripten:
+ case OsShaderModel:
case OsOpenCL:
case OsGLSL450:
case OsVulkan:
@@ -532,6 +567,8 @@ uint32_t target_arch_pointer_bit_width(ZigLLVM_ArchType arch) {
case ZigLLVM_aarch64_32:
case ZigLLVM_csky:
case ZigLLVM_spirv32:
+ case ZigLLVM_loongarch32:
+ case ZigLLVM_dxil:
return 32;
case ZigLLVM_aarch64:
@@ -556,6 +593,7 @@ uint32_t target_arch_pointer_bit_width(ZigLLVM_ArchType arch) {
case ZigLLVM_renderscript64:
case ZigLLVM_ve:
case ZigLLVM_spirv64:
+ case ZigLLVM_loongarch64:
return 64;
}
zig_unreachable();
@@ -601,6 +639,8 @@ uint32_t target_arch_largest_atomic_bits(ZigLLVM_ArchType arch) {
case ZigLLVM_renderscript32:
case ZigLLVM_csky:
case ZigLLVM_spirv32:
+ case ZigLLVM_loongarch32:
+ case ZigLLVM_dxil:
return 32;
case ZigLLVM_aarch64:
@@ -625,6 +665,7 @@ uint32_t target_arch_largest_atomic_bits(ZigLLVM_ArchType arch) {
case ZigLLVM_renderscript64:
case ZigLLVM_ve:
case ZigLLVM_spirv64:
+ case ZigLLVM_loongarch64:
return 64;
case ZigLLVM_x86_64:
@@ -751,6 +792,7 @@ uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id) {
case OsAIX:
case OsAMDHSA:
case OsPS4:
+ case OsPS5:
case OsELFIAMCU:
case OsTvOS:
case OsWatchOS:
@@ -763,6 +805,8 @@ uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id) {
case OsOpenCL:
case OsGLSL450:
case OsVulkan:
+ case OsDriverKit:
+ case OsShaderModel:
zig_panic("TODO c type size in bits for this target");
}
zig_unreachable();
@@ -860,6 +904,9 @@ const char *arch_stack_pointer_register_name(ZigLLVM_ArchType arch) {
case ZigLLVM_tcele:
case ZigLLVM_xcore:
case ZigLLVM_ve:
+ case ZigLLVM_dxil:
+ case ZigLLVM_loongarch32:
+ case ZigLLVM_loongarch64:
zig_panic("TODO populate this table with stack pointer register name for this CPU architecture");
}
zig_unreachable();
@@ -927,6 +974,9 @@ bool target_is_arm(const ZigTarget *target) {
case ZigLLVM_ve:
case ZigLLVM_spirv32:
case ZigLLVM_spirv64:
+ case ZigLLVM_dxil:
+ case ZigLLVM_loongarch32:
+ case ZigLLVM_loongarch64:
return false;
}
zig_unreachable();
@@ -973,6 +1023,7 @@ ZigLLVM_EnvironmentType target_default_abi(ZigLLVM_ArchType arch, Os os) {
case OsNVCL:
case OsAMDHSA:
case OsPS4:
+ case OsPS5:
case OsELFIAMCU:
case OsMesa3D:
case OsContiki:
@@ -1004,6 +1055,8 @@ ZigLLVM_EnvironmentType target_default_abi(ZigLLVM_ArchType arch, Os os) {
case OsIOS:
case OsTvOS:
case OsWatchOS:
+ case OsDriverKit:
+ case OsShaderModel:
return ZigLLVM_UnknownEnvironment;
}
zig_unreachable();
diff --git a/src/stage1/zig0.cpp b/src/stage1/zig0.cpp
index f248f6e866..ea0c397243 100644
--- a/src/stage1/zig0.cpp
+++ b/src/stage1/zig0.cpp
@@ -112,6 +112,8 @@ static Os get_zig_os_type(ZigLLVM_OSType os_type) {
return OsAMDHSA;
case ZigLLVM_PS4:
return OsPS4;
+ case ZigLLVM_PS5:
+ return OsPS5;
case ZigLLVM_ELFIAMCU:
return OsELFIAMCU;
case ZigLLVM_TvOS:
@@ -132,6 +134,10 @@ static Os get_zig_os_type(ZigLLVM_OSType os_type) {
return OsWASI;
case ZigLLVM_Emscripten:
return OsEmscripten;
+ case ZigLLVM_DriverKit:
+ return OsDriverKit;
+ case ZigLLVM_ShaderModel:
+ return OsShaderModel;
}
zig_unreachable();
}
diff --git a/src/target.zig b/src/target.zig
index f8b44bac0e..b7da04e548 100644
--- a/src/target.zig
+++ b/src/target.zig
@@ -106,6 +106,23 @@ pub fn libCGenericName(target: std.Target) [:0]const u8 {
.simulator,
.macabi,
=> unreachable,
+
+ .pixel,
+ .vertex,
+ .geometry,
+ .hull,
+ .domain,
+ .compute,
+ .library,
+ .raygeneration,
+ .intersection,
+ .anyhit,
+ .closesthit,
+ .miss,
+ .callable,
+ .mesh,
+ .amplification,
+ => unreachable,
}
}
@@ -218,6 +235,7 @@ pub fn hasLlvmSupport(target: std.Target, ofmt: std.Target.ObjectFormat) bool {
.hex,
.raw,
.nvptx,
+ .dxcontainer,
=> {},
}
@@ -232,7 +250,10 @@ pub fn hasLlvmSupport(target: std.Target, ofmt: std.Target.ObjectFormat) bool {
.bpfel,
.bpfeb,
.csky,
+ .dxil,
.hexagon,
+ .loongarch32,
+ .loongarch64,
.m68k,
.mips,
.mipsel,
@@ -535,6 +556,8 @@ pub fn atomicPtrAlignment(
.renderscript32,
.csky,
.spirv32,
+ .dxil,
+ .loongarch32,
=> 32,
.aarch64,
@@ -559,6 +582,7 @@ pub fn atomicPtrAlignment(
.renderscript64,
.ve,
.spirv64,
+ .loongarch64,
=> 64,
.x86_64 => 128,
diff --git a/src/type.zig b/src/type.zig
index c72cf2be84..3e2e395d07 100644
--- a/src/type.zig
+++ b/src/type.zig
@@ -6280,6 +6280,11 @@ pub const Type = extern union {
mutable: bool = true, // TODO rename this to const, not mutable
@"volatile": bool = false,
size: std.builtin.Type.Pointer.Size = .One,
+
+ pub fn alignment(data: Data, target: Target) u32 {
+ if (data.@"align" != 0) return data.@"align";
+ return abiAlignment(data.pointee_type, target);
+ }
};
};
@@ -6696,6 +6701,7 @@ pub const CType = enum {
.nvcl,
.amdhsa,
.ps4,
+ .ps5,
.elfiamcu,
.mesa3d,
.contiki,
@@ -6705,6 +6711,8 @@ pub const CType = enum {
.opencl,
.glsl450,
.vulkan,
+ .driverkit,
+ .shadermodel,
=> @panic("TODO specify the C integer and float type sizes for this OS"),
}
}
diff --git a/src/zig_clang.cpp b/src/zig_clang.cpp
index 7b79f8e985..223dc29067 100644
--- a/src/zig_clang.cpp
+++ b/src/zig_clang.cpp
@@ -317,6 +317,7 @@ void ZigClang_detect_enum_TypeClass(clang::Type::TypeClass ty) {
case clang::Type::Enum:
case clang::Type::Elaborated:
case clang::Type::Attributed:
+ case clang::Type::BTFTagAttributed:
case clang::Type::BitInt:
case clang::Type::TemplateTypeParm:
case clang::Type::SubstTemplateTypeParm:
@@ -346,6 +347,7 @@ static_assert((clang::Type::TypeClass)ZigClangType_IncompleteArray == clang::Typ
static_assert((clang::Type::TypeClass)ZigClangType_VariableArray == clang::Type::VariableArray, "");
static_assert((clang::Type::TypeClass)ZigClangType_Atomic == clang::Type::Atomic, "");
static_assert((clang::Type::TypeClass)ZigClangType_Attributed == clang::Type::Attributed, "");
+static_assert((clang::Type::TypeClass)ZigClangType_BTFTagAttributed == clang::Type::BTFTagAttributed, "");
static_assert((clang::Type::TypeClass)ZigClangType_BitInt == clang::Type::BitInt, "");
static_assert((clang::Type::TypeClass)ZigClangType_BlockPointer == clang::Type::BlockPointer, "");
static_assert((clang::Type::TypeClass)ZigClangType_Builtin == clang::Type::Builtin, "");
@@ -432,25 +434,33 @@ void ZigClang_detect_enum_StmtClass(clang::Stmt::StmtClass x) {
case clang::Stmt::OMPForDirectiveClass:
case clang::Stmt::OMPForSimdDirectiveClass:
case clang::Stmt::OMPGenericLoopDirectiveClass:
+ case clang::Stmt::OMPMaskedTaskLoopDirectiveClass:
+ case clang::Stmt::OMPMaskedTaskLoopSimdDirectiveClass:
case clang::Stmt::OMPMasterTaskLoopDirectiveClass:
case clang::Stmt::OMPMasterTaskLoopSimdDirectiveClass:
case clang::Stmt::OMPParallelForDirectiveClass:
case clang::Stmt::OMPParallelForSimdDirectiveClass:
+ case clang::Stmt::OMPParallelGenericLoopDirectiveClass:
+ case clang::Stmt::OMPParallelMaskedTaskLoopDirectiveClass:
+ case clang::Stmt::OMPParallelMaskedTaskLoopSimdDirectiveClass:
case clang::Stmt::OMPParallelMasterTaskLoopDirectiveClass:
case clang::Stmt::OMPParallelMasterTaskLoopSimdDirectiveClass:
case clang::Stmt::OMPSimdDirectiveClass:
case clang::Stmt::OMPTargetParallelForSimdDirectiveClass:
+ case clang::Stmt::OMPTargetParallelGenericLoopDirectiveClass:
case clang::Stmt::OMPTargetSimdDirectiveClass:
case clang::Stmt::OMPTargetTeamsDistributeDirectiveClass:
case clang::Stmt::OMPTargetTeamsDistributeParallelForDirectiveClass:
case clang::Stmt::OMPTargetTeamsDistributeParallelForSimdDirectiveClass:
case clang::Stmt::OMPTargetTeamsDistributeSimdDirectiveClass:
+ case clang::Stmt::OMPTargetTeamsGenericLoopDirectiveClass:
case clang::Stmt::OMPTaskLoopDirectiveClass:
case clang::Stmt::OMPTaskLoopSimdDirectiveClass:
case clang::Stmt::OMPTeamsDistributeDirectiveClass:
case clang::Stmt::OMPTeamsDistributeParallelForDirectiveClass:
case clang::Stmt::OMPTeamsDistributeParallelForSimdDirectiveClass:
case clang::Stmt::OMPTeamsDistributeSimdDirectiveClass:
+ case clang::Stmt::OMPTeamsGenericLoopDirectiveClass:
case clang::Stmt::OMPTileDirectiveClass:
case clang::Stmt::OMPUnrollDirectiveClass:
case clang::Stmt::OMPMaskedDirectiveClass:
@@ -458,6 +468,7 @@ void ZigClang_detect_enum_StmtClass(clang::Stmt::StmtClass x) {
case clang::Stmt::OMPMetaDirectiveClass:
case clang::Stmt::OMPOrderedDirectiveClass:
case clang::Stmt::OMPParallelDirectiveClass:
+ case clang::Stmt::OMPParallelMaskedDirectiveClass:
case clang::Stmt::OMPParallelMasterDirectiveClass:
case clang::Stmt::OMPParallelSectionsDirectiveClass:
case clang::Stmt::OMPScanDirectiveClass:
@@ -659,25 +670,33 @@ static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPDistributeSimdDirectiveCla
static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPForDirectiveClass == clang::Stmt::OMPForDirectiveClass, "");
static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPForSimdDirectiveClass == clang::Stmt::OMPForSimdDirectiveClass, "");
static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPGenericLoopDirectiveClass == clang::Stmt::OMPGenericLoopDirectiveClass, "");
+static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPMaskedTaskLoopDirectiveClass == clang::Stmt::OMPMaskedTaskLoopDirectiveClass, "");
+static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPMaskedTaskLoopSimdDirectiveClass == clang::Stmt::OMPMaskedTaskLoopSimdDirectiveClass, "");
static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPMasterTaskLoopDirectiveClass == clang::Stmt::OMPMasterTaskLoopDirectiveClass, "");
static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPMasterTaskLoopSimdDirectiveClass == clang::Stmt::OMPMasterTaskLoopSimdDirectiveClass, "");
static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPParallelForDirectiveClass == clang::Stmt::OMPParallelForDirectiveClass, "");
static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPParallelForSimdDirectiveClass == clang::Stmt::OMPParallelForSimdDirectiveClass, "");
+static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPParallelGenericLoopDirectiveClass == clang::Stmt::OMPParallelGenericLoopDirectiveClass, "");
+static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPParallelMaskedTaskLoopDirectiveClass == clang::Stmt::OMPParallelMaskedTaskLoopDirectiveClass, "");
+static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPParallelMaskedTaskLoopSimdDirectiveClass == clang::Stmt::OMPParallelMaskedTaskLoopSimdDirectiveClass, "");
static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPParallelMasterTaskLoopDirectiveClass == clang::Stmt::OMPParallelMasterTaskLoopDirectiveClass, "");
static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPParallelMasterTaskLoopSimdDirectiveClass == clang::Stmt::OMPParallelMasterTaskLoopSimdDirectiveClass, "");
static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPSimdDirectiveClass == clang::Stmt::OMPSimdDirectiveClass, "");
static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPTargetParallelForSimdDirectiveClass == clang::Stmt::OMPTargetParallelForSimdDirectiveClass, "");
+static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPTargetParallelGenericLoopDirectiveClass == clang::Stmt::OMPTargetParallelGenericLoopDirectiveClass, "");
static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPTargetSimdDirectiveClass == clang::Stmt::OMPTargetSimdDirectiveClass, "");
static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPTargetTeamsDistributeDirectiveClass == clang::Stmt::OMPTargetTeamsDistributeDirectiveClass, "");
static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPTargetTeamsDistributeParallelForDirectiveClass == clang::Stmt::OMPTargetTeamsDistributeParallelForDirectiveClass, "");
static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPTargetTeamsDistributeParallelForSimdDirectiveClass == clang::Stmt::OMPTargetTeamsDistributeParallelForSimdDirectiveClass, "");
static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPTargetTeamsDistributeSimdDirectiveClass == clang::Stmt::OMPTargetTeamsDistributeSimdDirectiveClass, "");
+static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPTargetTeamsGenericLoopDirectiveClass == clang::Stmt::OMPTargetTeamsGenericLoopDirectiveClass, "");
static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPTaskLoopDirectiveClass == clang::Stmt::OMPTaskLoopDirectiveClass, "");
static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPTaskLoopSimdDirectiveClass == clang::Stmt::OMPTaskLoopSimdDirectiveClass, "");
static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPTeamsDistributeDirectiveClass == clang::Stmt::OMPTeamsDistributeDirectiveClass, "");
static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPTeamsDistributeParallelForDirectiveClass == clang::Stmt::OMPTeamsDistributeParallelForDirectiveClass, "");
static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPTeamsDistributeParallelForSimdDirectiveClass == clang::Stmt::OMPTeamsDistributeParallelForSimdDirectiveClass, "");
static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPTeamsDistributeSimdDirectiveClass == clang::Stmt::OMPTeamsDistributeSimdDirectiveClass, "");
+static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPTeamsGenericLoopDirectiveClass == clang::Stmt::OMPTeamsGenericLoopDirectiveClass, "");
static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPTileDirectiveClass == clang::Stmt::OMPTileDirectiveClass, "");
static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPUnrollDirectiveClass == clang::Stmt::OMPUnrollDirectiveClass, "");
static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPMaskedDirectiveClass == clang::Stmt::OMPMaskedDirectiveClass, "");
@@ -685,6 +704,7 @@ static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPMasterDirectiveClass == cl
static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPMetaDirectiveClass == clang::Stmt::OMPMetaDirectiveClass, "");
static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPOrderedDirectiveClass == clang::Stmt::OMPOrderedDirectiveClass, "");
static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPParallelDirectiveClass == clang::Stmt::OMPParallelDirectiveClass, "");
+static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPParallelMaskedDirectiveClass == clang::Stmt::OMPParallelMaskedDirectiveClass, "");
static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPParallelMasterDirectiveClass == clang::Stmt::OMPParallelMasterDirectiveClass, "");
static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPParallelSectionsDirectiveClass == clang::Stmt::OMPParallelSectionsDirectiveClass, "");
static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPScanDirectiveClass == clang::Stmt::OMPScanDirectiveClass, "");
@@ -958,6 +978,7 @@ void ZigClang_detect_enum_DeclKind(clang::Decl::Kind x) {
case clang::Decl::OMPDeclareMapper:
case clang::Decl::OMPDeclareReduction:
case clang::Decl::TemplateParamObject:
+ case clang::Decl::UnnamedGlobalConstant:
case clang::Decl::UnresolvedUsingValue:
case clang::Decl::OMPAllocate:
case clang::Decl::OMPRequires:
@@ -1046,6 +1067,7 @@ static_assert((clang::Decl::Kind)ZigClangDeclMSGuid == clang::Decl::MSGuid, "");
static_assert((clang::Decl::Kind)ZigClangDeclOMPDeclareMapper == clang::Decl::OMPDeclareMapper, "");
static_assert((clang::Decl::Kind)ZigClangDeclOMPDeclareReduction == clang::Decl::OMPDeclareReduction, "");
static_assert((clang::Decl::Kind)ZigClangDeclTemplateParamObject == clang::Decl::TemplateParamObject, "");
+static_assert((clang::Decl::Kind)ZigClangDeclUnnamedGlobalConstant == clang::Decl::UnnamedGlobalConstant, "");
static_assert((clang::Decl::Kind)ZigClangDeclUnresolvedUsingValue == clang::Decl::UnresolvedUsingValue, "");
static_assert((clang::Decl::Kind)ZigClangDeclOMPRequires == clang::Decl::OMPRequires, "");
static_assert((clang::Decl::Kind)ZigClangDeclOMPThreadPrivate == clang::Decl::OMPThreadPrivate, "");
@@ -1560,6 +1582,8 @@ void ZigClang_detect_enum_CallingConv(clang::CallingConv x) {
case clang::CC_PreserveMost:
case clang::CC_PreserveAll:
case clang::CC_AArch64VectorCall:
+ case clang::CC_AArch64SVEPCS:
+ case clang::CC_AMDGPUKernelCall:
break;
}
}
@@ -1583,6 +1607,8 @@ static_assert((clang::CallingConv)ZigClangCallingConv_SwiftAsync == clang::CC_Sw
static_assert((clang::CallingConv)ZigClangCallingConv_PreserveMost == clang::CC_PreserveMost, "");
static_assert((clang::CallingConv)ZigClangCallingConv_PreserveAll == clang::CC_PreserveAll, "");
static_assert((clang::CallingConv)ZigClangCallingConv_AArch64VectorCall == clang::CC_AArch64VectorCall, "");
+static_assert((clang::CallingConv)ZigClangCallingConv_AArch64SVEPCS == clang::CC_AArch64SVEPCS, "");
+static_assert((clang::CallingConv)ZigClangCallingConv_AMDGPUKernelCall == clang::CC_AMDGPUKernelCall, "");
void ZigClang_detect_enum_StorageClass(clang::StorageClass x) {
switch (x) {
@@ -1623,22 +1649,6 @@ static_assert((llvm::RoundingMode)ZigClangAPFloat_roundingMode_NearestTiesToAway
static_assert((llvm::RoundingMode)ZigClangAPFloat_roundingMode_Dynamic == llvm::RoundingMode::Dynamic, "");
static_assert((llvm::RoundingMode)ZigClangAPFloat_roundingMode_Invalid == llvm::RoundingMode::Invalid, "");
-void ZigClang_detect_enum_StringKind(clang::StringLiteral::StringKind x) {
- switch (x) {
- case clang::StringLiteral::Ascii:
- case clang::StringLiteral::Wide:
- case clang::StringLiteral::UTF8:
- case clang::StringLiteral::UTF16:
- case clang::StringLiteral::UTF32:
- break;
- }
-}
-static_assert((clang::StringLiteral::StringKind)ZigClangStringLiteral_StringKind_Ascii == clang::StringLiteral::Ascii, "");
-static_assert((clang::StringLiteral::StringKind)ZigClangStringLiteral_StringKind_Wide == clang::StringLiteral::Wide, "");
-static_assert((clang::StringLiteral::StringKind)ZigClangStringLiteral_StringKind_UTF8 == clang::StringLiteral::UTF8, "");
-static_assert((clang::StringLiteral::StringKind)ZigClangStringLiteral_StringKind_UTF16 == clang::StringLiteral::UTF16, "");
-static_assert((clang::StringLiteral::StringKind)ZigClangStringLiteral_StringKind_UTF32 == clang::StringLiteral::UTF32, "");
-
void ZigClang_detect_enum_CharacterKind(clang::CharacterLiteral::CharacterKind x) {
switch (x) {
case clang::CharacterLiteral::Ascii:
@@ -2724,9 +2734,9 @@ ZigClangAPFloatBase_Semantics ZigClangFloatingLiteral_getRawSemantics(const ZigC
return static_cast<ZigClangAPFloatBase_Semantics>(casted->getRawSemantics());
}
-enum ZigClangStringLiteral_StringKind ZigClangStringLiteral_getKind(const struct ZigClangStringLiteral *self) {
+enum ZigClangCharacterLiteral_CharacterKind ZigClangStringLiteral_getKind(const struct ZigClangStringLiteral *self) {
auto casted = reinterpret_cast<const clang::StringLiteral *>(self);
- return (ZigClangStringLiteral_StringKind)casted->getKind();
+ return (ZigClangCharacterLiteral_CharacterKind)casted->getKind();
}
uint32_t ZigClangStringLiteral_getCodeUnit(const struct ZigClangStringLiteral *self, size_t i) {
diff --git a/src/zig_clang.h b/src/zig_clang.h
index 3da57d4301..5d556700e6 100644
--- a/src/zig_clang.h
+++ b/src/zig_clang.h
@@ -252,6 +252,7 @@ enum ZigClangTypeClass {
ZigClangType_VariableArray,
ZigClangType_Atomic,
ZigClangType_Attributed,
+ ZigClangType_BTFTagAttributed,
ZigClangType_BitInt,
ZigClangType_BlockPointer,
ZigClangType_Builtin,
@@ -337,25 +338,33 @@ enum ZigClangStmtClass {
ZigClangStmt_OMPForDirectiveClass,
ZigClangStmt_OMPForSimdDirectiveClass,
ZigClangStmt_OMPGenericLoopDirectiveClass,
+ ZigClangStmt_OMPMaskedTaskLoopDirectiveClass,
+ ZigClangStmt_OMPMaskedTaskLoopSimdDirectiveClass,
ZigClangStmt_OMPMasterTaskLoopDirectiveClass,
ZigClangStmt_OMPMasterTaskLoopSimdDirectiveClass,
ZigClangStmt_OMPParallelForDirectiveClass,
ZigClangStmt_OMPParallelForSimdDirectiveClass,
+ ZigClangStmt_OMPParallelGenericLoopDirectiveClass,
+ ZigClangStmt_OMPParallelMaskedTaskLoopDirectiveClass,
+ ZigClangStmt_OMPParallelMaskedTaskLoopSimdDirectiveClass,
ZigClangStmt_OMPParallelMasterTaskLoopDirectiveClass,
ZigClangStmt_OMPParallelMasterTaskLoopSimdDirectiveClass,
ZigClangStmt_OMPSimdDirectiveClass,
ZigClangStmt_OMPTargetParallelForSimdDirectiveClass,
+ ZigClangStmt_OMPTargetParallelGenericLoopDirectiveClass,
ZigClangStmt_OMPTargetSimdDirectiveClass,
ZigClangStmt_OMPTargetTeamsDistributeDirectiveClass,
ZigClangStmt_OMPTargetTeamsDistributeParallelForDirectiveClass,
ZigClangStmt_OMPTargetTeamsDistributeParallelForSimdDirectiveClass,
ZigClangStmt_OMPTargetTeamsDistributeSimdDirectiveClass,
+ ZigClangStmt_OMPTargetTeamsGenericLoopDirectiveClass,
ZigClangStmt_OMPTaskLoopDirectiveClass,
ZigClangStmt_OMPTaskLoopSimdDirectiveClass,
ZigClangStmt_OMPTeamsDistributeDirectiveClass,
ZigClangStmt_OMPTeamsDistributeParallelForDirectiveClass,
ZigClangStmt_OMPTeamsDistributeParallelForSimdDirectiveClass,
ZigClangStmt_OMPTeamsDistributeSimdDirectiveClass,
+ ZigClangStmt_OMPTeamsGenericLoopDirectiveClass,
ZigClangStmt_OMPTileDirectiveClass,
ZigClangStmt_OMPUnrollDirectiveClass,
ZigClangStmt_OMPMaskedDirectiveClass,
@@ -363,6 +372,7 @@ enum ZigClangStmtClass {
ZigClangStmt_OMPMetaDirectiveClass,
ZigClangStmt_OMPOrderedDirectiveClass,
ZigClangStmt_OMPParallelDirectiveClass,
+ ZigClangStmt_OMPParallelMaskedDirectiveClass,
ZigClangStmt_OMPParallelMasterDirectiveClass,
ZigClangStmt_OMPParallelSectionsDirectiveClass,
ZigClangStmt_OMPScanDirectiveClass,
@@ -667,6 +677,7 @@ enum ZigClangDeclKind {
ZigClangDeclOMPDeclareMapper,
ZigClangDeclOMPDeclareReduction,
ZigClangDeclTemplateParamObject,
+ ZigClangDeclUnnamedGlobalConstant,
ZigClangDeclUnresolvedUsingValue,
ZigClangDeclOMPAllocate,
ZigClangDeclOMPRequires,
@@ -921,25 +932,27 @@ enum ZigClangBuiltinTypeKind {
};
enum ZigClangCallingConv {
- ZigClangCallingConv_C, // __attribute__((cdecl))
- ZigClangCallingConv_X86StdCall, // __attribute__((stdcall))
- ZigClangCallingConv_X86FastCall, // __attribute__((fastcall))
- ZigClangCallingConv_X86ThisCall, // __attribute__((thiscall))
- ZigClangCallingConv_X86VectorCall, // __attribute__((vectorcall))
- ZigClangCallingConv_X86Pascal, // __attribute__((pascal))
- ZigClangCallingConv_Win64, // __attribute__((ms_abi))
- ZigClangCallingConv_X86_64SysV, // __attribute__((sysv_abi))
- ZigClangCallingConv_X86RegCall, // __attribute__((regcall))
- ZigClangCallingConv_AAPCS, // __attribute__((pcs("aapcs")))
- ZigClangCallingConv_AAPCS_VFP, // __attribute__((pcs("aapcs-vfp")))
- ZigClangCallingConv_IntelOclBicc, // __attribute__((intel_ocl_bicc))
- ZigClangCallingConv_SpirFunction, // default for OpenCL functions on SPIR target
- ZigClangCallingConv_OpenCLKernel, // inferred for OpenCL kernels
- ZigClangCallingConv_Swift, // __attribute__((swiftcall))
- ZigClangCallingConv_SwiftAsync, // __attribute__((swiftasynccall))
- ZigClangCallingConv_PreserveMost, // __attribute__((preserve_most))
- ZigClangCallingConv_PreserveAll, // __attribute__((preserve_all))
- ZigClangCallingConv_AArch64VectorCall, // __attribute__((aarch64_vector_pcs))
+ ZigClangCallingConv_C,
+ ZigClangCallingConv_X86StdCall,
+ ZigClangCallingConv_X86FastCall,
+ ZigClangCallingConv_X86ThisCall,
+ ZigClangCallingConv_X86VectorCall,
+ ZigClangCallingConv_X86Pascal,
+ ZigClangCallingConv_Win64,
+ ZigClangCallingConv_X86_64SysV,
+ ZigClangCallingConv_X86RegCall,
+ ZigClangCallingConv_AAPCS,
+ ZigClangCallingConv_AAPCS_VFP,
+ ZigClangCallingConv_IntelOclBicc,
+ ZigClangCallingConv_SpirFunction,
+ ZigClangCallingConv_OpenCLKernel,
+ ZigClangCallingConv_Swift,
+ ZigClangCallingConv_SwiftAsync,
+ ZigClangCallingConv_PreserveMost,
+ ZigClangCallingConv_PreserveAll,
+ ZigClangCallingConv_AArch64VectorCall,
+ ZigClangCallingConv_AArch64SVEPCS,
+ ZigClangCallingConv_AMDGPUKernelCall,
};
enum ZigClangStorageClass {
@@ -1253,7 +1266,9 @@ ZIG_EXTERN_C double ZigClangFloatingLiteral_getValueAsApproximateDouble(const Zi
ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangFloatingLiteral_getBeginLoc(const struct ZigClangFloatingLiteral *);
ZIG_EXTERN_C ZigClangAPFloatBase_Semantics ZigClangFloatingLiteral_getRawSemantics(const ZigClangFloatingLiteral *self);
-ZIG_EXTERN_C enum ZigClangStringLiteral_StringKind ZigClangStringLiteral_getKind(const struct ZigClangStringLiteral *self);
+
+ZIG_EXTERN_C enum ZigClangCharacterLiteral_CharacterKind ZigClangStringLiteral_getKind(
+ const struct ZigClangStringLiteral *self);
ZIG_EXTERN_C uint32_t ZigClangStringLiteral_getCodeUnit(const struct ZigClangStringLiteral *self, size_t i);
ZIG_EXTERN_C unsigned ZigClangStringLiteral_getLength(const struct ZigClangStringLiteral *self);
ZIG_EXTERN_C unsigned ZigClangStringLiteral_getCharByteWidth(const struct ZigClangStringLiteral *self);
diff --git a/src/zig_clang_cc1_main.cpp b/src/zig_clang_cc1_main.cpp
index f648adeba4..de33aa9ea9 100644
--- a/src/zig_clang_cc1_main.cpp
+++ b/src/zig_clang_cc1_main.cpp
@@ -212,7 +212,9 @@ int cc1_main(ArrayRef<const char *> Argv, const char *Argv0, void *MainAddr) {
bool Success = CompilerInvocation::CreateFromArgs(Clang->getInvocation(),
Argv, Diags, Argv0);
- if (Clang->getFrontendOpts().TimeTrace) {
+ if (Clang->getFrontendOpts().TimeTrace ||
+ !Clang->getFrontendOpts().TimeTracePath.empty()) {
+ Clang->getFrontendOpts().TimeTrace = 1;
llvm::timeTraceProfilerInitialize(
Clang->getFrontendOpts().TimeTraceGranularity, Argv0);
}
@@ -256,12 +258,18 @@ int cc1_main(ArrayRef<const char *> Argv, const char *Argv0, void *MainAddr) {
if (llvm::timeTraceProfilerEnabled()) {
SmallString<128> Path(Clang->getFrontendOpts().OutputFile);
llvm::sys::path::replace_extension(Path, "json");
+ if (!Clang->getFrontendOpts().TimeTracePath.empty()) {
+ // replace the suffix to '.json' directly
+ SmallString<128> TracePath(Clang->getFrontendOpts().TimeTracePath);
+ if (llvm::sys::fs::is_directory(TracePath))
+ llvm::sys::path::append(TracePath, llvm::sys::path::filename(Path));
+ Path.assign(TracePath);
+ }
if (auto profilerOutput = Clang->createOutputFile(
Path.str(), /*Binary=*/false, /*RemoveFileOnSignal=*/false,
/*useTemporary=*/false)) {
llvm::timeTraceProfilerWrite(*profilerOutput);
- // FIXME(ibiryukov): make profilerOutput flush in destructor instead.
- profilerOutput->flush();
+ profilerOutput.reset();
llvm::timeTraceProfilerCleanup();
Clang->clearOutputFiles(false);
}
diff --git a/src/zig_clang_cc1as_main.cpp b/src/zig_clang_cc1as_main.cpp
index 6459d1534b..5498810d83 100644
--- a/src/zig_clang_cc1as_main.cpp
+++ b/src/zig_clang_cc1as_main.cpp
@@ -137,6 +137,9 @@ struct AssemblerInvocation {
unsigned IncrementalLinkerCompatible : 1;
unsigned EmbedBitcode : 1;
+ /// Whether to emit DWARF unwind info.
+ EmitDwarfUnwindType EmitDwarfUnwind;
+
/// The name of the relocation model to use.
std::string RelocationModel;
@@ -144,6 +147,9 @@ struct AssemblerInvocation {
/// otherwise.
std::string TargetABI;
+ /// Darwin target variant triple, the variant of the deployment target
+ /// for which the code is being compiled.
+ llvm::Optional<llvm::Triple> DarwinTargetVariantTriple;
/// @}
public:
@@ -164,6 +170,7 @@ public:
Dwarf64 = 0;
DwarfVersion = 0;
EmbedBitcode = 0;
+ EmitDwarfUnwind = EmitDwarfUnwindType::Default;
}
static bool CreateFromArgs(AssemblerInvocation &Res,
@@ -209,6 +216,9 @@ bool AssemblerInvocation::CreateFromArgs(AssemblerInvocation &Opts,
// Target Options
Opts.Triple = llvm::Triple::normalize(Args.getLastArgValue(OPT_triple));
+ if (Arg *A = Args.getLastArg(options::OPT_darwin_target_variant_triple))
+ Opts.DarwinTargetVariantTriple = llvm::Triple(A->getValue());
+
Opts.CPU = std::string(Args.getLastArgValue(OPT_target_cpu));
Opts.Features = Args.getAllArgValues(OPT_target_feature);
@@ -311,6 +321,14 @@ bool AssemblerInvocation::CreateFromArgs(AssemblerInvocation &Opts,
.Default(0);
}
+ if (auto *A = Args.getLastArg(OPT_femit_dwarf_unwind_EQ)) {
+ Opts.EmitDwarfUnwind =
+ llvm::StringSwitch<EmitDwarfUnwindType>(A->getValue())
+ .Case("always", EmitDwarfUnwindType::Always)
+ .Case("no-compact-unwind", EmitDwarfUnwindType::NoCompactUnwind)
+ .Case("default", EmitDwarfUnwindType::Default);
+ }
+
return Success;
}
@@ -361,6 +379,8 @@ static bool ExecuteAssemblerImpl(AssemblerInvocation &Opts,
assert(MRI && "Unable to create target register info!");
MCTargetOptions MCOptions;
+ MCOptions.EmitDwarfUnwind = Opts.EmitDwarfUnwind;
+
std::unique_ptr<MCAsmInfo> MAI(
TheTarget->createMCAsmInfo(*MRI, Opts.Triple, MCOptions));
assert(MAI && "Unable to create target asm info!");
@@ -407,6 +427,8 @@ static bool ExecuteAssemblerImpl(AssemblerInvocation &Opts,
// MCObjectFileInfo needs a MCContext reference in order to initialize itself.
std::unique_ptr<MCObjectFileInfo> MOFI(
TheTarget->createMCObjectFileInfo(Ctx, PIC));
+ if (Opts.DarwinTargetVariantTriple)
+ MOFI->setDarwinTargetVariantTriple(*Opts.DarwinTargetVariantTriple);
Ctx.setObjectFileInfo(MOFI.get());
if (Opts.SaveTemporaryLabels)
@@ -455,7 +477,7 @@ static bool ExecuteAssemblerImpl(AssemblerInvocation &Opts,
std::unique_ptr<MCCodeEmitter> CE;
if (Opts.ShowEncoding)
- CE.reset(TheTarget->createMCCodeEmitter(*MCII, *MRI, Ctx));
+ CE.reset(TheTarget->createMCCodeEmitter(*MCII, Ctx));
std::unique_ptr<MCAsmBackend> MAB(
TheTarget->createMCAsmBackend(*STI, *MRI, MCOptions));
@@ -475,7 +497,7 @@ static bool ExecuteAssemblerImpl(AssemblerInvocation &Opts,
}
std::unique_ptr<MCCodeEmitter> CE(
- TheTarget->createMCCodeEmitter(*MCII, *MRI, Ctx));
+ TheTarget->createMCCodeEmitter(*MCII, Ctx));
std::unique_ptr<MCAsmBackend> MAB(
TheTarget->createMCAsmBackend(*STI, *MRI, MCOptions));
assert(MAB && "Unable to create asm backend!");
@@ -497,7 +519,7 @@ static bool ExecuteAssemblerImpl(AssemblerInvocation &Opts,
if (Opts.EmbedBitcode && Ctx.getObjectFileType() == MCContext::IsMachO) {
MCSection *AsmLabel = Ctx.getMachOSection(
"__LLVM", "__asm", MachO::S_REGULAR, 4, SectionKind::getReadOnly());
- Str.get()->SwitchSection(AsmLabel);
+ Str.get()->switchSection(AsmLabel);
Str.get()->emitZeros(1);
}
diff --git a/src/zig_clang_driver.cpp b/src/zig_clang_driver.cpp
index 1f24131f14..b83cddf202 100644
--- a/src/zig_clang_driver.cpp
+++ b/src/zig_clang_driver.cpp
@@ -410,18 +410,18 @@ int ZigClang_main(int Argc, const char **Argv) {
if (ClangCLMode) {
// Arguments in "CL" are prepended.
llvm::Optional<std::string> OptCL = llvm::sys::Process::GetEnv("CL");
- if (OptCL.hasValue()) {
+ if (OptCL) {
SmallVector<const char *, 8> PrependedOpts;
- getCLEnvVarOptions(OptCL.getValue(), Saver, PrependedOpts);
+ getCLEnvVarOptions(OptCL.value(), Saver, PrependedOpts);
// Insert right after the program name to prepend to the argument list.
Args.insert(Args.begin() + 1, PrependedOpts.begin(), PrependedOpts.end());
}
// Arguments in "_CL_" are appended.
llvm::Optional<std::string> Opt_CL_ = llvm::sys::Process::GetEnv("_CL_");
- if (Opt_CL_.hasValue()) {
+ if (Opt_CL_) {
SmallVector<const char *, 8> AppendedOpts;
- getCLEnvVarOptions(Opt_CL_.getValue(), Saver, AppendedOpts);
+ getCLEnvVarOptions(Opt_CL_.value(), Saver, AppendedOpts);
// Insert at the end of the argument list to append.
Args.append(AppendedOpts.begin(), AppendedOpts.end());
@@ -488,32 +488,39 @@ int ZigClang_main(int Argc, const char **Argv) {
}
std::unique_ptr<Compilation> C(TheDriver.BuildCompilation(Args));
+
+ Driver::ReproLevel ReproLevel = Driver::ReproLevel::OnCrash;
+ if (Arg *A = C->getArgs().getLastArg(options::OPT_gen_reproducer_eq)) {
+ auto Level = llvm::StringSwitch<Optional<Driver::ReproLevel>>(A->getValue())
+ .Case("off", Driver::ReproLevel::Off)
+ .Case("crash", Driver::ReproLevel::OnCrash)
+ .Case("error", Driver::ReproLevel::OnError)
+ .Case("always", Driver::ReproLevel::Always)
+ .Default(None);
+ if (!Level) {
+ llvm::errs() << "Unknown value for " << A->getSpelling() << ": '"
+ << A->getValue() << "'\n";
+ return 1;
+ }
+ ReproLevel = *Level;
+ }
+ if (!!::getenv("FORCE_CLANG_DIAGNOSTICS_CRASH"))
+ ReproLevel = Driver::ReproLevel::Always;
+
int Res = 1;
bool IsCrash = false;
+ Driver::CommandStatus CommandStatus = Driver::CommandStatus::Ok;
+ // Pretend the first command failed if ReproStatus is Always.
+ const Command *FailingCommand = nullptr;
+ if (!C->getJobs().empty())
+ FailingCommand = &*C->getJobs().begin();
if (C && !C->containsError()) {
SmallVector<std::pair<int, const Command *>, 4> FailingCommands;
Res = TheDriver.ExecuteCompilation(*C, FailingCommands);
- // Force a crash to test the diagnostics.
- if (TheDriver.GenReproducer) {
- Diags.Report(diag::err_drv_force_crash)
- << !::getenv("FORCE_CLANG_DIAGNOSTICS_CRASH");
-
- // Pretend that every command failed.
- FailingCommands.clear();
- for (const auto &J : C->getJobs())
- if (const Command *C = dyn_cast<Command>(&J))
- FailingCommands.push_back(std::make_pair(-1, C));
-
- // Print the bug report message that would be printed if we did actually
- // crash, but only if we're crashing due to FORCE_CLANG_DIAGNOSTICS_CRASH.
- if (::getenv("FORCE_CLANG_DIAGNOSTICS_CRASH"))
- llvm::dbgs() << llvm::getBugReportMsg();
- }
-
for (const auto &P : FailingCommands) {
int CommandRes = P.first;
- const Command *FailingCommand = P.second;
+ FailingCommand = P.second;
if (!Res)
Res = CommandRes;
@@ -532,13 +539,22 @@ int ZigClang_main(int Argc, const char **Argv) {
// https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xcu_chap02.html
IsCrash |= CommandRes > 128;
#endif
- if (IsCrash) {
- TheDriver.generateCompilationDiagnostics(*C, *FailingCommand);
+ CommandStatus =
+ IsCrash ? Driver::CommandStatus::Crash : Driver::CommandStatus::Error;
+ if (IsCrash)
break;
- }
}
}
+ // Print the bug report message that would be printed if we did actually
+ // crash, but only if we're crashing due to FORCE_CLANG_DIAGNOSTICS_CRASH.
+ if (::getenv("FORCE_CLANG_DIAGNOSTICS_CRASH"))
+ llvm::dbgs() << llvm::getBugReportMsg();
+ if (FailingCommand != nullptr &&
+ TheDriver.maybeGenerateCompilationDiagnostics(CommandStatus, ReproLevel,
+ *C, *FailingCommand))
+ Res = 1;
+
Diags.getClient()->finish();
if (!UseNewCC1Process && IsCrash) {
diff --git a/src/zig_llvm-ar.cpp b/src/zig_llvm-ar.cpp
index c959f339a2..6e5f9d36d8 100644
--- a/src/zig_llvm-ar.cpp
+++ b/src/zig_llvm-ar.cpp
@@ -18,10 +18,15 @@
#include "llvm/IR/LLVMContext.h"
#include "llvm/Object/Archive.h"
#include "llvm/Object/ArchiveWriter.h"
+#include "llvm/Object/COFFImportFile.h"
+#include "llvm/Object/ELFObjectFile.h"
#include "llvm/Object/IRObjectFile.h"
#include "llvm/Object/MachO.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Object/SymbolicFile.h"
+#include "llvm/Object/TapiFile.h"
+#include "llvm/Object/Wasm.h"
+#include "llvm/Object/XCOFFObjectFile.h"
#include "llvm/Support/Chrono.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ConvertUTF.h"
@@ -54,6 +59,7 @@
#endif
using namespace llvm;
+using namespace llvm::object;
// The name this program was invoked as.
static StringRef ToolName;
@@ -61,37 +67,36 @@ static StringRef ToolName;
// The basename of this program.
static StringRef Stem;
-const char RanlibHelp[] = R"(OVERVIEW: LLVM Ranlib (llvm-ranlib)
-
- This program generates an index to speed access to archives
-
-USAGE: llvm-ranlib <archive-file>
-
-OPTIONS:
- -h --help - Display available options
- -v --version - Display the version of this program
- -D - Use zero for timestamps and uids/gids (default)
- -U - Use actual timestamps and uids/gids
-)";
-
-const char ArHelp[] = R"(OVERVIEW: LLVM Archiver
-
-USAGE: llvm-ar [options] [-]<operation>[modifiers] [relpos] [count] <archive> [files]
- llvm-ar -M [<mri-script]
+static void printRanLibHelp(StringRef ToolName) {
+ outs() << "OVERVIEW: LLVM Ranlib\n\n"
+ << "This program generates an index to speed access to archives\n\n"
+ << "USAGE: " + ToolName + " <archive-file>\n\n"
+ << "OPTIONS:\n"
+ << " -h --help - Display available options\n"
+ << " -v --version - Display the version of this program\n"
+ << " -D - Use zero for timestamps and uids/gids "
+ "(default)\n"
+ << " -U - Use actual timestamps and uids/gids\n";
+}
-OPTIONS:
+static void printArHelp(StringRef ToolName) {
+ const char ArOptions[] =
+ R"(OPTIONS:
--format - archive format to create
=default - default
=gnu - gnu
=darwin - darwin
=bsd - bsd
+ =bigarchive - big archive (AIX OS)
--plugin=<string> - ignored for compatibility
-h --help - display this help and exit
+ --output - the directory to extract archive members to
--rsp-quoting - quoting style for response files
=posix - posix
=windows - windows
--thin - create a thin archive
--version - print the version and exit
+ -X{32|64|32_64|any} - object mode (only for AIX OS)
@<file> - read options from <file>
OPERATIONS:
@@ -126,11 +131,20 @@ MODIFIERS:
[V] - display the version and exit
)";
+ outs() << "OVERVIEW: LLVM Archiver\n\n"
+ << "USAGE: " + ToolName +
+ " [options] [-]<operation>[modifiers] [relpos] "
+ "[count] <archive> [files]\n"
+ << " " + ToolName + " -M [<mri-script]\n\n";
+
+ outs() << ArOptions;
+}
+
static void printHelpMessage() {
if (Stem.contains_insensitive("ranlib"))
- outs() << RanlibHelp;
+ printRanLibHelp(Stem);
else if (Stem.contains_insensitive("ar"))
- outs() << ArHelp;
+ printArHelp(Stem);
}
static unsigned MRILineNumber;
@@ -176,12 +190,16 @@ static void failIfError(Error E, Twine Context = "") {
});
}
+static void warn(Twine Message) {
+ WithColor::warning(errs(), ToolName) << Message << "\n";
+}
+
static SmallVector<const char *, 256> PositionalArgs;
static bool MRI;
namespace {
-enum Format { Default, GNU, BSD, DARWIN, Unknown };
+enum Format { Default, GNU, BSD, DARWIN, BIGARCHIVE, Unknown };
}
static Format FormatType = Default;
@@ -201,6 +219,10 @@ enum ArchiveOperation {
CreateSymTab ///< Create a symbol table in an existing archive
};
+enum class BitModeTy { Bit32, Bit64, Bit32_64, Any, Unknown };
+
+static BitModeTy BitMode = BitModeTy::Bit32;
+
// Modifiers to follow operation to vary behavior
static bool AddAfter = false; ///< 'a' modifier
static bool AddBefore = false; ///< 'b' modifier
@@ -230,6 +252,9 @@ static int CountParam = 0;
// command line.
static std::string ArchiveName;
+// Output directory specified by --output.
+static std::string OutputDir;
+
static std::vector<std::unique_ptr<MemoryBuffer>> ArchiveBuffers;
static std::vector<std::unique_ptr<object::Archive>> Archives;
@@ -447,6 +472,19 @@ static ArchiveOperation parseCommandLine() {
if (AddLibrary && Operation != QuickAppend)
badUsage("the 'L' modifier is only applicable to the 'q' operation");
+ if (!OutputDir.empty()) {
+ if (Operation != Extract)
+ badUsage("--output is only applicable to the 'x' operation");
+ bool IsDir = false;
+ // If OutputDir is not a directory, create_directories may still succeed if
+ // all components of the path prefix are directories. Test is_directory as
+ // well.
+ if (!sys::fs::create_directories(OutputDir))
+ sys::fs::is_directory(OutputDir, IsDir);
+ if (!IsDir)
+ fail("'" + OutputDir + "' is not a directory");
+ }
+
// Return the parsed operation to the caller
return Operation;
}
@@ -547,7 +585,15 @@ static void doExtract(StringRef Name, const object::Archive::Child &C) {
failIfError(ModeOrErr.takeError());
sys::fs::perms Mode = ModeOrErr.get();
- llvm::StringRef outputFilePath = sys::path::filename(Name);
+ StringRef outputFilePath;
+ SmallString<128> path;
+ if (OutputDir.empty()) {
+ outputFilePath = sys::path::filename(Name);
+ } else {
+ sys::path::append(path, OutputDir, sys::path::filename(Name));
+ outputFilePath = path.str();
+ }
+
if (Verbose)
outs() << "x - " << outputFilePath << '\n';
@@ -600,6 +646,71 @@ static bool shouldCreateArchive(ArchiveOperation Op) {
llvm_unreachable("Missing entry in covered switch.");
}
+static bool is64BitSymbolicFile(SymbolicFile &Obj) {
+ if (auto *IRObj = dyn_cast<IRObjectFile>(&Obj))
+ return Triple(IRObj->getTargetTriple()).isArch64Bit();
+ if (isa<COFFObjectFile>(Obj) || isa<COFFImportFile>(Obj))
+ return false;
+ if (XCOFFObjectFile *XCOFFObj = dyn_cast<XCOFFObjectFile>(&Obj))
+ return XCOFFObj->is64Bit();
+ if (isa<WasmObjectFile>(Obj))
+ return false;
+ if (TapiFile *Tapi = dyn_cast<TapiFile>(&Obj))
+ return Tapi->is64Bit();
+ if (MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(&Obj))
+ return MachO->is64Bit();
+ if (ELFObjectFileBase *ElfO = dyn_cast<ELFObjectFileBase>(&Obj))
+ return ElfO->getBytesInAddress() == 8;
+
+ fail("unsupported file format");
+}
+
+static bool isValidInBitMode(Binary &Bin) {
+ if (BitMode == BitModeTy::Bit32_64 || BitMode == BitModeTy::Any)
+ return true;
+
+ if (SymbolicFile *SymFile = dyn_cast<SymbolicFile>(&Bin)) {
+ bool Is64Bit = is64BitSymbolicFile(*SymFile);
+ if ((Is64Bit && (BitMode == BitModeTy::Bit32)) ||
+ (!Is64Bit && (BitMode == BitModeTy::Bit64)))
+ return false;
+ }
+ // In AIX "ar", non-object files are always considered to have a valid bit
+ // mode.
+ return true;
+}
+
+Expected<std::unique_ptr<Binary>> getAsBinary(const NewArchiveMember &NM,
+ LLVMContext *Context) {
+ auto BinaryOrErr = createBinary(NM.Buf->getMemBufferRef(), Context);
+ if (BinaryOrErr)
+ return std::move(*BinaryOrErr);
+ return BinaryOrErr.takeError();
+}
+
+Expected<std::unique_ptr<Binary>> getAsBinary(const Archive::Child &C,
+ LLVMContext *Context) {
+ return C.getAsBinary(Context);
+}
+
+template <class A> static bool isValidInBitMode(const A &Member) {
+ if (object::Archive::getDefaultKindForHost() != object::Archive::K_AIXBIG)
+ return true;
+ LLVMContext Context;
+ Expected<std::unique_ptr<Binary>> BinOrErr = getAsBinary(Member, &Context);
+ // In AIX "ar", if there is a non-object file member, it is never ignored due
+ // to the bit mode setting.
+ if (!BinOrErr) {
+ consumeError(BinOrErr.takeError());
+ return true;
+ }
+ return isValidInBitMode(*BinOrErr.get());
+}
+
+static void warnInvalidObjectForFileMode(Twine Name) {
+ warn("'" + Name + "' is not valid with the current object file mode");
+}
+
static void performReadOperation(ArchiveOperation Operation,
object::Archive *OldArchive) {
if (Operation == Extract && OldArchive->isThin())
@@ -614,6 +725,10 @@ static void performReadOperation(ArchiveOperation Operation,
failIfError(NameOrErr.takeError());
StringRef Name = NameOrErr.get();
+ // Check whether to ignore this object due to its bitness.
+ if (!isValidInBitMode(C))
+ continue;
+
if (Filter) {
auto I = find_if(Members, [Name](StringRef Path) {
return comparePaths(Name, Path);
@@ -652,8 +767,6 @@ static void performReadOperation(ArchiveOperation Operation,
static void addChildMember(std::vector<NewArchiveMember> &Members,
const object::Archive::Child &M,
bool FlattenArchive = false) {
- if (Thin && !M.getParent()->isThin())
- fail("cannot convert a regular archive to a thin one");
Expected<NewArchiveMember> NMOrErr =
NewArchiveMember::getOldMember(M, Deterministic);
failIfError(NMOrErr.takeError());
@@ -692,8 +805,7 @@ static void addChildMember(std::vector<NewArchiveMember> &Members,
Members.push_back(std::move(*NMOrErr));
}
-static void addMember(std::vector<NewArchiveMember> &Members,
- StringRef FileName, bool FlattenArchive = false) {
+static NewArchiveMember getArchiveMember(StringRef FileName) {
Expected<NewArchiveMember> NMOrErr =
NewArchiveMember::getFile(FileName, Deterministic);
failIfError(NMOrErr.takeError(), FileName);
@@ -713,9 +825,24 @@ static void addMember(std::vector<NewArchiveMember> &Members,
PathOrErr ? *PathOrErr : sys::path::convert_to_slash(FileName));
}
}
+ return std::move(*NMOrErr);
+}
+
+static void addMember(std::vector<NewArchiveMember> &Members,
+ NewArchiveMember &NM) {
+ Members.push_back(std::move(NM));
+}
+
+static void addMember(std::vector<NewArchiveMember> &Members,
+ StringRef FileName, bool FlattenArchive = false) {
+ NewArchiveMember NM = getArchiveMember(FileName);
+ if (!isValidInBitMode(NM)) {
+ warnInvalidObjectForFileMode(FileName);
+ return;
+ }
if (FlattenArchive &&
- identify_magic(NMOrErr->Buf->getBuffer()) == file_magic::archive) {
+ identify_magic(NM.Buf->getBuffer()) == file_magic::archive) {
object::Archive &Lib = readLibrary(FileName);
// When creating thin archives, only flatten if the member is also thin.
if (!Thin || Lib.isThin()) {
@@ -727,7 +854,7 @@ static void addMember(std::vector<NewArchiveMember> &Members,
return;
}
}
- Members.push_back(std::move(*NMOrErr));
+ Members.push_back(std::move(NM));
}
enum InsertAction {
@@ -743,6 +870,9 @@ static InsertAction computeInsertAction(ArchiveOperation Operation,
StringRef Name,
std::vector<StringRef>::iterator &Pos,
StringMap<int> &MemberCount) {
+ if (!isValidInBitMode(Member))
+ return IA_AddOldMember;
+
if (Operation == QuickAppend || Members.empty())
return IA_AddOldMember;
auto MI = find_if(
@@ -804,7 +934,7 @@ computeNewArchiveMembers(ArchiveOperation Operation,
Expected<StringRef> NameOrErr = Child.getName();
failIfError(NameOrErr.takeError());
std::string Name = std::string(NameOrErr.get());
- if (comparePaths(Name, RelPos)) {
+ if (comparePaths(Name, RelPos) && isValidInBitMode(Child)) {
assert(AddAfter || AddBefore);
if (AddBefore)
InsertPos = Pos;
@@ -815,12 +945,25 @@ computeNewArchiveMembers(ArchiveOperation Operation,
std::vector<StringRef>::iterator MemberI = Members.end();
InsertAction Action =
computeInsertAction(Operation, Child, Name, MemberI, MemberCount);
+
+ auto HandleNewMember = [](auto Member, auto &Members, auto &Child) {
+ NewArchiveMember NM = getArchiveMember(*Member);
+ if (isValidInBitMode(NM))
+ addMember(Members, NM);
+ else {
+ // If a new member is not a valid object for the bit mode, add
+ // the old member back.
+ warnInvalidObjectForFileMode(*Member);
+ addChildMember(Members, Child, /*FlattenArchive=*/Thin);
+ }
+ };
+
switch (Action) {
case IA_AddOldMember:
addChildMember(Ret, Child, /*FlattenArchive=*/Thin);
break;
case IA_AddNewMember:
- addMember(Ret, *MemberI);
+ HandleNewMember(MemberI, Ret, Child);
break;
case IA_Delete:
break;
@@ -828,7 +971,7 @@ computeNewArchiveMembers(ArchiveOperation Operation,
addChildMember(Moved, Child, /*FlattenArchive=*/Thin);
break;
case IA_MoveNewMember:
- addMember(Moved, *MemberI);
+ HandleNewMember(MemberI, Moved, Child);
break;
}
// When processing elements with the count param, we need to preserve the
@@ -875,48 +1018,18 @@ computeNewArchiveMembers(ArchiveOperation Operation,
return Ret;
}
-static object::Archive::Kind getDefaultForHost() {
- return Triple(sys::getProcessTriple()).isOSDarwin()
- ? object::Archive::K_DARWIN
- : object::Archive::K_GNU;
-}
-
-static object::Archive::Kind getKindFromMember(const NewArchiveMember &Member) {
- auto MemBufferRef = Member.Buf->getMemBufferRef();
- Expected<std::unique_ptr<object::ObjectFile>> OptionalObject =
- object::ObjectFile::createObjectFile(MemBufferRef);
-
- if (OptionalObject)
- return isa<object::MachOObjectFile>(**OptionalObject)
- ? object::Archive::K_DARWIN
- : object::Archive::K_GNU;
-
- // squelch the error in case we had a non-object file
- consumeError(OptionalObject.takeError());
-
- // If we're adding a bitcode file to the archive, detect the Archive kind
- // based on the target triple.
- LLVMContext Context;
- if (identify_magic(MemBufferRef.getBuffer()) == file_magic::bitcode) {
- if (auto ObjOrErr = object::SymbolicFile::createSymbolicFile(
- MemBufferRef, file_magic::bitcode, &Context)) {
- auto &IRObject = cast<object::IRObjectFile>(**ObjOrErr);
- return Triple(IRObject.getTargetTriple()).isOSDarwin()
- ? object::Archive::K_DARWIN
- : object::Archive::K_GNU;
- } else {
- // Squelch the error in case this was not a SymbolicFile.
- consumeError(ObjOrErr.takeError());
- }
- }
-
- return getDefaultForHost();
-}
-
static void performWriteOperation(ArchiveOperation Operation,
object::Archive *OldArchive,
std::unique_ptr<MemoryBuffer> OldArchiveBuf,
std::vector<NewArchiveMember> *NewMembersP) {
+ if (OldArchive) {
+ if (Thin && !OldArchive->isThin())
+ fail("cannot convert a regular archive to a thin one");
+
+ if (OldArchive->isThin())
+ Thin = true;
+ }
+
std::vector<NewArchiveMember> NewMembers;
if (!NewMembersP)
NewMembers = computeNewArchiveMembers(Operation, OldArchive);
@@ -926,14 +1039,23 @@ static void performWriteOperation(ArchiveOperation Operation,
case Default:
if (Thin)
Kind = object::Archive::K_GNU;
- else if (OldArchive)
+ else if (OldArchive) {
Kind = OldArchive->kind();
- else if (NewMembersP)
- Kind = !NewMembersP->empty() ? getKindFromMember(NewMembersP->front())
- : getDefaultForHost();
+ if (Kind == object::Archive::K_BSD) {
+ auto InferredKind = object::Archive::K_BSD;
+ if (NewMembersP && !NewMembersP->empty())
+ InferredKind = NewMembersP->front().detectKindFromObject();
+ else if (!NewMembers.empty())
+ InferredKind = NewMembers.front().detectKindFromObject();
+ if (InferredKind == object::Archive::K_DARWIN)
+ Kind = object::Archive::K_DARWIN;
+ }
+ } else if (NewMembersP)
+ Kind = !NewMembersP->empty() ? NewMembersP->front().detectKindFromObject()
+ : object::Archive::getDefaultKindForHost();
else
- Kind = !NewMembers.empty() ? getKindFromMember(NewMembers.front())
- : getDefaultForHost();
+ Kind = !NewMembers.empty() ? NewMembers.front().detectKindFromObject()
+ : object::Archive::getDefaultKindForHost();
break;
case GNU:
Kind = object::Archive::K_GNU;
@@ -948,6 +1070,11 @@ static void performWriteOperation(ArchiveOperation Operation,
fail("only the gnu format has a thin mode");
Kind = object::Archive::K_DARWIN;
break;
+ case BIGARCHIVE:
+ if (Thin)
+ fail("only the gnu format has a thin mode");
+ Kind = object::Archive::K_AIXBIG;
+ break;
case Unknown:
llvm_unreachable("");
}
@@ -1029,8 +1156,7 @@ static int performOperation(ArchiveOperation Operation,
} else {
if (!Create) {
// Produce a warning if we should and we're creating the archive
- WithColor::warning(errs(), ToolName)
- << "creating " << ArchiveName << "\n";
+ warn("creating " + ArchiveName);
}
}
@@ -1073,8 +1199,12 @@ static void runMRIScript() {
switch (Command) {
case MRICommand::AddLib: {
+ if (!Create)
+ fail("no output archive has been opened");
object::Archive &Lib = readLibrary(Rest);
{
+ if (Thin && !Lib.isThin())
+ fail("cannot add a regular archive's contents to a thin archive");
Error Err = Error::success();
for (auto &Member : Lib.children(Err))
addChildMember(NewMembers, Member, /*FlattenArchive=*/Thin);
@@ -1083,6 +1213,8 @@ static void runMRIScript() {
break;
}
case MRICommand::AddMod:
+ if (!Create)
+ fail("no output archive has been opened");
addMember(NewMembers, Rest);
break;
case MRICommand::CreateThin:
@@ -1095,6 +1227,8 @@ static void runMRIScript() {
if (Saved)
fail("file already saved");
ArchiveName = std::string(Rest);
+ if (ArchiveName.empty())
+ fail("missing archive name");
break;
case MRICommand::Delete: {
llvm::erase_if(NewMembers, [=](NewArchiveMember &M) {
@@ -1116,7 +1250,8 @@ static void runMRIScript() {
// Nothing to do if not saved.
if (Saved)
- performOperation(ReplaceOrInsert, &NewMembers);
+ performOperation(ReplaceOrInsert, /*OldArchive=*/nullptr,
+ /*OldArchiveBuf=*/nullptr, &NewMembers);
exit(0);
}
@@ -1132,6 +1267,15 @@ static bool handleGenericOption(StringRef arg) {
return false;
}
+static BitModeTy getBitMode(const char *RawBitMode) {
+ return StringSwitch<BitModeTy>(RawBitMode)
+ .Case("32", BitModeTy::Bit32)
+ .Case("64", BitModeTy::Bit64)
+ .Case("32_64", BitModeTy::Bit32_64)
+ .Case("any", BitModeTy::Any)
+ .Default(BitModeTy::Unknown);
+}
+
static const char *matchFlagWithArg(StringRef Expected,
ArrayRef<const char *>::iterator &ArgIt,
ArrayRef<const char *> Args) {
@@ -1181,6 +1325,14 @@ static int ar_main(int argc, char **argv) {
cl::ExpandResponseFiles(Saver, getRspQuoting(makeArrayRef(argv, argc)), Argv);
+ // Get BitMode from enviorment variable "OBJECT_MODE" for AIX OS, if
+ // specified.
+ if (object::Archive::getDefaultKindForHost() == object::Archive::K_AIXBIG) {
+ BitMode = getBitMode(getenv("OBJECT_MODE"));
+ if (BitMode == BitModeTy::Unknown)
+ BitMode = BitModeTy::Bit32;
+ }
+
for (ArrayRef<const char *>::iterator ArgIt = Argv.begin();
ArgIt != Argv.end(); ++ArgIt) {
const char *Match = nullptr;
@@ -1219,16 +1371,35 @@ static int ar_main(int argc, char **argv) {
.Case("gnu", GNU)
.Case("darwin", DARWIN)
.Case("bsd", BSD)
+ .Case("bigarchive", BIGARCHIVE)
.Default(Unknown);
if (FormatType == Unknown)
fail(std::string("Invalid format ") + Match);
continue;
}
+ if ((Match = matchFlagWithArg("output", ArgIt, Argv))) {
+ OutputDir = Match;
+ continue;
+ }
+
if (matchFlagWithArg("plugin", ArgIt, Argv) ||
matchFlagWithArg("rsp-quoting", ArgIt, Argv))
continue;
+ if (strncmp(*ArgIt, "-X", 2) == 0) {
+ if (object::Archive::getDefaultKindForHost() ==
+ object::Archive::K_AIXBIG) {
+ Match = *(*ArgIt + 2) != '\0' ? *ArgIt + 2 : *(++ArgIt);
+ BitMode = getBitMode(Match);
+ if (BitMode == BitModeTy::Unknown)
+ fail(Twine("invalid bit mode: ") + Match);
+ continue;
+ } else {
+ fail(Twine(*ArgIt) + " option not supported on non AIX OS");
+ }
+ }
+
Options += *ArgIt + 1;
}
diff --git a/src/zig_llvm.cpp b/src/zig_llvm.cpp
index 52c202fded..4f9cd76c6a 100644
--- a/src/zig_llvm.cpp
+++ b/src/zig_llvm.cpp
@@ -417,12 +417,13 @@ LLVMValueRef ZigLLVMAddFunctionInAddressSpace(LLVMModuleRef M, const char *Name,
return wrap(func);
}
-LLVMValueRef ZigLLVMBuildCall(LLVMBuilderRef B, LLVMValueRef Fn, LLVMValueRef *Args,
- unsigned NumArgs, ZigLLVM_CallingConv CC, ZigLLVM_CallAttr attr, const char *Name)
+LLVMValueRef ZigLLVMBuildCall(LLVMBuilderRef B, LLVMTypeRef Ty, LLVMValueRef Fn,
+ LLVMValueRef *Args, unsigned NumArgs, ZigLLVM_CallingConv CC, ZigLLVM_CallAttr attr,
+ const char *Name)
{
- Value *V = unwrap(Fn);
- FunctionType *FnT = cast<FunctionType>(V->getType()->getNonOpaquePointerElementType());
- CallInst *call_inst = CallInst::Create(FnT, V, makeArrayRef(unwrap(Args), NumArgs), Name);
+ FunctionType *FTy = unwrap<FunctionType>(Ty);
+ CallInst *call_inst = unwrap(B)->CreateCall(FTy, unwrap(Fn), makeArrayRef(unwrap(Args),
+ NumArgs), Name);
call_inst->setCallingConv(static_cast<CallingConv::ID>(CC));
switch (attr) {
case ZigLLVM_CallAttrAuto:
@@ -440,7 +441,7 @@ LLVMValueRef ZigLLVMBuildCall(LLVMBuilderRef B, LLVMValueRef Fn, LLVMValueRef *A
call_inst->addFnAttr(Attribute::AlwaysInline);
break;
}
- return wrap(unwrap(B)->Insert(call_inst));
+ return wrap(call_inst);
}
LLVMValueRef ZigLLVMBuildMemCpy(LLVMBuilderRef B, LLVMValueRef Dst, unsigned DstAlign,
@@ -1194,6 +1195,10 @@ void ZigLLVMSetCallElemTypeAttr(LLVMValueRef Call, size_t arg_index, LLVMTypeRef
Attribute::get(call_inst->getContext(), Attribute::ElementType, llvm_type));
}
+LLVMTypeRef ZigLLVMGetGEPResultElementType(LLVMValueRef GEP) {
+ return wrap(unwrap<GEPOperator>(GEP)->getResultElementType());
+}
+
void ZigLLVMFunctionSetPrefixData(LLVMValueRef function, LLVMValueRef data) {
unwrap<Function>(function)->setPrefixData(unwrap<Constant>(data));
}
diff --git a/src/zig_llvm.h b/src/zig_llvm.h
index 804caf616e..7fdddda6a4 100644
--- a/src/zig_llvm.h
+++ b/src/zig_llvm.h
@@ -125,8 +125,9 @@ enum ZigLLVM_CallAttr {
ZigLLVM_CallAttrAlwaysTail,
ZigLLVM_CallAttrAlwaysInline,
};
-ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildCall(LLVMBuilderRef B, LLVMValueRef Fn, LLVMValueRef *Args,
- unsigned NumArgs, enum ZigLLVM_CallingConv CC, enum ZigLLVM_CallAttr attr, const char *Name);
+ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildCall(LLVMBuilderRef B, LLVMTypeRef function_type,
+ LLVMValueRef Fn, LLVMValueRef *Args, unsigned NumArgs, enum ZigLLVM_CallingConv CC,
+ enum ZigLLVM_CallAttr attr, const char *Name);
ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildMemCpy(LLVMBuilderRef B, LLVMValueRef Dst, unsigned DstAlign,
LLVMValueRef Src, unsigned SrcAlign, LLVMValueRef Size, bool isVolatile);
@@ -321,11 +322,15 @@ ZIG_EXTERN_C void ZigLLVMAddSretAttr(LLVMValueRef fn_ref, LLVMTypeRef type_val);
ZIG_EXTERN_C void ZigLLVMAddFunctionElemTypeAttr(LLVMValueRef fn_ref, size_t arg_index, LLVMTypeRef elem_ty);
ZIG_EXTERN_C void ZigLLVMAddFunctionAttrCold(LLVMValueRef fn);
+ZIG_EXTERN_C LLVMTypeRef ZigLLVMGetGEPResultElementType(LLVMValueRef GEP);
+
ZIG_EXTERN_C void ZigLLVMParseCommandLineOptions(size_t argc, const char *const *argv);
-// copied from include/llvm/ADT/Triple.h
-// synchronize with target.cpp::arch_list
+// synchronize with llvm/include/ADT/Triple.h::ArchType
+// synchronize with std.Target.Cpu.Arch
+// synchronize with src/stage1/target.cpp::arch_list
+// synchronize with codegen/llvm/bindings.zig::ArchType
enum ZigLLVM_ArchType {
ZigLLVM_UnknownArch,
@@ -339,7 +344,10 @@ enum ZigLLVM_ArchType {
ZigLLVM_bpfel, // eBPF or extended BPF or 64-bit BPF (little endian)
ZigLLVM_bpfeb, // eBPF or extended BPF or 64-bit BPF (big endian)
ZigLLVM_csky, // CSKY: csky
+ ZigLLVM_dxil, // DXIL 32-bit DirectX bytecode
ZigLLVM_hexagon, // Hexagon: hexagon
+ ZigLLVM_loongarch32, // LoongArch (32-bit): loongarch32
+ ZigLLVM_loongarch64, // LoongArch (64-bit): loongarch64
ZigLLVM_m68k, // M68k: Motorola 680x0 family
ZigLLVM_mips, // MIPS: mips, mipsallegrex, mipsr6
ZigLLVM_mipsel, // MIPSEL: mipsel, mipsallegrexe, mipsr6el
@@ -409,6 +417,10 @@ enum ZigLLVM_VendorType {
ZigLLVM_LastVendorType = ZigLLVM_OpenEmbedded
};
+// synchronize with llvm/include/ADT/Triple.h::OsType
+// synchronize with std.Target.Os.Tag
+// synchronize with codegen/llvm/bindings.zig::OsType
+// synchronize with src/stage1/target.cpp::os_list
enum ZigLLVM_OSType {
ZigLLVM_UnknownOS,
@@ -437,9 +449,11 @@ enum ZigLLVM_OSType {
ZigLLVM_NVCL, // NVIDIA OpenCL
ZigLLVM_AMDHSA, // AMD HSA Runtime
ZigLLVM_PS4,
+ ZigLLVM_PS5,
ZigLLVM_ELFIAMCU,
ZigLLVM_TvOS, // Apple tvOS
ZigLLVM_WatchOS, // Apple watchOS
+ ZigLLVM_DriverKit, // Apple DriverKit
ZigLLVM_Mesa3D,
ZigLLVM_Contiki,
ZigLLVM_AMDPAL, // AMD PAL Runtime
@@ -447,8 +461,8 @@ enum ZigLLVM_OSType {
ZigLLVM_Hurd, // GNU/Hurd
ZigLLVM_WASI, // Experimental WebAssembly OS
ZigLLVM_Emscripten,
-
- ZigLLVM_LastOSType = ZigLLVM_Emscripten
+ ZigLLVM_ShaderModel, // DirectX ShaderModel
+ ZigLLVM_LastOSType = ZigLLVM_ShaderModel
};
// Synchronize with target.cpp::abi_list
@@ -477,16 +491,35 @@ enum ZigLLVM_EnvironmentType {
ZigLLVM_CoreCLR,
ZigLLVM_Simulator, // Simulator variants of other systems, e.g., Apple's iOS
ZigLLVM_MacABI, // Mac Catalyst variant of Apple's iOS deployment target.
- ZigLLVM_LastEnvironmentType = ZigLLVM_MacABI
+
+ ZigLLVM_Pixel,
+ ZigLLVM_Vertex,
+ ZigLLVM_Geometry,
+ ZigLLVM_Hull,
+ ZigLLVM_Domain,
+ ZigLLVM_Compute,
+ ZigLLVM_Library,
+ ZigLLVM_RayGeneration,
+ ZigLLVM_Intersection,
+ ZigLLVM_AnyHit,
+ ZigLLVM_ClosestHit,
+ ZigLLVM_Miss,
+ ZigLLVM_Callable,
+ ZigLLVM_Mesh,
+ ZigLLVM_Amplification,
+
+ ZigLLVM_LastEnvironmentType = ZigLLVM_Amplification
};
enum ZigLLVM_ObjectFormatType {
ZigLLVM_UnknownObjectFormat,
ZigLLVM_COFF,
+ ZigLLVM_DXContainer,
ZigLLVM_ELF,
ZigLLVM_GOFF,
ZigLLVM_MachO,
+ ZigLLVM_SPIRV,
ZigLLVM_Wasm,
ZigLLVM_XCOFF,
};