From 3986d54de6229047791c778ee441231aa34def81 Mon Sep 17 00:00:00 2001 From: Steven Johnson Date: Wed, 26 Jun 2024 16:56:19 -0700 Subject: [PATCH 1/6] Add support for arm64e --- python_bindings/src/halide/halide_/PyEnums.cpp | 1 + src/CodeGen_ARM.cpp | 10 +++++++--- src/LLVM_Runtime_Linker.cpp | 6 +++++- src/Target.cpp | 2 ++ src/Target.h | 1 + src/runtime/HalideRuntime.h | 1 + test/correctness/cross_compilation.cpp | 1 + test/correctness/simd_op_check.h | 1 + 8 files changed, 19 insertions(+), 4 deletions(-) diff --git a/python_bindings/src/halide/halide_/PyEnums.cpp b/python_bindings/src/halide/halide_/PyEnums.cpp index 5a442bdca737..b6443f3849c6 100644 --- a/python_bindings/src/halide/halide_/PyEnums.cpp +++ b/python_bindings/src/halide/halide_/PyEnums.cpp @@ -180,6 +180,7 @@ void define_enums(py::module &m) { .value("LLVMLargeCodeModel", Target::Feature::LLVMLargeCodeModel) .value("RVV", Target::Feature::RVV) .value("ARMv81a", Target::Feature::ARMv81a) + .value("ARM64e", Target::Feature::ARM64e) .value("SanitizerCoverage", Target::Feature::SanitizerCoverage) .value("ProfileByTimer", Target::Feature::ProfileByTimer) .value("SPIRV", Target::Feature::SPIRV) diff --git a/src/CodeGen_ARM.cpp b/src/CodeGen_ARM.cpp index 0e4de6baa050..f50c77900878 100644 --- a/src/CodeGen_ARM.cpp +++ b/src/CodeGen_ARM.cpp @@ -2445,9 +2445,13 @@ string CodeGen_ARM::mcpu_target() const { } } else { if (target.os == Target::IOS) { - return "cyclone"; + if (target.has_feature(Target::ARM64e)) { + return "apple-a12"; + } else { + return "cyclone"; // aka Apple A7 + } } else if (target.os == Target::OSX) { - return "apple-a12"; + return "apple-m1"; } else if (target.has_feature(Target::SVE2)) { return "cortex-x1"; } else { @@ -2482,7 +2486,7 @@ string CodeGen_ARM::mattrs() const { } } else { // TODO: Should Halide's SVE flags be 64-bit only? - // TODO: Sound we ass "-neon" if NoNEON is set? Does this make any sense? + // TODO: Sound we add "-neon" if NoNEON is set? Does this make any sense? if (target.has_feature(Target::SVE2)) { attrs.emplace_back("+sve2"); } else if (target.has_feature(Target::SVE)) { diff --git a/src/LLVM_Runtime_Linker.cpp b/src/LLVM_Runtime_Linker.cpp index 09e58bea894b..986770e886a2 100644 --- a/src/LLVM_Runtime_Linker.cpp +++ b/src/LLVM_Runtime_Linker.cpp @@ -486,7 +486,11 @@ llvm::Triple get_triple_for_target(const Target &target) { } else { user_assert(target.bits == 64) << "Target bits must be 32 or 64\n"; #ifdef WITH_AARCH64 - triple.setArch(llvm::Triple::aarch64); + if (target.has_feature(Target::ARM64e)) { + triple.setArch(llvm::Triple::aarch64, llvm::Triple::AArch64SubArch_arm64e); + } else { + triple.setArch(llvm::Triple::aarch64); + } #else user_error << "AArch64 llvm target not enabled in this build of Halide\n"; #endif diff --git a/src/Target.cpp b/src/Target.cpp index 53e85196dae3..7b4b130fa61f 100644 --- a/src/Target.cpp +++ b/src/Target.cpp @@ -581,6 +581,7 @@ const std::map feature_name_map = { {"llvm_large_code_model", Target::LLVMLargeCodeModel}, {"rvv", Target::RVV}, {"armv81a", Target::ARMv81a}, + {"arm64e", Target::ARM64e}, {"sanitizer_coverage", Target::SanitizerCoverage}, {"profile_by_timer", Target::ProfileByTimer}, {"spirv", Target::SPIRV}, @@ -1388,6 +1389,7 @@ bool Target::get_runtime_compatible_target(const Target &other, Target &result) const std::array intersection_features = {{ ARMv7s, ARMv81a, + ARM64e, AVX, AVX2, AVX512, diff --git a/src/Target.h b/src/Target.h index 7150513e6451..4d76c53af7b0 100644 --- a/src/Target.h +++ b/src/Target.h @@ -155,6 +155,7 @@ struct Target { LLVMLargeCodeModel = halide_llvm_large_code_model, RVV = halide_target_feature_rvv, ARMv81a = halide_target_feature_armv81a, + ARM64e = halide_target_feature_arm64e, SanitizerCoverage = halide_target_feature_sanitizer_coverage, ProfileByTimer = halide_target_feature_profile_by_timer, SPIRV = halide_target_feature_spirv, diff --git a/src/runtime/HalideRuntime.h b/src/runtime/HalideRuntime.h index 736d64478c8b..e6c8ca9fd536 100644 --- a/src/runtime/HalideRuntime.h +++ b/src/runtime/HalideRuntime.h @@ -1435,6 +1435,7 @@ typedef enum halide_target_feature_t { halide_llvm_large_code_model, ///< Use the LLVM large code model to compile halide_target_feature_rvv, ///< Enable RISCV "V" Vector Extension halide_target_feature_armv81a, ///< Enable ARMv8.1-a instructions + halide_target_feature_arm64e, ///< Enable ARM64e (requires ARMv8.3a) halide_target_feature_sanitizer_coverage, ///< Enable hooks for SanitizerCoverage support. halide_target_feature_profile_by_timer, ///< Alternative to halide_target_feature_profile using timer interrupt for systems without threads or applicartions that need to avoid them. halide_target_feature_spirv, ///< Enable SPIR-V code generation support. diff --git a/test/correctness/cross_compilation.cpp b/test/correctness/cross_compilation.cpp index 7831e2c303f7..aff9219e3089 100644 --- a/test/correctness/cross_compilation.cpp +++ b/test/correctness/cross_compilation.cpp @@ -21,6 +21,7 @@ int main(int argc, char **argv) { "arm-64-android", "arm-64-android-hvx", "arm-64-ios", + "arm-64-ios-arm64e", "arm-64-linux", "arm-64-noos-semihosting", "arm-64-windows", diff --git a/test/correctness/simd_op_check.h b/test/correctness/simd_op_check.h index f386b7efc094..7e7122b7a6c6 100644 --- a/test/correctness/simd_op_check.h +++ b/test/correctness/simd_op_check.h @@ -121,6 +121,7 @@ class SimdOpCheckTest { Target::ARMFp16, Target::ARMv7s, Target::ARMv81a, + Target::ARM64e, Target::AVX, Target::AVX2, Target::AVX512, From 502e2a103890dc29d3b49d9ac4808b13aebdfeeb Mon Sep 17 00:00:00 2001 From: Steven Johnson Date: Wed, 26 Jun 2024 16:59:06 -0700 Subject: [PATCH 2/6] Update LLVM_Runtime_Linker.cpp --- src/LLVM_Runtime_Linker.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/LLVM_Runtime_Linker.cpp b/src/LLVM_Runtime_Linker.cpp index 986770e886a2..243fe4ad21ec 100644 --- a/src/LLVM_Runtime_Linker.cpp +++ b/src/LLVM_Runtime_Linker.cpp @@ -487,9 +487,9 @@ llvm::Triple get_triple_for_target(const Target &target) { user_assert(target.bits == 64) << "Target bits must be 32 or 64\n"; #ifdef WITH_AARCH64 if (target.has_feature(Target::ARM64e)) { - triple.setArch(llvm::Triple::aarch64, llvm::Triple::AArch64SubArch_arm64e); + triple.setArch(llvm::Triple::aarch64, llvm::Triple::AArch64SubArch_arm64e); } else { - triple.setArch(llvm::Triple::aarch64); + triple.setArch(llvm::Triple::aarch64); } #else user_error << "AArch64 llvm target not enabled in this build of Halide\n"; From 729929116d85832d160fd91ca15d51dbb021034a Mon Sep 17 00:00:00 2001 From: Steven Johnson Date: Wed, 26 Jun 2024 17:00:43 -0700 Subject: [PATCH 3/6] Update Target.cpp --- src/Target.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Target.cpp b/src/Target.cpp index 7b4b130fa61f..330b85affbc9 100644 --- a/src/Target.cpp +++ b/src/Target.cpp @@ -1386,7 +1386,7 @@ bool Target::get_runtime_compatible_target(const Target &other, Target &result) // clang-format on // clang-format off - const std::array intersection_features = {{ + const std::array intersection_features = {{ ARMv7s, ARMv81a, ARM64e, From cf5a13b4942bc4cc547ab08a6a7e1a2ce6d1c843 Mon Sep 17 00:00:00 2001 From: Steven Johnson Date: Thu, 27 Jun 2024 10:02:24 -0700 Subject: [PATCH 4/6] Update CodeGen_ARM.cpp --- src/CodeGen_ARM.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CodeGen_ARM.cpp b/src/CodeGen_ARM.cpp index f50c77900878..8fca379e7980 100644 --- a/src/CodeGen_ARM.cpp +++ b/src/CodeGen_ARM.cpp @@ -2448,7 +2448,7 @@ string CodeGen_ARM::mcpu_target() const { if (target.has_feature(Target::ARM64e)) { return "apple-a12"; } else { - return "cyclone"; // aka Apple A7 + return "apple-a7"; } } else if (target.os == Target::OSX) { return "apple-m1"; From a48dfe07cf849a3a4891db0261479e9add195c87 Mon Sep 17 00:00:00 2001 From: Steven Johnson Date: Wed, 24 Jul 2024 09:38:04 -0700 Subject: [PATCH 5/6] ARM64e implies ARM8.3a --- src/CodeGen_ARM.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/CodeGen_ARM.cpp b/src/CodeGen_ARM.cpp index ae92f29a0dcf..b3fbaca8923a 100644 --- a/src/CodeGen_ARM.cpp +++ b/src/CodeGen_ARM.cpp @@ -45,6 +45,11 @@ namespace { // // v8r has no relation to anything. Target complete_arm_target(Target t) { + // If arm64e is set, assume at least arm8.3a + if (t.has_feature(Target::ARM64e)) { + t.set_feature(Target::ARMv83a); + } + constexpr int num_arm_v8_features = 10; static const Target::Feature arm_v8_features[num_arm_v8_features] = { Target::ARMv89a, From 2e5e6458dcf32535c1dc208da4e6deb6d211bdbc Mon Sep 17 00:00:00 2001 From: Steven Johnson Date: Fri, 23 Aug 2024 10:45:24 -0700 Subject: [PATCH 6/6] Update Target.cpp --- src/Target.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Target.cpp b/src/Target.cpp index 497bf6717469..12490fb82eea 100644 --- a/src/Target.cpp +++ b/src/Target.cpp @@ -1505,7 +1505,7 @@ bool Target::get_runtime_compatible_target(const Target &other, Target &result) // (c) must match across both targets; it is an error if one target has the feature and the other doesn't // clang-format off - const std::array union_features = {{ + const std::array union_features = {{ // These are true union features. CUDA, D3D12Compute, @@ -1546,13 +1546,14 @@ bool Target::get_runtime_compatible_target(const Target &other, Target &result) ARMv87a, ARMv88a, ARMv89a, + + ARM64e, }}; // clang-format on // clang-format off const std::array intersection_features = {{ ARMv7s, - ARM64e, AVX, AVX2, AVX512,