diff --git a/.clang-tidy b/.clang-tidy index 646be4bdbc83..9ff4d6ba7877 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -6,7 +6,9 @@ Checks: > -*, bugprone-*, -bugprone-branch-clone, + -bugprone-easily-swappable-parameters, -bugprone-exception-escape, + -bugprone-implicit-widening-of-multiplication-result, -bugprone-integer-division, -bugprone-narrowing-conversions, -bugprone-reserved-identifier, diff --git a/.github/workflows/packaging.yml b/.github/workflows/packaging.yml index c971d205447e..2b6e9625d69a 100644 --- a/.github/workflows/packaging.yml +++ b/.github/workflows/packaging.yml @@ -7,16 +7,20 @@ jobs: env: CMAKE_CXX_COMPILER_LAUNCHER: ccache CMAKE_C_COMPILER_LAUNCHER: ccache - LLVM_ROOT: /usr/lib/llvm-12 + LLVM_ROOT: /usr/lib/llvm-13 steps: - name: Install dependencies run: | wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc 2>/dev/null \ | gpg --dearmor - | sudo tee /etc/apt/trusted.gpg.d/kitware.gpg >/dev/null sudo apt-add-repository 'deb https://apt.kitware.com/ubuntu/ focal main' + # from apt.llvm.org + # wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add - + sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 15CF4D18AF4F7421 + sudo apt-add-repository "deb https://apt.llvm.org/$(lsb_release -sc)/ llvm-toolchain-$(lsb_release -sc)-13 main" sudo apt update sudo apt install cmake ninja-build doxygen ccache - sudo apt install llvm-12-dev liblld-12-dev clang-12 libclang-12-dev libjpeg-dev libpng-dev + sudo apt install llvm-13-dev liblld-13-dev clang-13 libclang-13-dev libjpeg-dev libpng-dev sudo apt install lintian dpkg-dev - name: Check out sources uses: actions/checkout@v2 @@ -37,6 +41,10 @@ jobs: # Specifically use the CMake version that comes with Ubuntu. - name: Install dependencies run: | + # from apt.llvm.org + # wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add - + sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 15CF4D18AF4F7421 + sudo apt-add-repository "deb https://apt.llvm.org/$(lsb_release -sc)/ llvm-toolchain-$(lsb_release -sc)-13 main" sudo apt update sudo apt install cmake ninja-build libc6-dev-arm64-cross gcc-aarch64-linux-gnu g++-aarch64-linux-gnu qemu-user - name: Check out sources diff --git a/.github/workflows/presubmit.yml b/.github/workflows/presubmit.yml index b370b2fe4848..5beabb6dce5f 100644 --- a/.github/workflows/presubmit.yml +++ b/.github/workflows/presubmit.yml @@ -27,13 +27,17 @@ jobs: - uses: actions/checkout@v2 - name: Install clang-tidy run: | + # from apt.llvm.org + # wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add - + sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 15CF4D18AF4F7421 + sudo apt-add-repository "deb https://apt.llvm.org/$(lsb_release -sc)/ llvm-toolchain-$(lsb_release -sc)-13 main" sudo apt-get update - sudo apt-get install llvm-12 clang-12 liblld-12-dev libclang-12-dev clang-tidy-12 ninja-build + sudo apt-get install llvm-13 clang-13 liblld-13-dev libclang-13-dev clang-tidy-13 ninja-build - name: Run clang-tidy run: | - export CC=clang-12 - export CXX=clang++-12 - export CLANG_TIDY_LLVM_INSTALL_DIR=/usr/lib/llvm-12 + export CC=clang-13 + export CXX=clang++-13 + export CLANG_TIDY_LLVM_INSTALL_DIR=/usr/lib/llvm-13 ./run-clang-tidy.sh check_cmake_file_lists: name: Check CMake file lists diff --git a/Makefile b/Makefile index 69abd1a6afce..56b921d73f65 100644 --- a/Makefile +++ b/Makefile @@ -1066,7 +1066,7 @@ $(BUILD_DIR)/initmod.%_32_debug.ll: $(SRC_DIR)/runtime/%.cpp $(BUILD_DIR)/clang_ @mkdir -p $(@D) $(CLANG) $(CXX_WARNING_FLAGS) -g -DDEBUG_RUNTIME -O3 $(RUNTIME_CXX_FLAGS) -fpic -m32 -target $(RUNTIME_TRIPLE_32) -DCOMPILING_HALIDE_RUNTIME -DBITS_32 -emit-llvm -S $(SRC_DIR)/runtime/$*.cpp -o $@ -MMD -MP -MF $(BUILD_DIR)/initmod.$*_32_debug.d -ifneq (,$(findstring $(LLVM_VERSION_TIMES_10), 120 130)) +ifneq (,$(findstring $(LLVM_VERSION_TIMES_10), 130)) # For LLVM14+, we must add elementtype() annotations to some of our LLVM IR; # earlier versions either don't understand that keyword at all, or don't support # the uses we have for it. Rather than forking these sources, for now we'll just @@ -2185,7 +2185,7 @@ $(BUILD_DIR)/clang_ok: @exit 1 endif -ifneq (,$(findstring $(LLVM_VERSION_TIMES_10), 120 130 140, 150)) +ifneq (,$(findstring $(LLVM_VERSION_TIMES_10), 130 140, 150)) LLVM_OK=yes endif diff --git a/README.md b/README.md index 682bc15b9fcb..7ae0b66ecdff 100644 --- a/README.md +++ b/README.md @@ -109,14 +109,14 @@ issue. ### TL;DR -Have llvm-12.0 (or greater) installed and run `make` in the root directory of +Have llvm-13.0 (or greater) installed and run `make` in the root directory of the repository (where this README is). ### Acquiring LLVM At any point in time, building Halide requires either the latest stable version of LLVM, the previous stable version of LLVM, and trunk. At the time of writing, -this means versions 13.0 and 12.0 are supported, but 11.0 is not. The commands +this means versions 14.0 and 13.0 are supported, but 12.0 is not. The commands `llvm-config` and `clang` must be somewhere in the path. If your OS does not have packages for LLVM, you can find binaries for it at @@ -130,7 +130,7 @@ If you want to build it yourself, first check it out from GitHub: % git clone --depth 1 --branch llvmorg-13.0.0 https://github.com/llvm/llvm-project.git ``` -(If you want to build LLVM 12.x, use branch `release/12.x`; for current trunk, +(If you want to build LLVM 13.x, use branch `release/13.x`; for current trunk, use `main`) Then build it like so: @@ -285,7 +285,7 @@ Subsets of the tests can be selected with `-L` and include `correctness`, #### Building LLVM (optional) Follow these steps if you want to build LLVM yourself. First, download LLVM's -sources (these instructions use the latest 12.0 release) +sources (these instructions use the latest 13.0 release) ``` D:\> git clone --depth 1 --branch llvmorg-13.0.0 https://github.com/llvm/llvm-project.git diff --git a/dependencies/llvm/CMakeLists.txt b/dependencies/llvm/CMakeLists.txt index 248aaf9ea4e3..296dde998c16 100644 --- a/dependencies/llvm/CMakeLists.txt +++ b/dependencies/llvm/CMakeLists.txt @@ -20,8 +20,8 @@ message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}") message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}") message(STATUS "Using ClangConfig.cmake in: ${Clang_DIR}") -if (LLVM_PACKAGE_VERSION VERSION_LESS 12.0) - message(FATAL_ERROR "LLVM version must be 12.0 or newer") +if (LLVM_PACKAGE_VERSION VERSION_LESS 13.0) + message(FATAL_ERROR "LLVM version must be 13.0 or newer") endif () if (LLVM_PACKAGE_VERSION VERSION_GREATER 15.0) diff --git a/packaging/ubuntu/config.cmake b/packaging/ubuntu/config.cmake index 722cf47852a2..d4df26dee844 100644 --- a/packaging/ubuntu/config.cmake +++ b/packaging/ubuntu/config.cmake @@ -62,8 +62,8 @@ set(CPACK_DEBIAN_HALIDE_DOCUMENTATION_PACKAGE_ARCHITECTURE all) # Package dependencies. # TODO: figure out how to get LLVM major version piped in here. -set(CPACK_DEBIAN_HALIDE_RUNTIME_PACKAGE_DEPENDS "llvm-12 (>= 12.0.0)") -set(CPACK_DEBIAN_HALIDE_DEVELOPMENT_PACKAGE_DEPENDS "llvm-12-dev (>= 12.0.0), liblld-12-dev (>= 12.0.0)") +set(CPACK_DEBIAN_HALIDE_RUNTIME_PACKAGE_DEPENDS "llvm-13 (>= 13.0.0)") +set(CPACK_DEBIAN_HALIDE_DEVELOPMENT_PACKAGE_DEPENDS "llvm-13-dev (>= 13.0.0), liblld-13-dev (>= 13.0.0)") set(CPACK_DEBIAN_HALIDE_DOCUMENTATION_PACKAGE_DEPENDS "") # Sets up package dependencies based on CPack component dependencies diff --git a/run-clang-tidy.sh b/run-clang-tidy.sh index 379d1d0d40bd..46ac24bb74fa 100755 --- a/run-clang-tidy.sh +++ b/run-clang-tidy.sh @@ -13,18 +13,18 @@ FIX=$1 # are using to build Halide itself. If you don't have LLVM12 installed, # you can usually install what you need easily via: # -# sudo apt-get install llvm-12 clang-12 libclang-12-dev clang-tidy-12 -# export CLANG_TIDY_LLVM_INSTALL_DIR=/usr/lib/llvm-12 +# sudo apt-get install llvm-13 clang-13 libclang-13-dev clang-tidy-13 +# export CLANG_TIDY_LLVM_INSTALL_DIR=/usr/lib/llvm-13 [ -z "$CLANG_TIDY_LLVM_INSTALL_DIR" ] && echo "CLANG_TIDY_LLVM_INSTALL_DIR must point to an LLVM installation dir for this script." && exit echo CLANG_TIDY_LLVM_INSTALL_DIR = ${CLANG_TIDY_LLVM_INSTALL_DIR} VERSION=$(${CLANG_TIDY_LLVM_INSTALL_DIR}/bin/clang-tidy --version) -if [[ ${VERSION} =~ .*version\ 12.* ]] +if [[ ${VERSION} =~ .*version\ 13.* ]] then - echo "clang-tidy version 12 found." + echo "clang-tidy version 13 found." else - echo "CLANG_TIDY_LLVM_INSTALL_DIR must point to an LLVM 12 install!" + echo "CLANG_TIDY_LLVM_INSTALL_DIR must point to an LLVM 13 install!" exit 1 fi @@ -49,7 +49,7 @@ cmake -DCMAKE_BUILD_TYPE=Debug \ # We must populate the includes directory to check things outside of src/ cmake --build ${CLANG_TIDY_BUILD_DIR} --target HalideIncludes -RUN_CLANG_TIDY=${CLANG_TIDY_LLVM_INSTALL_DIR}/share/clang/run-clang-tidy.py +RUN_CLANG_TIDY=${CLANG_TIDY_LLVM_INSTALL_DIR}/bin/run-clang-tidy # We deliberately skip apps/ and test/ for now, as the compile commands won't include # generated headers files from Generators. diff --git a/src/CodeGen_Internal.cpp b/src/CodeGen_Internal.cpp index f7f7b2917991..cf2b25cc0a7e 100644 --- a/src/CodeGen_Internal.cpp +++ b/src/CodeGen_Internal.cpp @@ -611,11 +611,6 @@ void get_target_options(const llvm::Module &module, llvm::TargetOptions &options options.HonorSignDependentRoundingFPMathOption = !per_instruction_fast_math_flags; options.NoZerosInBSS = false; options.GuaranteedTailCallOpt = false; -#if LLVM_VERSION >= 130 - // nothing -#else - options.StackAlignmentOverride = 0; -#endif options.FunctionSections = true; options.UseInitArray = true; options.FloatABIType = @@ -690,11 +685,7 @@ void set_function_attributes_for_target(llvm::Function *fn, const Target &t) { void embed_bitcode(llvm::Module *M, const string &halide_command) { // Save llvm.compiler.used and remote it. SmallVector used_array; -#if LLVM_VERSION >= 130 SmallVector used_globals; -#else - SmallPtrSet used_globals; -#endif llvm::Type *used_element_type = llvm::Type::getInt8Ty(M->getContext())->getPointerTo(0); GlobalVariable *used = collectUsedGlobalVariables(*M, used_globals, true); for (auto *GV : used_globals) { diff --git a/src/CodeGen_LLVM.cpp b/src/CodeGen_LLVM.cpp index 22945cc4361b..53de525c8ca5 100644 --- a/src/CodeGen_LLVM.cpp +++ b/src/CodeGen_LLVM.cpp @@ -147,21 +147,12 @@ namespace { llvm::Value *CreateConstGEP1_32(IRBuilderBase *builder, llvm::Type *gep_type, Value *ptr, unsigned index) { -#if LLVM_VERSION >= 130 return builder->CreateConstGEP1_32(gep_type, ptr, index); -#else - (void)gep_type; - return builder->CreateConstGEP1_32(ptr, index); -#endif } llvm::Value *CreateInBoundsGEP(IRBuilderBase *builder, llvm::Type *gep_type, Value *ptr, ArrayRef index_list) { -#if LLVM_VERSION >= 130 return builder->CreateInBoundsGEP(gep_type, ptr, index_list); -#else - return builder->CreateInBoundsGEP(ptr, index_list); -#endif } // Get the LLVM linkage corresponding to a Halide linkage type. @@ -1126,25 +1117,14 @@ void CodeGen_LLVM::optimize_module() { // 21.04 -> 14.78 using current ToT release build. (See also https://reviews.llvm.org/rL358304) pto.ForgetAllSCEVInLoopUnroll = true; -#if LLVM_VERSION >= 130 llvm::PassBuilder pb(tm.get(), pto); -#else - llvm::PassBuilder pb(/*DebugLogging*/ false, tm.get(), pto); -#endif bool debug_pass_manager = false; // These analysis managers have to be declared in this order. -#if LLVM_VERSION >= 130 llvm::LoopAnalysisManager lam; llvm::FunctionAnalysisManager fam; llvm::CGSCCAnalysisManager cgam; llvm::ModuleAnalysisManager mam; -#else - llvm::LoopAnalysisManager lam(debug_pass_manager); - llvm::FunctionAnalysisManager fam(debug_pass_manager); - llvm::CGSCCAnalysisManager cgam(debug_pass_manager); - llvm::ModuleAnalysisManager mam(debug_pass_manager); -#endif llvm::AAManager aa = pb.buildDefaultAAPipeline(); fam.registerPass([&] { return std::move(aa); }); @@ -1155,11 +1135,7 @@ void CodeGen_LLVM::optimize_module() { pb.registerFunctionAnalyses(fam); pb.registerLoopAnalyses(lam); pb.crossRegisterProxies(lam, fam, cgam, mam); -#if LLVM_VERSION >= 130 ModulePassManager mpm; -#else - ModulePassManager mpm(debug_pass_manager); -#endif #if LLVM_VERSION >= 140 using OptimizationLevel = llvm::OptimizationLevel; @@ -1246,15 +1222,9 @@ void CodeGen_LLVM::optimize_module() { } } -#if LLVM_VERSION >= 130 if (tm) { tm->registerPassBuilderCallbacks(pb); } -#else - if (tm) { - tm->registerPassBuilderCallbacks(pb, debug_pass_manager); - } -#endif mpm = pb.buildPerModuleDefaultPipeline(level, debug_pass_manager); mpm.run(*module, mam); @@ -2376,11 +2346,7 @@ llvm::Value *CodeGen_LLVM::codegen_dense_vector_load(const Type &type, const std Instruction *load_inst; if (vpred != nullptr) { Value *slice_mask = slice_vector(vpred, i, slice_lanes); -#if LLVM_VERSION >= 130 load_inst = builder->CreateMaskedLoad(slice_type, vec_ptr, llvm::Align(align_bytes), slice_mask); -#else - load_inst = builder->CreateMaskedLoad(vec_ptr, llvm::Align(align_bytes), slice_mask); -#endif } else { load_inst = builder->CreateAlignedLoad(slice_type, vec_ptr, llvm::Align(align_bytes)); } @@ -2467,20 +2433,11 @@ void CodeGen_LLVM::codegen_atomic_rmw(const Store *op) { Value *ptr = codegen_buffer_pointer(op->name, op->value.type(), op->index); -#if LLVM_VERSION >= 130 if (value_type.is_float()) { builder->CreateAtomicRMW(AtomicRMWInst::FAdd, ptr, val, llvm::MaybeAlign(), AtomicOrdering::Monotonic); } else { builder->CreateAtomicRMW(AtomicRMWInst::Add, ptr, val, llvm::MaybeAlign(), AtomicOrdering::Monotonic); } -#else - // llvm 9 has FAdd which can be used for atomic floats. - if (value_type.is_float()) { - builder->CreateAtomicRMW(AtomicRMWInst::FAdd, ptr, val, AtomicOrdering::Monotonic); - } else { - builder->CreateAtomicRMW(AtomicRMWInst::Add, ptr, val, AtomicOrdering::Monotonic); - } -#endif } else { Value *index = codegen(op->index); // Scalarize vector store. @@ -2489,19 +2446,11 @@ void CodeGen_LLVM::codegen_atomic_rmw(const Store *op) { Value *idx = builder->CreateExtractElement(index, lane); Value *v = builder->CreateExtractElement(val, lane); Value *ptr = codegen_buffer_pointer(op->name, value_type.element_of(), idx); -#if LLVM_VERSION >= 130 if (value_type.is_float()) { builder->CreateAtomicRMW(AtomicRMWInst::FAdd, ptr, v, llvm::MaybeAlign(), AtomicOrdering::Monotonic); } else { builder->CreateAtomicRMW(AtomicRMWInst::Add, ptr, v, llvm::MaybeAlign(), AtomicOrdering::Monotonic); } -#else - if (value_type.is_float()) { - builder->CreateAtomicRMW(AtomicRMWInst::FAdd, ptr, v, AtomicOrdering::Monotonic); - } else { - builder->CreateAtomicRMW(AtomicRMWInst::Add, ptr, v, AtomicOrdering::Monotonic); - } -#endif } } } else { @@ -2564,13 +2513,8 @@ void CodeGen_LLVM::codegen_atomic_rmw(const Store *op) { val = builder->CreateBitCast(val, int_type); cmp_val = builder->CreateBitCast(cmp_val, int_type); } -#if LLVM_VERSION >= 130 Value *cmpxchg_pair = builder->CreateAtomicCmpXchg( ptr, cmp_val, val, llvm::MaybeAlign(), AtomicOrdering::Monotonic, AtomicOrdering::Monotonic); -#else - Value *cmpxchg_pair = builder->CreateAtomicCmpXchg( - ptr, cmp_val, val, AtomicOrdering::Monotonic, AtomicOrdering::Monotonic); -#endif Value *val_loaded = builder->CreateExtractValue(cmpxchg_pair, 0, "val_loaded"); Value *success = builder->CreateExtractValue(cmpxchg_pair, 1, "success"); if (need_bit_cast) { diff --git a/src/CodeGen_PTX_Dev.cpp b/src/CodeGen_PTX_Dev.cpp index 1baa55bbd1d0..c6ee48dd0826 100644 --- a/src/CodeGen_PTX_Dev.cpp +++ b/src/CodeGen_PTX_Dev.cpp @@ -544,7 +544,6 @@ string CodeGen_PTX_Dev::march() const { string CodeGen_PTX_Dev::mcpu() const { if (target.has_feature(Target::CUDACapability86)) { - user_assert(LLVM_VERSION >= 130) << "The linked LLVM version does not support cuda compute capability 8.6\n"; return "sm_86"; } else if (target.has_feature(Target::CUDACapability80)) { return "sm_80"; @@ -615,11 +614,6 @@ vector CodeGen_PTX_Dev::compile_to_src() { options.HonorSignDependentRoundingFPMathOption = false; options.NoZerosInBSS = false; options.GuaranteedTailCallOpt = false; -#if LLVM_VERSION >= 130 - // nothing -#else - options.StackAlignmentOverride = 0; -#endif std::unique_ptr target_machine(llvm_target->createTargetMachine(triple.str(), diff --git a/src/CodeGen_WebAssembly.cpp b/src/CodeGen_WebAssembly.cpp index 726330e47931..83dc6775fc5f 100644 --- a/src/CodeGen_WebAssembly.cpp +++ b/src/CodeGen_WebAssembly.cpp @@ -61,17 +61,10 @@ const WasmIntrinsic intrinsic_defs[] = { {"llvm.uadd.sat.v16i8", UInt(8, 16), "saturating_add", {UInt(8, 16), UInt(8, 16)}, Target::WasmSimd128}, // TODO: Are these really different than the standard llvm.*sub.sat.*? -#if LLVM_VERSION >= 130 {"llvm.wasm.sub.sat.signed.v16i8", Int(8, 16), "saturating_sub", {Int(8, 16), Int(8, 16)}, Target::WasmSimd128}, {"llvm.wasm.sub.sat.unsigned.v16i8", UInt(8, 16), "saturating_sub", {UInt(8, 16), UInt(8, 16)}, Target::WasmSimd128}, {"llvm.wasm.sub.sat.signed.v8i16", Int(16, 8), "saturating_sub", {Int(16, 8), Int(16, 8)}, Target::WasmSimd128}, {"llvm.wasm.sub.sat.unsigned.v8i16", UInt(16, 8), "saturating_sub", {UInt(16, 8), UInt(16, 8)}, Target::WasmSimd128}, -#else - {"llvm.wasm.sub.saturate.signed.v16i8", Int(8, 16), "saturating_sub", {Int(8, 16), Int(8, 16)}, Target::WasmSimd128}, - {"llvm.wasm.sub.saturate.unsigned.v16i8", UInt(8, 16), "saturating_sub", {UInt(8, 16), UInt(8, 16)}, Target::WasmSimd128}, - {"llvm.wasm.sub.saturate.signed.v8i16", Int(16, 8), "saturating_sub", {Int(16, 8), Int(16, 8)}, Target::WasmSimd128}, - {"llvm.wasm.sub.saturate.unsigned.v8i16", UInt(16, 8), "saturating_sub", {UInt(16, 8), UInt(16, 8)}, Target::WasmSimd128}, -#endif {"llvm.wasm.avgr.unsigned.v16i8", UInt(8, 16), "rounding_halving_add", {UInt(8, 16), UInt(8, 16)}, Target::WasmSimd128}, {"llvm.wasm.avgr.unsigned.v8i16", UInt(16, 8), "rounding_halving_add", {UInt(16, 8), UInt(16, 8)}, Target::WasmSimd128}, @@ -80,7 +73,6 @@ const WasmIntrinsic intrinsic_defs[] = { {"float_to_double", Float(64, 4), "float_to_double", {Float(32, 4)}, Target::WasmSimd128}, #endif -#if LLVM_VERSION >= 130 // With some work, some of these could possibly be adapted to work under earlier versions of LLVM. {"widening_mul_i8x16", Int(16, 16), "widening_mul", {Int(8, 16), Int(8, 16)}, Target::WasmSimd128}, {"widening_mul_i16x8", Int(32, 8), "widening_mul", {Int(16, 8), Int(16, 8)}, Target::WasmSimd128}, @@ -118,7 +110,6 @@ const WasmIntrinsic intrinsic_defs[] = { {"extend_u16x8_to_u32x8", UInt(32, 8), "widen_integer", {UInt(16, 8)}, Target::WasmSimd128}, {"extend_i32x4_to_i64x4", Int(64, 4), "widen_integer", {Int(32, 4)}, Target::WasmSimd128}, {"extend_u32x4_to_u64x4", UInt(64, 4), "widen_integer", {UInt(32, 4)}, Target::WasmSimd128}, -#endif }; // clang-format on @@ -147,7 +138,6 @@ void CodeGen_WebAssembly::init_module() { } void CodeGen_WebAssembly::visit(const Cast *op) { -#if LLVM_VERSION >= 130 struct Pattern { std::string intrin; ///< Name of the intrinsic Expr pattern; ///< The pattern to match against @@ -189,13 +179,11 @@ void CodeGen_WebAssembly::visit(const Cast *op) { } } } -#endif // LLVM_VERSION >= 130 CodeGen_Posix::visit(op); } void CodeGen_WebAssembly::codegen_vector_reduce(const VectorReduce *op, const Expr &init) { -#if LLVM_VERSION >= 130 struct Pattern { VectorReduce::Operator reduce_op; int factor; @@ -264,7 +252,6 @@ void CodeGen_WebAssembly::codegen_vector_reduce(const VectorReduce *op, const Ex } } } -#endif // LLVM_VERSION >= 130 CodeGen_Posix::codegen_vector_reduce(op, init); } diff --git a/src/ExtractTileOperations.cpp b/src/ExtractTileOperations.cpp index 08df3ff7e39f..54a32d756afd 100644 --- a/src/ExtractTileOperations.cpp +++ b/src/ExtractTileOperations.cpp @@ -260,12 +260,6 @@ Matmul convert_to_matmul(const Store *op, const string &new_name, AMXOpType op_t return {}; } -#if LLVM_VERSION < 130 - user_assert(op_type != AMXOpType::Bfloat16 && - lhs_load->type.is_int() && rhs_cast->value.type().is_int()) - << "LLVM 13 or above is required for unsigned or float AMX instructions"; -#endif - // {rows, colbytes, var, index} auto lhs_var = Variable::make(Handle(), lhs_load->name); const auto &lhs_load_type = lhs_load->type; diff --git a/src/LLVM_Headers.h b/src/LLVM_Headers.h index f23362a2d79f..42f44e0428c4 100644 --- a/src/LLVM_Headers.h +++ b/src/LLVM_Headers.h @@ -1,10 +1,10 @@ #ifndef HALIDE_LLVM_HEADERS_H #define HALIDE_LLVM_HEADERS_H -#if LLVM_VERSION >= 120 +#if LLVM_VERSION >= 130 // We're good to go #else -#error "Compiling Halide requires LLVM 12.0 or newer" +#error "Compiling Halide requires LLVM 13.0 or newer" #endif // No msvc warnings from llvm headers please diff --git a/src/Random.cpp b/src/Random.cpp index bb132a9ea536..111ec73ebb5e 100644 --- a/src/Random.cpp +++ b/src/Random.cpp @@ -64,7 +64,7 @@ Expr rng32(const Expr &x) { } // namespace Expr random_int(const vector &e) { - internal_assert(e.size()); + internal_assert(!e.empty()); internal_assert(e[0].type() == Int(32) || e[0].type() == UInt(32)); // Permute the first term Expr result = rng32(cast(UInt(32), e[0])); diff --git a/src/Target.cpp b/src/Target.cpp index d838902b1081..ab4af5072006 100644 --- a/src/Target.cpp +++ b/src/Target.cpp @@ -326,7 +326,7 @@ Target::Feature calculate_host_cuda_capability(Target t) { return Target::CUDACapability70; } else if (ver < 80) { return Target::CUDACapability75; - } else if (ver < 86 || LLVM_VERSION < 130) { + } else if (ver < 86) { return Target::CUDACapability80; } else { return Target::CUDACapability86; diff --git a/test/correctness/simd_op_check.cpp b/test/correctness/simd_op_check.cpp index a6760f6a290b..51872615a201 100644 --- a/test/correctness/simd_op_check.cpp +++ b/test/correctness/simd_op_check.cpp @@ -1766,27 +1766,17 @@ class SimdOpCheck : public SimdOpCheckTest { if (use_wasm_simd128) { for (int w = 1; w <= 4; w <<= 1) { // create arbitrary 16-byte constant - if (Halide::Internal::get_llvm_version() >= 130) { - check("v128.const", 16 * w, u8_1 * u8(42 + x)); - } + check("v128.const", 16 * w, u8_1 * u8(42 + x)); // Create vector with identical lanes // (Note that later LLVMs will use 64-bit constants for some smaller splats) check("i8x16.splat", 16 * w, u8_1 * u8(42)); - if (Halide::Internal::get_llvm_version() >= 130) { - // LLVM13 likes to emit all of these as v128.const - check("v128.const", 8 * w, u16_1 * u16(42)); - check("v128.const", 4 * w, u32_1 * u32(42)); - check("v128.const", 2 * w, u64_1 * u64(42)); - check("v128.const", 8 * w, f32_1 * f32(42)); - check("v128.const", 4 * w, f64_1 * f64(42)); - } else { - check("i64x2.splat", 8 * w, u16_1 * u16(42)); - check("i64x2.splat", 4 * w, u32_1 * u32(42)); - check("i64x2.splat", 2 * w, u64_1 * u64(42)); - check("f32x4.splat", 8 * w, f32_1 * f32(42)); - check("f64x2.splat", 4 * w, f64_1 * f64(42)); - } + // LLVM13 likes to emit all of these as v128.const + check("v128.const", 8 * w, u16_1 * u16(42)); + check("v128.const", 4 * w, u32_1 * u32(42)); + check("v128.const", 2 * w, u64_1 * u64(42)); + check("v128.const", 8 * w, f32_1 * f32(42)); + check("v128.const", 4 * w, f64_1 * f64(42)); // Extract lane as a scalar (extract_lane) // Replace lane value (replace_lane) @@ -1826,13 +1816,11 @@ class SimdOpCheck : public SimdOpCheckTest { check("i32x4.mul", 4 * w, i32_1 * i32_2); check("i64x2.mul", 2 * w, i64_1 * i64_2); - if (Halide::Internal::get_llvm_version() >= 130) { - // Integer dot product (16 -> 32) - for (int f : {2, 4, 8}) { - RDom r(0, f); - for (int v : {1, 2, 4}) { - check("i32x4.dot_i16x8_s", w * v, sum(i32(in_i16(f * x + r)) * in_i16(f * x + r + 32))); - } + // Integer dot product (16 -> 32) + for (int f : {2, 4, 8}) { + RDom r(0, f); + for (int v : {1, 2, 4}) { + check("i32x4.dot_i16x8_s", w * v, sum(i32(in_i16(f * x + r)) * in_i16(f * x + r + 32))); } } @@ -1842,72 +1830,65 @@ class SimdOpCheck : public SimdOpCheckTest { check("i32x4.neg", 4 * w, -i32_1); check("i64x2.neg", 2 * w, -i64_1); - if (Halide::Internal::get_llvm_version() >= 130) { - // At present, we only attempt to generate these for LLVM >= 13. - - // Extended (widening) integer multiplication - if (w > 1) { - // Need a register wider than 128 bits for us to generate these - check("i16x8.extmul_low_i8x16_s", 8 * w, i16(i8_1) * i8_2); - check("i32x4.extmul_low_i16x8_s", 4 * w, i32(i16_1) * i16_2); - check("i64x2.extmul_low_i32x4_s", 2 * w, i64(i32_1) * i32_2); - check("i16x8.extmul_low_i8x16_u", 8 * w, u16(u8_1) * u8_2); - check("i32x4.extmul_low_i16x8_u", 4 * w, u32(u16_1) * u16_2); - check("i64x2.extmul_low_i32x4_u", 2 * w, u64(u32_1) * u32_2); - check("i16x8.extmul_high_i8x16_s", 8 * w, i16(i8_1) * i8_2); - check("i32x4.extmul_high_i16x8_s", 4 * w, i32(i16_1) * i16_2); - check("i64x2.extmul_high_i32x4_s", 2 * w, i64(i32_1) * i32_2); - check("i16x8.extmul_high_i8x16_u", 8 * w, u16(u8_1) * u8_2); - check("i32x4.extmul_high_i16x8_u", 4 * w, u32(u16_1) * u16_2); - check("i64x2.extmul_high_i32x4_u", 2 * w, u64(u32_1) * u32_2); - } + // Extended (widening) integer multiplication + if (w > 1) { + // Need a register wider than 128 bits for us to generate these + check("i16x8.extmul_low_i8x16_s", 8 * w, i16(i8_1) * i8_2); + check("i32x4.extmul_low_i16x8_s", 4 * w, i32(i16_1) * i16_2); + check("i64x2.extmul_low_i32x4_s", 2 * w, i64(i32_1) * i32_2); + check("i16x8.extmul_low_i8x16_u", 8 * w, u16(u8_1) * u8_2); + check("i32x4.extmul_low_i16x8_u", 4 * w, u32(u16_1) * u16_2); + check("i64x2.extmul_low_i32x4_u", 2 * w, u64(u32_1) * u32_2); + check("i16x8.extmul_high_i8x16_s", 8 * w, i16(i8_1) * i8_2); + check("i32x4.extmul_high_i16x8_s", 4 * w, i32(i16_1) * i16_2); + check("i64x2.extmul_high_i32x4_s", 2 * w, i64(i32_1) * i32_2); + check("i16x8.extmul_high_i8x16_u", 8 * w, u16(u8_1) * u8_2); + check("i32x4.extmul_high_i16x8_u", 4 * w, u32(u16_1) * u16_2); + check("i64x2.extmul_high_i32x4_u", 2 * w, u64(u32_1) * u32_2); + } - // Extended pairwise integer addition - for (int f : {2, 4}) { - RDom r(0, f); + // Extended pairwise integer addition + for (int f : {2, 4}) { + RDom r(0, f); - // A summation reduction that starts at something - // non-trivial, to avoid llvm simplifying accumulating - // widening summations into just widening summations. - auto sum_ = [&](Expr e) { - Func f; - f(x) = cast(e.type(), 123); - f(x) += e; - return f(x); - }; - - check("i16x8.extadd_pairwise_i8x16_s", 8 * w, sum_(i16(in_i8(f * x + r)))); - check("i16x8.extadd_pairwise_i8x16_u", 8 * w, sum_(u16(in_u8(f * x + r)))); - // The u8->i16 op uses the unsigned variant - check("i16x8.extadd_pairwise_i8x16_u", 8 * w, sum_(i16(in_u8(f * x + r)))); - - check("i32x4.extadd_pairwise_i16x8_s", 8 * w, sum_(i32(in_i16(f * x + r)))); - check("i32x4.extadd_pairwise_i16x8_u", 8 * w, sum_(u32(in_u16(f * x + r)))); - // The u16->i32 op uses the unsigned variant - check("i32x4.extadd_pairwise_i16x8_u", 8 * w, sum_(i32(in_u16(f * x + r)))); - } + // A summation reduction that starts at something + // non-trivial, to avoid llvm simplifying accumulating + // widening summations into just widening summations. + auto sum_ = [&](Expr e) { + Func f; + f(x) = cast(e.type(), 123); + f(x) += e; + return f(x); + }; + + check("i16x8.extadd_pairwise_i8x16_s", 8 * w, sum_(i16(in_i8(f * x + r)))); + check("i16x8.extadd_pairwise_i8x16_u", 8 * w, sum_(u16(in_u8(f * x + r)))); + // The u8->i16 op uses the unsigned variant + check("i16x8.extadd_pairwise_i8x16_u", 8 * w, sum_(i16(in_u8(f * x + r)))); + + check("i32x4.extadd_pairwise_i16x8_s", 8 * w, sum_(i32(in_i16(f * x + r)))); + check("i32x4.extadd_pairwise_i16x8_u", 8 * w, sum_(u32(in_u16(f * x + r)))); + // The u16->i32 op uses the unsigned variant + check("i32x4.extadd_pairwise_i16x8_u", 8 * w, sum_(i32(in_u16(f * x + r)))); } // Saturating integer addition - std::string sat = Halide::Internal::get_llvm_version() >= 130 ? "sat" : "saturate"; - check("i8x16.add_" + sat + "_s", 16 * w, i8_sat(i16(i8_1) + i16(i8_2))); - check("i8x16.add_" + sat + "_u", 16 * w, u8_sat(u16(u8_1) + u16(u8_2))); - check("i16x8.add_" + sat + "_s", 8 * w, i16_sat(i32(i16_1) + i32(i16_2))); - check("i16x8.add_" + sat + "_u", 8 * w, u16_sat(u32(u16_1) + u32(u16_2))); + check("i8x16.add_sat_s", 16 * w, i8_sat(i16(i8_1) + i16(i8_2))); + check("i8x16.add_sat_u", 16 * w, u8_sat(u16(u8_1) + u16(u8_2))); + check("i16x8.add_sat_s", 8 * w, i16_sat(i32(i16_1) + i32(i16_2))); + check("i16x8.add_sat_u", 8 * w, u16_sat(u32(u16_1) + u32(u16_2))); // Saturating integer subtraction - check("i8x16.sub_" + sat + "_s", 16 * w, i8_sat(i16(i8_1) - i16(i8_2))); - check("i16x8.sub_" + sat + "_s", 8 * w, i16_sat(i32(i16_1) - i32(i16_2))); + check("i8x16.sub_sat_s", 16 * w, i8_sat(i16(i8_1) - i16(i8_2))); + check("i16x8.sub_sat_s", 8 * w, i16_sat(i32(i16_1) - i32(i16_2))); // N.B. Saturating subtracts are expressed by widening to a *signed* type - check("i8x16.sub_" + sat + "_u", 16 * w, u8_sat(i16(u8_1) - i16(u8_2))); - check("i16x8.sub_" + sat + "_u", 8 * w, u16_sat(i32(u16_1) - i32(u16_2))); - - if (Halide::Internal::get_llvm_version() >= 130) { - // Saturating integer Q-format rounding multiplication - // Note: division in Halide always rounds down (not towards - // zero). Otherwise these patterns would be more complicated. - check("i16x8.q15mulr_sat_s", 8 * w, i16_sat((i32(i16_1) * i32(i16_2) + (1 << 14)) / (1 << 15))); - } + check("i8x16.sub_sat_u", 16 * w, u8_sat(i16(u8_1) - i16(u8_2))); + check("i16x8.sub_sat_u", 8 * w, u16_sat(i32(u16_1) - i32(u16_2))); + + // Saturating integer Q-format rounding multiplication + // Note: division in Halide always rounds down (not towards + // zero). Otherwise these patterns would be more complicated. + check("i16x8.q15mulr_sat_s", 8 * w, i16_sat((i32(i16_1) * i32(i16_2) + (1 << 14)) / (1 << 15))); // Lane-wise integer minimum check("i8x16.min_s", 16 * w, min(i8_1, i8_2)); @@ -1935,9 +1916,7 @@ class SimdOpCheck : public SimdOpCheckTest { check("i8x16.abs", 16 * w, abs(i8_1)); check("i16x8.abs", 8 * w, abs(i16_1)); check("i32x4.abs", 4 * w, abs(i32_1)); - if (Halide::Internal::get_llvm_version() >= 130) { - check("i64x2.abs", 2 * w, abs(i64_1)); - } + check("i64x2.abs", 2 * w, abs(i64_1)); // Left shift by constant scalar check("i8x16.shl", 16 * w, i8_1 << i8(7)); @@ -2046,9 +2025,7 @@ class SimdOpCheck : public SimdOpCheckTest { check("i8x16.eq", 16 * w, i8_1 == i8_2); check("i16x8.eq", 8 * w, i16_1 == i16_2); check("i32x4.eq", 4 * w, i32_1 == i32_2); - if (Halide::Internal::get_llvm_version() >= 130) { - check("i64x2.eq", 2 * w, i64_1 == i64_2); - } + check("i64x2.eq", 2 * w, i64_1 == i64_2); check("f32x4.eq", 4 * w, f32_1 == f32_2); check("f64x2.eq", 2 * w, f64_1 == f64_2); @@ -2056,9 +2033,7 @@ class SimdOpCheck : public SimdOpCheckTest { check("i8x16.ne", 16 * w, i8_1 != i8_2); check("i16x8.ne", 8 * w, i16_1 != i16_2); check("i32x4.ne", 4 * w, i32_1 != i32_2); - if (Halide::Internal::get_llvm_version() >= 130) { - check("i64x2.ne", 2 * w, i64_1 != i64_2); - } + check("i64x2.ne", 2 * w, i64_1 != i64_2); check("f32x4.ne", 4 * w, f32_1 != f32_2); check("f64x2.ne", 2 * w, f64_1 != f64_2); @@ -2069,9 +2044,7 @@ class SimdOpCheck : public SimdOpCheckTest { check("i16x8.lt_u", 8 * w, u16_1 < u16_2); check("i32x4.lt_s", 4 * w, i32_1 < i32_2); check("i32x4.lt_u", 4 * w, u32_1 < u32_2); - if (Halide::Internal::get_llvm_version() >= 130) { - check("i64x2.lt_s", 2 * w, i64_1 < i64_2); - } + check("i64x2.lt_s", 2 * w, i64_1 < i64_2); check("f32x4.lt", 4 * w, f32_1 < f32_2); check("f64x2.lt", 2 * w, f64_1 < f64_2); @@ -2082,9 +2055,7 @@ class SimdOpCheck : public SimdOpCheckTest { check("i16x8.le_u", 8 * w, u16_1 <= u16_2); check("i32x4.le_s", 4 * w, i32_1 <= i32_2); check("i32x4.le_u", 4 * w, u32_1 <= u32_2); - if (Halide::Internal::get_llvm_version() >= 130) { - check("i64x2.le_s", 2 * w, i64_1 <= i64_2); - } + check("i64x2.le_s", 2 * w, i64_1 <= i64_2); check("f32x4.le", 4 * w, f32_1 <= f32_2); check("f64x2.le", 2 * w, f64_1 <= f64_2); @@ -2175,23 +2146,21 @@ class SimdOpCheck : public SimdOpCheckTest { check("f32x4.sqrt", 4 * w, sqrt(f32_1)); check("f64x2.sqrt", 2 * w, sqrt(f64_1)); - if (Halide::Internal::get_llvm_version() >= 130) { - // Round to integer above (ceiling) - check("f32x4.ceil", 4 * w, ceil(f32_1)); - check("f64x2.ceil", 2 * w, ceil(f64_1)); + // Round to integer above (ceiling) + check("f32x4.ceil", 4 * w, ceil(f32_1)); + check("f64x2.ceil", 2 * w, ceil(f64_1)); - // Round to integer below (floor) - check("f32x4.floor", 4 * w, floor(f32_1)); - check("f64x2.floor", 2 * w, floor(f64_1)); + // Round to integer below (floor) + check("f32x4.floor", 4 * w, floor(f32_1)); + check("f64x2.floor", 2 * w, floor(f64_1)); - // Round to integer toward zero (truncate to integer) - check("f32x4.trunc", 4 * w, trunc(f32_1)); - check("f64x2.trunc", 2 * w, trunc(f64_1)); + // Round to integer toward zero (truncate to integer) + check("f32x4.trunc", 4 * w, trunc(f32_1)); + check("f64x2.trunc", 2 * w, trunc(f64_1)); - // Round to nearest integer, ties to even) - check("f32x4.nearest", 4 * w, round(f32_1)); - check("f64x2.nearest", 2 * w, round(f64_1)); - } + // Round to nearest integer, ties to even) + check("f32x4.nearest", 4 * w, round(f32_1)); + check("f64x2.nearest", 2 * w, round(f64_1)); // Integer to single-precision floating point check("f32x4.convert_i32x4_s", 8 * w, cast(i32_1)); @@ -2222,17 +2191,15 @@ class SimdOpCheck : public SimdOpCheckTest { if (w < 2) { check("f64x2.promote_low_f32x4", 2 * w, cast(f32_1)); } - } else if (Halide::Internal::get_llvm_version() >= 130) { + } else { check("f64x2.promote_low_f32x4", 2 * w, cast(f32_1)); } // Integer to integer narrowing - if (Halide::Internal::get_llvm_version() >= 130) { - check("i8x16.narrow_i16x8_s", 16 * w, i8_sat(i16_1)); - check("i8x16.narrow_i16x8_u", 16 * w, u8_sat(i16_1)); - check("i16x8.narrow_i32x4_s", 8 * w, i16_sat(i32_1)); - check("i16x8.narrow_i32x4_u", 8 * w, u16_sat(i32_1)); - } + check("i8x16.narrow_i16x8_s", 16 * w, i8_sat(i16_1)); + check("i8x16.narrow_i16x8_u", 16 * w, u8_sat(i16_1)); + check("i16x8.narrow_i32x4_s", 8 * w, i16_sat(i32_1)); + check("i16x8.narrow_i32x4_u", 8 * w, u16_sat(i32_1)); // Integer to integer widening check("i16x8.extend_low_i8x16_s", 16 * w, i16(i8_1)); diff --git a/test/correctness/tiled_matmul.cpp b/test/correctness/tiled_matmul.cpp index 7fbeedef3ecc..8c703b3faa3b 100644 --- a/test/correctness/tiled_matmul.cpp +++ b/test/correctness/tiled_matmul.cpp @@ -231,35 +231,32 @@ int main(int argc, char **argv) { printf("Success!\n"); } - // llvm >= 13.0 is required for unsigned and float AMX instructions - if (Halide::Internal::get_llvm_version() >= 130) { - printf("Running AMX matmul (signed/unsigned)\n"); - if (!matmul_su()) { - return -1; - } else { - printf("Success!\n"); - } + printf("Running AMX matmul (signed/unsigned)\n"); + if (!matmul_su()) { + return -1; + } else { + printf("Success!\n"); + } - printf("Running AMX matmul (unsigned/signed)\n"); - if (!matmul_us()) { - return -1; - } else { - printf("Success!\n"); - } + printf("Running AMX matmul (unsigned/signed)\n"); + if (!matmul_us()) { + return -1; + } else { + printf("Success!\n"); + } - printf("Running AMX matmul (unsigned/unsigned)\n"); - if (!matmul_uu()) { - return -1; - } else { - printf("Success!\n"); - } + printf("Running AMX matmul (unsigned/unsigned)\n"); + if (!matmul_uu()) { + return -1; + } else { + printf("Success!\n"); + } - printf("Running AMX matmul (bf16)\n"); - if (!matmul_bf16()) { - return -1; - } else { - printf("Success!\n"); - } + printf("Running AMX matmul (bf16)\n"); + if (!matmul_bf16()) { + return -1; + } else { + printf("Success!\n"); } return 0; } \ No newline at end of file