diff --git a/src/CodeGen_LLVM.cpp b/src/CodeGen_LLVM.cpp index 0142fe290a9e..67b91e9b1775 100644 --- a/src/CodeGen_LLVM.cpp +++ b/src/CodeGen_LLVM.cpp @@ -1390,7 +1390,28 @@ void CodeGen_LLVM::optimize_module() { // 21.04 -> 14.78 using current ToT release build. (See also https://reviews.llvm.org/rL358304) pto.ForgetAllSCEVInLoopUnroll = true; - llvm::PassBuilder pb(tm.get(), pto); + llvm::PassInstrumentationCallbacks pic; +#if LLVM_VERSION < 220 + if (get_target().has_feature(Target::SVE) || get_target().has_feature(Target::SVE2)) { + // LLVM 21's LoopAccessAnalysis::getStrideFromAddRec() queries a + // scalable-vector access type's fixed element count, which hits a + // fatal assertion (TypeSize::getFixedValue on a scalable TypeSize). + // This is reached from LoopLoadEliminationPass, which the default + // pipeline always runs (independent of Halide's own loop-opt + // settings). Fixed upstream in LLVM 22 by guarding that query + // against ScalableVectorType. Loop load elimination looks for + // opportunities to forward a store to a later load across loop + // iterations, which Halide-generated code essentially never + // benefits from, so skip it entirely on affected SVE targets rather + // than accept a compiler crash (or, in a no-asserts LLVM build, a + // silently bogus stride). + pic.registerShouldRunOptionalPassCallback( + [](llvm::StringRef pass_name, const llvm::Any &) { + return pass_name != "LoopLoadEliminationPass"; + }); + } +#endif + llvm::PassBuilder pb(tm.get(), pto, /*PGOOpt=*/std::nullopt, &pic); // These analysis managers have to be declared in this order. llvm::LoopAnalysisManager lam; diff --git a/test/autoschedulers/mullapudi2016/max_filter.cpp b/test/autoschedulers/mullapudi2016/max_filter.cpp index 7c4da2683753..c745c277acf6 100644 --- a/test/autoschedulers/mullapudi2016/max_filter.cpp +++ b/test/autoschedulers/mullapudi2016/max_filter.cpp @@ -128,15 +128,6 @@ int main(int argc, char **argv) { return 0; } - // LLVM 21 calls getFixedValue() on scalable TypeSize objects in the - // AArch64 backend, triggering an assertion. Fixed in LLVM 22 by: - // https://github.com/llvm/llvm-project/commit/d1500d12be60 (PR #169764) - if (Internal::get_llvm_version() < 220 && - get_jit_target_from_environment().has_feature(Target::SVE2)) { - printf("[SKIP] LLVM 21 has known getFixedValue() assertion failures on SVE scalable types.\n"); - return 0; - } - if (argc != 2) { fprintf(stderr, "Usage: %s \n", argv[0]); return 1; diff --git a/test/correctness/align_bounds.cpp b/test/correctness/align_bounds.cpp index ebcf3d6c8267..7007bfd60c98 100644 --- a/test/correctness/align_bounds.cpp +++ b/test/correctness/align_bounds.cpp @@ -28,15 +28,6 @@ void my_error_handler(JITUserContext *user_context, const char *msg) { } int main(int argc, char **argv) { - // LLVM 21 calls getFixedValue() on scalable TypeSize objects in the - // AArch64 backend, triggering an assertion. Fixed in LLVM 22 by: - // https://github.com/llvm/llvm-project/commit/d1500d12be60 (PR #169764) - if (Internal::get_llvm_version() < 220 && - get_jit_target_from_environment().has_feature(Target::SVE2)) { - printf("[SKIP] LLVM 21 has known getFixedValue() assertion failures on SVE scalable types.\n"); - return 0; - } - // Force the bounds of an intermediate pipeline stage to be even to remove a select { Func f, g, h; diff --git a/test/correctness/bound_small_allocations.cpp b/test/correctness/bound_small_allocations.cpp index d2863be1d450..480750d08c90 100644 --- a/test/correctness/bound_small_allocations.cpp +++ b/test/correctness/bound_small_allocations.cpp @@ -10,15 +10,6 @@ Expr calc(Expr a) { } int main(int argc, char **argv) { - // LLVM 21 calls getFixedValue() on scalable TypeSize objects in the - // AArch64 backend, triggering an assertion. Fixed in LLVM 22 by: - // https://github.com/llvm/llvm-project/commit/d1500d12be60 (PR #169764) - if (Internal::get_llvm_version() < 220 && - get_jit_target_from_environment().has_feature(Target::SVE2)) { - printf("[SKIP] LLVM 21 has known getFixedValue() assertion failures on SVE scalable types.\n"); - return 0; - } - Var x, y; Func f, g, h; diff --git a/test/correctness/fit_function.cpp b/test/correctness/fit_function.cpp index 20f9a1ea5e75..7b6abc4fa5cb 100644 --- a/test/correctness/fit_function.cpp +++ b/test/correctness/fit_function.cpp @@ -7,15 +7,6 @@ using namespace Halide; int main(int argc, char **argv) { - // LLVM 21 calls getFixedValue() on scalable TypeSize objects in the - // AArch64 backend, triggering an assertion. Fixed in LLVM 22 by: - // https://github.com/llvm/llvm-project/commit/d1500d12be60 (PR #169764) - if (Internal::get_llvm_version() < 220 && - get_jit_target_from_environment().has_feature(Target::SVE2)) { - printf("[SKIP] LLVM 21 has known getFixedValue() assertion failures on SVE scalable types.\n"); - return 0; - } - // Fit an odd polynomial to sin from 0 to pi/2 using Halide's derivative support ImageParam coeffs(Float(64), 1); Param learning_rate; diff --git a/test/correctness/interleave_rgb.cpp b/test/correctness/interleave_rgb.cpp index 092b54eb569a..3a679a239035 100644 --- a/test/correctness/interleave_rgb.cpp +++ b/test/correctness/interleave_rgb.cpp @@ -103,16 +103,6 @@ bool test_deinterleave(int x_stride) { } int main(int argc, char **argv) { - // LLVM 20 is missing llvm.vector.deinterleave4 for SVE and LLVM 21 - // asserts (getFixedValue on scalable TypeSize). Fixed in LLVM 22 by: - // https://github.com/llvm/llvm-project/commit/d1500d12be60 (PR #169764) - if (Internal::get_llvm_version() < 220 && - get_jit_target_from_environment().has_feature(Target::SVE2)) { - printf("[SKIP] LLVM %d has known SVE backend bugs for this test.\n", - Internal::get_llvm_version()); - return 0; - } - for (int x_stride : {3, 4}) { if (!test_interleave(x_stride)) return 1; if (!test_interleave(x_stride)) return 1; diff --git a/test/correctness/logical.cpp b/test/correctness/logical.cpp index 2d246998f565..440f41329e81 100644 --- a/test/correctness/logical.cpp +++ b/test/correctness/logical.cpp @@ -12,15 +12,6 @@ Expr u16(Expr a) { } int main(int argc, char **argv) { - // LLVM 21 calls getFixedValue() on scalable TypeSize objects in the - // AArch64 backend, triggering an assertion. Fixed in LLVM 22 by: - // https://github.com/llvm/llvm-project/commit/d1500d12be60 (PR #169764) - if (Internal::get_llvm_version() < 220 && - get_jit_target_from_environment().has_feature(Target::SVE2)) { - printf("[SKIP] LLVM 21 has known getFixedValue() assertion failures on SVE scalable types.\n"); - return 0; - } - Buffer input(128, 64); for (int y = 0; y < input.height(); y++) { diff --git a/test/correctness/predicated_store_load.cpp b/test/correctness/predicated_store_load.cpp index af1f0c53d96c..3e21e0f9a3d7 100644 --- a/test/correctness/predicated_store_load.cpp +++ b/test/correctness/predicated_store_load.cpp @@ -487,15 +487,6 @@ int predicated_atomic_store_test(const Target &t) { int main(int argc, char **argv) { Target t = get_jit_target_from_environment(); - // LLVM 21 calls getFixedValue() on scalable TypeSize objects in the - // AArch64 backend, triggering an assertion. Fixed in LLVM 22 by: - // https://github.com/llvm/llvm-project/commit/d1500d12be60 (PR #169764) - if (Internal::get_llvm_version() < 220 && - t.has_feature(Target::SVE2)) { - printf("[SKIP] LLVM 21 has known getFixedValue() assertion failures on SVE scalable types.\n"); - return 0; - } - printf("Running vectorized dense load test\n"); if (predicated_tail_test(t) != 0) { return 1; diff --git a/test/correctness/stage_strided_loads.cpp b/test/correctness/stage_strided_loads.cpp index e0373a5be69e..dc09be89d09c 100644 --- a/test/correctness/stage_strided_loads.cpp +++ b/test/correctness/stage_strided_loads.cpp @@ -56,16 +56,6 @@ class CheckForStridedLoads : public IRMutator { } checker; int main(int argc, char **argv) { - // LLVM 20 is missing llvm.vector.deinterleave4 for SVE and LLVM 21 - // asserts (getFixedValue on scalable TypeSize). Fixed in LLVM 22 by: - // https://github.com/llvm/llvm-project/commit/d1500d12be60 (PR #169764) - if (Internal::get_llvm_version() < 220 && - get_jit_target_from_environment().has_feature(Target::SVE2)) { - printf("[SKIP] LLVM %d has known SVE backend bugs for this test.\n", - Internal::get_llvm_version()); - return 0; - } - ImageParam buf(Float(32), 1, "buf"); { diff --git a/test/correctness/truncated_pyramid.cpp b/test/correctness/truncated_pyramid.cpp index 26f0143fc513..081c46b4d1ea 100644 --- a/test/correctness/truncated_pyramid.cpp +++ b/test/correctness/truncated_pyramid.cpp @@ -6,15 +6,6 @@ using std::pair; using std::vector; int main(int argc, char **argv) { - // LLVM 21 calls getFixedValue() on scalable TypeSize objects in the - // AArch64 backend, triggering an assertion. Fixed in LLVM 22 by: - // https://github.com/llvm/llvm-project/commit/d1500d12be60 (PR #169764) - if (Internal::get_llvm_version() < 220 && - get_jit_target_from_environment().has_feature(Target::SVE2)) { - printf("[SKIP] LLVM 21 has known getFixedValue() assertion failures on SVE scalable types.\n"); - return 0; - } - Func input; Var x, y; input(x, y) = random_float(); diff --git a/test/correctness/vector_reductions.cpp b/test/correctness/vector_reductions.cpp index e2fa21278fb3..49a4f9f9a215 100644 --- a/test/correctness/vector_reductions.cpp +++ b/test/correctness/vector_reductions.cpp @@ -160,9 +160,9 @@ void add_tasks(const Target &target, std::vector &tasks) { int main(int argc, char **argv) { Target target = get_jit_target_from_environment(); - // LLVM 20 hangs and LLVM 21 asserts (getFixedValue on scalable TypeSize) - // in the AArch64 backend for SVE. Fixed in LLVM 22 by: - // https://github.com/llvm/llvm-project/commit/d1500d12be60 (PR #169764) + // The reduce-padding recursion in CodeGen_ARM::codegen_across_vector_reduce + // can fail to converge for some SVE2 vector-reduce shapes under LLVM < 22, + // hanging the compiler indefinitely rather than failing outright. if (Internal::get_llvm_version() < 220 && target.has_feature(Target::SVE2)) { printf("[SKIP] LLVM %d has known SVE backend bugs for this test.\n", diff --git a/test/correctness/vectorize_nested.cpp b/test/correctness/vectorize_nested.cpp index f04359fe2df0..e9800ef8f034 100644 --- a/test/correctness/vectorize_nested.cpp +++ b/test/correctness/vectorize_nested.cpp @@ -277,15 +277,6 @@ int vectorize_inner_of_scalarization() { } int main(int argc, char **argv) { - // LLVM 21 calls getFixedValue() on scalable TypeSize objects in the - // AArch64 backend, triggering an assertion. Fixed in LLVM 22 by: - // https://github.com/llvm/llvm-project/commit/d1500d12be60 (PR #169764) - if (Internal::get_llvm_version() < 220 && - get_jit_target_from_environment().has_feature(Target::SVE2)) { - printf("[SKIP] LLVM 21 has known getFixedValue() assertion failures on SVE scalable types.\n"); - return 0; - } - if (vectorize_2d_round_up()) { printf("vectorize_2d_round_up failed\n"); return 1; diff --git a/test/performance/const_division.cpp b/test/performance/const_division.cpp index 0ee0f30f2e88..265a4bccbacd 100644 --- a/test/performance/const_division.cpp +++ b/test/performance/const_division.cpp @@ -191,15 +191,6 @@ int main(int argc, char **argv) { return 0; } - // LLVM 21 calls getFixedValue() on scalable TypeSize objects in the - // AArch64 backend, triggering an assertion. Fixed in LLVM 22 by: - // https://github.com/llvm/llvm-project/commit/d1500d12be60 (PR #169764) - if (Internal::get_llvm_version() < 220 && - target.has_feature(Target::SVE2)) { - printf("[SKIP] LLVM 21 has known getFixedValue() assertion failures on SVE scalable types.\n"); - return 0; - } - int seed = argc > 1 ? atoi(argv[1]) : time(nullptr); rng.seed(seed); std::cout << "const_division test seed: " << seed << std::endl;