diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 02303c5e6cc57..d646f47761186 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -150,3 +150,20 @@ clang/test/AST/Interp/ @tbaederr /llvm/**/DWARFLinker/ @JDevlieghere /llvm/**/dsymutil/ @JDevlieghere /llvm/**/llvm-dwarfutil/ @JDevlieghere + +# BEGIN COMPILER COURSE +# CI +.github/** @aobolensk @Kuznetsov-Artyom + +# Clang +/clang/compiler-course/** @aobolensk @m-ly4 @Kuznetsov-Artyom +/clang/test/compiler-course/** @aobolensk @m-ly4 @Kuznetsov-Artyom + +# LLVM +/llvm/compiler-course/** @aobolensk @m-ly4 @Kuznetsov-Artyom +/llvm/test/compiler-course/** @aobolensk @m-ly4 @Kuznetsov-Artyom + +# MLIR +/mlir/compiler-course/** @aobolensk @m-ly4 @Kuznetsov-Artyom +/mlir/test/compiler-course/** @aobolensk @m-ly4 @Kuznetsov-Artyom +# END COMPILER COURSE diff --git a/.github/deadline.py b/.github/deadline.py new file mode 100644 index 0000000000000..0b3b8a44dbfe9 --- /dev/null +++ b/.github/deadline.py @@ -0,0 +1,36 @@ +import os +import sys +from github import Github +from datetime import datetime +from zoneinfo import ZoneInfo + + +def main(): + moscow_tz = ZoneInfo("Europe/Moscow") + current_date = datetime.now(moscow_tz) + deadline_date = { + "lab:clang": datetime(2025, 6, 1, hour=19, tzinfo=moscow_tz), + "lab:llvm ir": datetime(2025, 6, 1, hour=19, tzinfo=moscow_tz), + "lab:backend": datetime(2025, 6, 1, hour=19, tzinfo=moscow_tz), + "lab:mlir": datetime(2025, 6, 1, hour=19, tzinfo=moscow_tz), + } + + gh = Github(os.environ["GITHUB_TOKEN"]) + repo = gh.get_repo(os.environ["GITHUB_REPOSITORY"]) + pr = repo.get_pull(int(os.environ["PR_NUMBER"])) + labels = ["lab:clang", "lab:llvm ir", "lab:backend", "lab:mlir"] + lab_label = None + + for label in pr.get_labels(): + if label.name in labels: + lab_label = label.name + + if not lab_label: + return + + if current_date > deadline_date[lab_label]: + pr.add_to_labels("delayed") + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/.github/labeler.yml b/.github/labeler.yml new file mode 100644 index 0000000000000..4201fd9ae4b57 --- /dev/null +++ b/.github/labeler.yml @@ -0,0 +1,16 @@ +'lab:clang': + - "clang/compiler-course/**" +'lab:llvm ir': + - "llvm/compiler-course/llvm-ir/**" +'lab:backend': + - "llvm/compiler-course/backend/**" +'lab:mlir': + - "mlir/compiler-course/**" + +tests: + - "clang/test/compiler-course/**" + - "llvm/test/compiler-course/**" + - "mlir/test/compiler-course/**" + +ci: + - ".github/**" diff --git a/.github/workflows/compiler-course-build.yml b/.github/workflows/compiler-course-build.yml new file mode 100644 index 0000000000000..e0d32823ada70 --- /dev/null +++ b/.github/workflows/compiler-course-build.yml @@ -0,0 +1,117 @@ +name: Build LLVM +on: [push, pull_request] + +jobs: + ubuntu-gcc-build: + runs-on: ubuntu-latest + strategy: + matrix: + assertions: [ON, OFF] + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 1 + - name: Setup environment + run: | + sudo apt-get install -y \ + build-essential \ + ninja-build \ + - name: Setup ccache + uses: hendrikmuhs/ccache-action@v1.2 + with: + max-size: 500M + key: ccache-${{ github.job }} + - name: Build + run: | + cmake -S llvm -B build \ + -DCMAKE_BUILD_TYPE=Release \ + -DLLVM_ENABLE_PROJECTS="clang;mlir" \ + -DLLVM_ENABLE_ASSERTIONS=${{ matrix.assertions }} \ + -DCMAKE_C_COMPILER_LAUNCHER=ccache \ + -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \ + -DLLVM_TARGETS_TO_BUILD="X86;AArch64" \ + -G Ninja + cmake --build build --config Release -j $(nproc) + - name: Test + run: | + cmake --build build --config Release -t \ + check-llvm-compiler-course \ + check-clang-compiler-course \ + check-mlir-compiler-course -j $(nproc) + macos-build: + runs-on: macOS-latest + strategy: + matrix: + assertions: [ON, OFF] + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 1 + - name: Setup environment + run: | + brew install \ + ninja + - name: Setup ccache + uses: hendrikmuhs/ccache-action@v1.2 + with: + max-size: 500M + key: ccache-${{ github.job }} + - name: Build + run: | + cmake -S llvm -B build \ + -DCMAKE_BUILD_TYPE=Release \ + -DLLVM_ENABLE_PROJECTS="clang;mlir" \ + -DLLVM_ENABLE_ASSERTIONS=${{ matrix.assertions }} \ + -DCMAKE_C_COMPILER_LAUNCHER=ccache \ + -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \ + -DLLVM_TARGETS_TO_BUILD="X86;AArch64" \ + -G Ninja + cmake --build build --config Release -j $(nproc) + - name: Test + run: | + cmake --build build --config Release -t \ + check-llvm-compiler-course \ + check-clang-compiler-course \ + check-mlir-compiler-course -j $(nproc) + windows-build: + runs-on: windows-latest + strategy: + matrix: + assertions: [ON, OFF] + steps: + - name: Setup Windows + uses: llvm/actions/setup-windows@main + with: + arch: amd64 + - name: Setup Python + uses: actions/setup-python@v4 + with: + python-version: ${{ inputs.python_version }} + - name: Install Ninja + uses: llvm/actions/install-ninja@main + - uses: actions/checkout@v4 + with: + fetch-depth: 250 + - name: Setup ccache + uses: hendrikmuhs/ccache-action@v1 + with: + max-size: 2G + variant: sccache + - name: Build + shell: bash + id: build-llvm + run: | + builddir="$(pwd)"/build + echo "llvm-builddir=$builddir" >> "$GITHUB_OUTPUT" + cmake -G Ninja \ + -B "$builddir" \ + -S llvm \ + -DLLVM_ENABLE_PROJECTS="clang" \ + -DCMAKE_BUILD_TYPE=Release \ + -DLLVM_ENABLE_ASSERTIONS=${{ matrix.assertions }} \ + -DLLDB_INCLUDE_TESTS=OFF \ + -DCMAKE_C_COMPILER_LAUNCHER=sccache \ + -DCMAKE_CXX_COMPILER_LAUNCHER=sccache \ + -DLLVM_TARGETS_TO_BUILD="X86;AArch64" \ + ${{ inputs.extra_cmake_args }} + ninja -C "$builddir" all diff --git a/.github/workflows/compiler-course-tidy.yml b/.github/workflows/compiler-course-tidy.yml new file mode 100644 index 0000000000000..7e0bf5a963d5f --- /dev/null +++ b/.github/workflows/compiler-course-tidy.yml @@ -0,0 +1,43 @@ +name: Static analysis +on: [pull_request] + +jobs: + clang-format: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Install clang-format + run: | + sudo apt-get install -y clang-format + - name: Run clang-format + run: | + git-clang-format --diff `git merge-base ${GITHUB_SHA} ${GITHUB_BASE_REF}` + clang-tidy: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + - name: Update submodules + run: git submodule update --init --recursive + - name: ccache + uses: hendrikmuhs/ccache-action@v1.2 + with: + key: ${{ github.job }} + - uses: aobolensk/clang-tidy-review@v0.20.1-patch-clang-tidy-19 + id: review + with: + build_dir: build + cmake_command: cmake -S llvm -B build + -DCMAKE_BUILD_TYPE=Release + -DLLVM_ENABLE_PROJECTS='clang;mlir' + -DLLVM_ENABLE_ASSERTIONS=ON + -DCMAKE_C_COMPILER_LAUNCHER=ccache + -DCMAKE_CXX_COMPILER_LAUNCHER=ccache + -G Ninja + config_file: .clang-tidy + apt_packages: build-essential,ninja-build + split_workflow: true + env: + CC: clang-19 + CXX: clang++-19 diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml new file mode 100644 index 0000000000000..e36d8ef12ecb7 --- /dev/null +++ b/.github/workflows/labeler.yml @@ -0,0 +1,28 @@ +name: "Label bot" +on: + - pull_request_target + +jobs: + label-bot: + runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: write + steps: + - name: Check out repository + uses: actions/checkout@v4.2.2 + - name: Add labels + uses: actions/labeler@v4 + with: + repo-token: "${{ secrets.GITHUB_TOKEN }}" + configuration-path: ".github/labeler.yml" + dot: true + - name: Install PyGithub + run: | + pip3 install PyGithub + - name: Check deadline + env: + GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} + PR_NUMBER: ${{github.event.number}} + run: | + python3 .github/deadline.py diff --git a/README.md b/README.md index a9b29ecbc1a3a..ebd30a67f8fab 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,35 @@ -# The LLVM Compiler Infrastructure +# Compiler course 2025 -[![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/llvm/llvm-project/badge)](https://securityscorecards.dev/viewer/?uri=github.com/llvm/llvm-project) -[![OpenSSF Best Practices](https://www.bestpractices.dev/projects/8273/badge)](https://www.bestpractices.dev/projects/8273) -[![libc++](https://github.com/llvm/llvm-project/actions/workflows/libcxx-build-and-test.yaml/badge.svg?branch=main&event=schedule)](https://github.com/llvm/llvm-project/actions/workflows/libcxx-build-and-test.yaml?query=event%3Aschedule) +[![Build LLVM](https://github.com/NN-complr-tech/compiler-course-2025/actions/workflows/compiler-course-build.yml/badge.svg)](https://github.com/NN-complr-tech/compiler-course-2025/actions/workflows/compiler-course-build.yml) -Welcome to the LLVM project! +# Resources +- [Telegram сhat][chat] +- [Telegram сhannel][channel] +- [Tasks and results][results] +- Materials + - [Lecture recordings][recording] + - [Lecture presentations][lecture] + - [LLVM][llvm] + - [MLIR][mlir] + - [Clang][clang] + - [Official YouTube channel LLVM][youtube_llvm] + + + +[results]: https://docs.google.com/spreadsheets/d/1LiZ5FMd5t61yoGdnpANTFpzqtKD_ejtvLl1cHKZxvXQ/edit?usp=sharing + +[channel]: https://t.me/+TPntKPD8z0E3OWJi +[chat]: https://t.me/+JG3n1jeSAiIxZjMy + +[recording]: https://disk.yandex.ru/d/52gu5vJTSt1VFg +[lecture]: https://github.com/NN-complr-tech/Complr-course-lectures +[llvm]: https://llvm.org/ +[mlir]: https://mlir.llvm.org/ +[clang]: https://clang.llvm.org/ +[youtube_llvm]: https://www.youtube.com/@LLVMPROJ + +# What is LLVM? +LLLVM is a set of compiler and toolchain technologies that can be used to develop a frontend for any programming language and a backend for any instruction set architecture. LLVM is designed around a language-independent intermediate representation (IR) that serves as a portable, high-level assembly language that can be optimized with a variety of transformations over multiple passes. The name LLVM originally stood for Low Level Virtual Machine, though the project has expanded and the name is no longer officially an initialism. This repository contains the source code for LLVM, a toolkit for the construction of highly optimized compilers, optimizers, and run-time @@ -16,29 +41,91 @@ files needed to process intermediate representations and convert them into object files. Tools include an assembler, disassembler, bitcode analyzer, and bitcode optimizer. -C-like languages use the [Clang](https://clang.llvm.org/) frontend. This -component compiles C, C++, Objective-C, and Objective-C++ code into LLVM bitcode --- and from there into object files, using LLVM. - -Other components include: -the [libc++ C++ standard library](https://libcxx.llvm.org), -the [LLD linker](https://lld.llvm.org), and more. - -## Getting the Source Code and Building LLVM +# 0. Intro +This course will consist of 4 laboratory work. As part of the laboratory works, you will study all stages of compilation, starting with the generation of the AST tree, ending with code generation. -Consult the -[Getting Started with LLVM](https://llvm.org/docs/GettingStarted.html#getting-the-source-code-and-building-llvm) -page for information on building and running LLVM. +## Note +Recommended OS - Linux (WSL). -For information on how to contribute to the LLVM project, please take a look at -the [Contributing to LLVM](https://llvm.org/docs/Contributing.html) guide. +# 1. Clone repository +1. Create fork this repository +2. Clone local fork +```bash +git clone https://github.com//llvm.git +cd llvm/ +git checkout -b +``` -## Getting in touch +# 2. Setup environment +```bash +sudo apt-get update \ + && sudo apt-get install -q -y --no-install-recommends \ + git \ + cmake \ + ccache \ + mold \ + clang \ + build-essential \ + ninja-build \ + python3 \ + python3-pip \ + wget \ + vim +``` -Join the [LLVM Discourse forums](https://discourse.llvm.org/), [Discord -chat](https://discord.gg/xS7Z362), -[LLVM Office Hours](https://llvm.org/docs/GettingInvolved.html#office-hours) or -[Regular sync-ups](https://llvm.org/docs/GettingInvolved.html#online-sync-ups). +# 3. Build project +```bash +cmake -G Ninja -S llvm -B build \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_CXX_COMPILER=clang++ \ + -DCMAKE_C_COMPILER=clang \ + -DLLVM_USE_LINKER=mold \ + -DLLVM_CCACHE_BUILD=ON \ + -DLLVM_ENABLE_ASSERTIONS=ON \ + -DLLVM_ENABLE_PROJECTS="clang;mlir" \ + -DLLVM_TARGETS_TO_BUILD=X86 # specify your target architecture (X86, Aarch64) +cmake --build build --config Release -j 4 +``` +# 4. Where to implement laboratory work? +Each directory has an implementation example. -The LLVM project has adopted a [code of conduct](https://llvm.org/docs/CodeOfConduct.html) for -participants to all modes of communication within the project. +## ClangAST lab +```bash +cd clang/compiler-course/ # for labs +``` +```bash +cd clang/test/compiler-course/ # for tests +``` +## LLVM IR lab +```bash +cd llvm/compiler-course/llvm-ir/ # for labs +``` +```bash +cd llvm/test/compiler-course/ # for tests +``` +## Backend lab +```bash +cd llvm/compiler-course/backend/ # for labs +``` +```bash +cd llvm/test/compiler-course/ # for tests +``` +## MLIR lab +```bash MLIR +cd mlir/compiler-course/ # for labs +``` +```bash MLIR +cd mlir/test/compiler-course/ # for tests +``` +# 5. Run tests +For all tests +```bash +cmake --build build --config Release -t \ + check-llvm-compiler-course \ + check-clang-compiler-course \ + check-mlir-compiler-course -j 4 +``` +For one test +```bash +./build/bin/llvm-lit -v /path/to/test_file +``` diff --git a/clang/CMakeLists.txt b/clang/CMakeLists.txt index c6496167d3828..69d917dbeb7d8 100644 --- a/clang/CMakeLists.txt +++ b/clang/CMakeLists.txt @@ -940,3 +940,8 @@ set(CLANG_INSTALL_LIBDIR_BASENAME "lib${CLANG_LIBDIR_SUFFIX}") configure_file( ${CLANG_SOURCE_DIR}/include/clang/Config/config.h.cmake ${CLANG_BINARY_DIR}/include/clang/Config/config.h) + +# BEGIN COMPILER COURSE +include(${LLVM_COMMON_CMAKE_UTILS}/Modules/UtilsCompilerCourse.cmake) +add_subdirectory(compiler-course) +# END COMPILER COURSE diff --git a/clang/compiler-course/CMakeLists.txt b/clang/compiler-course/CMakeLists.txt new file mode 100644 index 0000000000000..3a38ea06822df --- /dev/null +++ b/clang/compiler-course/CMakeLists.txt @@ -0,0 +1,5 @@ +if (CLANG_PLUGIN_SUPPORT) + list_subdirs(subdirs ${CMAKE_CURRENT_SOURCE_DIR}) + add_subdirs(subdirs "COMPILER COURSE (ClangAST)") + set(CLANG_TEST_DEPS ${CLANG_TEST_DEPS} PARENT_SCOPE) +endif() diff --git a/clang/compiler-course/example/CMakeLists.txt b/clang/compiler-course/example/CMakeLists.txt new file mode 100644 index 0000000000000..4ff6a244c48ec --- /dev/null +++ b/clang/compiler-course/example/CMakeLists.txt @@ -0,0 +1,18 @@ +set(Title "ExamplePlugin") +set(Student "Ivanov_Ivan") +set(Group "FIIT0") +set(TARGET_NAME "${Title}_${Student}_${Group}_ClangAST") + +file(GLOB_RECURSE SOURCES *.cpp *.h *.hpp) +add_llvm_library(${TARGET_NAME} MODULE ${SOURCES} PLUGIN_TOOL clang) + +if(WIN32 OR CYGWIN) + set(LLVM_LINK_COMPONENTS Support) + clang_target_link_libraries(${TARGET_NAME} PRIVATE + clangAST + clangBasic + clangFrontend + ) +endif() + +set(CLANG_TEST_DEPS "${TARGET_NAME}" ${CLANG_TEST_DEPS} PARENT_SCOPE) diff --git a/clang/compiler-course/example/example.cpp b/clang/compiler-course/example/example.cpp new file mode 100644 index 0000000000000..d85cf9f09206c --- /dev/null +++ b/clang/compiler-course/example/example.cpp @@ -0,0 +1,47 @@ +#include "clang/AST/ASTConsumer.h" +#include "clang/AST/RecursiveASTVisitor.h" +#include "clang/Frontend/CompilerInstance.h" +#include "clang/Frontend/FrontendPluginRegistry.h" +#include "llvm/Support/raw_ostream.h" + +namespace { +class ExampleVisitor final : public clang::RecursiveASTVisitor { +public: + explicit ExampleVisitor(clang::ASTContext *context) : m_context(context) {} + bool VisitFunctionDecl(clang::FunctionDecl *func) { + func->dump(); + return true; + } + +private: + clang::ASTContext *m_context; +}; + +class ExampleConsumer final : public clang::ASTConsumer { +public: + explicit ExampleConsumer(clang::ASTContext *context) : m_visitor(context) {} + + void HandleTranslationUnit(clang::ASTContext &context) override { + m_visitor.TraverseDecl(context.getTranslationUnitDecl()); + } + +private: + ExampleVisitor m_visitor; +}; + +class ExampleAction final : public clang::PluginASTAction { +public: + std::unique_ptr + CreateASTConsumer(clang::CompilerInstance &ci, llvm::StringRef) override { + return std::make_unique(&ci.getASTContext()); + } + + bool ParseArgs(const clang::CompilerInstance &ci, + const std::vector &args) override { + return true; + } +}; +} // namespace + +static clang::FrontendPluginRegistry::Add + X("example_plugin", "Description plugin"); diff --git a/clang/compiler-course/my_plugin/CMakeLists.txt b/clang/compiler-course/my_plugin/CMakeLists.txt new file mode 100644 index 0000000000000..21a93afcfb6a7 --- /dev/null +++ b/clang/compiler-course/my_plugin/CMakeLists.txt @@ -0,0 +1,18 @@ +set(Title "ClangPlugin") +set(Student "KholinKirill") +set(Group "3822B1FI3") +set(TARGET_NAME "${Title}_${Student}_${Group}_ClangAST") + +file(GLOB_RECURSE SOURCES *.cpp *.h *.hpp) +add_llvm_library(${TARGET_NAME} MODULE ${SOURCES} PLUGIN_TOOL clang) + +if(WIN32 OR CYGWIN) + set(LLVM_LINK_COMPONENTS Support) + clang_target_link_libraries(${TARGET_NAME} PRIVATE + clangAST + clangBasic + clangFrontend + ) +endif() + +set(CLANG_TEST_DEPS "${TARGET_NAME}" ${CLANG_TEST_DEPS} PARENT_SCOPE) diff --git a/clang/compiler-course/my_plugin/my_plugin.cpp b/clang/compiler-course/my_plugin/my_plugin.cpp new file mode 100644 index 0000000000000..f0b14cbf1177a --- /dev/null +++ b/clang/compiler-course/my_plugin/my_plugin.cpp @@ -0,0 +1,146 @@ +#include "clang/AST/ASTConsumer.h" +#include "clang/AST/RecursiveASTVisitor.h" +#include "clang/Frontend/CompilerInstance.h" +#include "clang/Frontend/FrontendPluginRegistry.h" +#include "clang/Rewrite/Core/Rewriter.h" +#include "llvm/Support/raw_ostream.h" +#include + +using namespace clang; + +class FindNamedClassVisitor + : public RecursiveASTVisitor { +public: + explicit FindNamedClassVisitor(ASTContext *Context, Rewriter &R) + : Context(Context), Rewrite(R) {} + + bool VisitVarDecl(VarDecl *Decl) { + if (!Decl) + return false; + + std::string VarPrefix; + if (Decl->isFileVarDecl() && !Decl->isStaticLocal()) { + VarPrefix = "global_"; + } else if (Decl->isStaticLocal()) { + VarPrefix = "static_"; + } else if (Decl->isLocalVarDecl() && !isa(Decl)) { + VarPrefix = "local_"; + } + + if (!VarPrefix.empty()) { + std::string NewID = VarPrefix + Decl->getNameAsString(); + SourceLocation StartLocation = Decl->getLocation(); + SourceLocation EndLocation = + StartLocation.getLocWithOffset(Decl->getNameAsString().length()); + Rewrite.ReplaceText(SourceRange(StartLocation, EndLocation), NewID); + + FullSourceLoc FullLocation = Context->getFullLoc(StartLocation); + if (FullLocation.isValid()) { + llvm::outs() << "Found variable: " << Decl->getNameAsString() << " -> " + << NewID << " at " + << FullLocation.getSpellingLineNumber() << ":" + << FullLocation.getSpellingColumnNumber() << "\n"; + } + } + + return true; + } + + bool VisitParmVarDecl(ParmVarDecl *Decl) { + if (!Decl) + return false; + + std::string VarParmPrefix = "param_"; + std::string NewID = VarParmPrefix + Decl->getNameAsString(); + SourceLocation StartLocation = Decl->getLocation(); + SourceLocation EndLocation = + StartLocation.getLocWithOffset(Decl->getNameAsString().length()); + Rewrite.ReplaceText(SourceRange(StartLocation, EndLocation), NewID); + + FullSourceLoc FullLocation = Context->getFullLoc(StartLocation); + if (FullLocation.isValid()) { + llvm::outs() << "Found parameter: " << Decl->getNameAsString() << " -> " + << NewID << " at " << FullLocation.getSpellingLineNumber() + << ":" << FullLocation.getSpellingColumnNumber() << "\n"; + } + + return true; + } + + bool VisitDeclRefExpr(DeclRefExpr *Expr) { + if (!Expr) + return false; + + VarDecl *Decl = dyn_cast(Expr->getDecl()); + if (!Decl) + return false; + + std::string VarPrefix; + if (Decl->isFileVarDecl() && !Decl->isStaticLocal()) { + VarPrefix = "global_"; + } else if (Decl->isStaticLocal()) { + VarPrefix = "static_"; + } else if (Decl->isLocalVarDecl() && !isa(Decl)) { + VarPrefix = "local_"; + } else if (isa(Decl)) { + VarPrefix = "param_"; + } + + if (!VarPrefix.empty()) { + std::string NewID = VarPrefix + Decl->getNameAsString(); + SourceLocation StartLocation = Expr->getLocation(); + SourceLocation EndLocation = + StartLocation.getLocWithOffset(Decl->getNameAsString().length()); + Rewrite.ReplaceText(SourceRange(StartLocation, EndLocation), NewID); + + FullSourceLoc FullLocation = Context->getFullLoc(StartLocation); + if (FullLocation.isValid()) { + llvm::outs() << "Found reference: " << Decl->getNameAsString() << " -> " + << NewID << " at " + << FullLocation.getSpellingLineNumber() << ":" + << FullLocation.getSpellingColumnNumber() << "\n"; + } + } + + return true; + } + +private: + ASTContext *Context; + Rewriter &Rewrite; +}; + +class FindNamedClassConsumer : public clang::ASTConsumer { +public: + explicit FindNamedClassConsumer(ASTContext *Context, Rewriter &R) + : Visitor(Context, R) {} + + void HandleTranslationUnit(ASTContext &Context) override { + Visitor.TraverseDecl(Context.getTranslationUnitDecl()); + } + +private: + FindNamedClassVisitor Visitor; +}; + +class FindNamedClassAction : public clang::PluginASTAction { +public: + std::unique_ptr + CreateASTConsumer(CompilerInstance &Compiler, + llvm::StringRef InFile) override { + Rewriter.setSourceMgr(Compiler.getSourceManager(), Compiler.getLangOpts()); + return std::make_unique(&Compiler.getASTContext(), + Rewriter); + } + + bool ParseArgs(const CompilerInstance &CI, + const std::vector &Args) override { + return true; + } + +private: + Rewriter Rewriter; +}; + +static clang::FrontendPluginRegistry::Add + X("ClangPlugin", "set prefixes"); \ No newline at end of file diff --git a/clang/test/compiler-course/example/test.cpp b/clang/test/compiler-course/example/test.cpp new file mode 100644 index 0000000000000..b8dc4e33d433d --- /dev/null +++ b/clang/test/compiler-course/example/test.cpp @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -load %llvmshlibdir/ExamplePlugin_Ivanov_Ivan_FIIT0_ClangAST%pluginext -plugin example_plugin -fsyntax-only %s 2>&1 | FileCheck %s + +// CHECK: FunctionDecl {{0x[0-9a-fA-F]+}} <{{.*}}> col:20 isEven 'bool (int) noexcept' +// CHECK-NEXT: |-ParmVarDecl {{0x[0-9a-fA-F]+}} col:31 used value 'int' +// CHECK-NEXT: |-CompoundStmt {{0x[0-9a-fA-F]+}} +// CHECK-NEXT: | `-ReturnStmt {{0x[0-9a-fA-F]+}} +// CHECK-NEXT: | `-BinaryOperator {{0x[0-9a-fA-F]+}} 'bool' '==' +// CHECK-NEXT: | |-BinaryOperator {{0x[0-9a-fA-F]+}} 'int' '%' +// CHECK-NEXT: | | |-ImplicitCastExpr {{0x[0-9a-fA-F]+}} 'int' +// CHECK-NEXT: | | | `-DeclRefExpr {{0x[0-9a-fA-F]+}} 'int' lvalue ParmVar {{0x[0-9a-fA-F]+}} 'value' 'int' +// CHECK-NEXT: | | `-IntegerLiteral {{0x[0-9a-fA-F]+}} 'int' 2 +// CHECK-NEXT: | `-IntegerLiteral {{0x[0-9a-fA-F]+}} 'int' 0 +// CHECK-NEXT: `-WarnUnusedResultAttr {{0x[0-9a-fA-F]+}} nodiscard "" + +[[nodiscard]] bool isEven(int value) noexcept { return value % 2 == 0; } diff --git a/clang/test/compiler-course/my_test/test.cpp b/clang/test/compiler-course/my_test/test.cpp new file mode 100644 index 0000000000000..adc2f63db917e --- /dev/null +++ b/clang/test/compiler-course/my_test/test.cpp @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -load %llvmshlibdir/ClangPlugin_KholinKirill_3822B1FI3_ClangAST%pluginext -plugin ClangPlugin %s -fsyntax-only 2>&1 | FileCheck -v %s + +// CHECK: Found variable: var1 -> global_var1 +// CHECK: Found parameter: a -> param_a +// CHECK: Found parameter: b -> param_b +// CHECK: Found variable: var2 -> static_var2 +// CHECK: Found variable: var3 -> local_var3 +// CHECK: Found reference: var1 -> global_var1 +// CHECK: Found reference: var2 -> static_var2 +// CHECK: Found reference: var3 -> local_var3 + +int var1 = 0; + +int foo(int a, int b) { + static int var2 = 0; + int var3 = 123; + ++var2; + return a + b + var1 + var2 + var3; +} \ No newline at end of file diff --git a/cmake/Modules/UtilsCompilerCourse.cmake b/cmake/Modules/UtilsCompilerCourse.cmake new file mode 100644 index 0000000000000..77efe8515eb2e --- /dev/null +++ b/cmake/Modules/UtilsCompilerCourse.cmake @@ -0,0 +1,27 @@ +macro(list_subdirs result curdir) + file(GLOB children RELATIVE ${curdir} ${curdir}/*) + set(dirlist "") + foreach(child ${children}) + if(IS_DIRECTORY ${curdir}/${child}) + list(APPEND dirlist ${child}) + endif() + endforeach() + set(${result} ${dirlist}) +endmacro() + +macro(add_subdirs subdirs label) + if(${subdirs}) + set(dirs "${${subdirs}}") + message("") + message("${label}") + message("__________________________________________________________________") + set(index 1) + foreach(dir ${dirs}) + message("${index}. ${dir}") + add_subdirectory(${dir}) + math(EXPR index "${index} + 1") + endforeach(dir ${dirs}) + message("__________________________________________________________________") + message("") + endif() +endmacro() diff --git a/llvm/CMakeLists.txt b/llvm/CMakeLists.txt index 12618966c4adf..9e372f9427a45 100644 --- a/llvm/CMakeLists.txt +++ b/llvm/CMakeLists.txt @@ -1423,3 +1423,9 @@ endif() if (LLVM_INCLUDE_UTILS AND LLVM_INCLUDE_TOOLS) add_subdirectory(utils/llvm-locstats) endif() + +# BEGIN COMPILER COURSE +set(PATH_TO_X86 ${CMAKE_CURRENT_SOURCE_DIR}/lib/Target/X86) +include(${LLVM_COMMON_CMAKE_UTILS}/Modules/UtilsCompilerCourse.cmake) +add_subdirectory(compiler-course) +# END COMPILER COURSE diff --git a/llvm/compiler-course/CMakeLists.txt b/llvm/compiler-course/CMakeLists.txt new file mode 100644 index 0000000000000..a1806a3a8784e --- /dev/null +++ b/llvm/compiler-course/CMakeLists.txt @@ -0,0 +1,3 @@ +add_subdirectory(llvm-ir) +add_subdirectory(backend) +set(LLVM_TEST_DEPENDS ${LLVM_TEST_DEPENDS} PARENT_SCOPE) diff --git a/llvm/compiler-course/backend/CMakeLists.txt b/llvm/compiler-course/backend/CMakeLists.txt new file mode 100644 index 0000000000000..01a969f6124c4 --- /dev/null +++ b/llvm/compiler-course/backend/CMakeLists.txt @@ -0,0 +1,6 @@ +if(NOT WIN32 AND NOT CYGWIN) + include_directories(${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/Target/X86) + list_subdirs(subdirs ${CMAKE_CURRENT_SOURCE_DIR}) + add_subdirs(subdirs "COMPILER COURSE (BACKEND)") + set(LLVM_TEST_DEPENDS ${LLVM_TEST_DEPENDS} PARENT_SCOPE) +endif() diff --git a/llvm/compiler-course/backend/example/CMakeLists.txt b/llvm/compiler-course/backend/example/CMakeLists.txt new file mode 100644 index 0000000000000..faa7d75a54bd9 --- /dev/null +++ b/llvm/compiler-course/backend/example/CMakeLists.txt @@ -0,0 +1,17 @@ +set(Title "ExamplePass") +set(Student "Ivanov_Ivan") +set(Group "FIIT0") +set(TARGET_NAME "${Title}_${Student}_${Group}_BACKEND") + +file(GLOB_RECURSE SOURCES *.cpp *.h *.hpp) + +add_llvm_pass_plugin(${TARGET_NAME} + ${SOURCES} + DEPENDS + intrinsics_gen + X86 + BUILDTREE_ONLY +) + +target_include_directories(${TARGET_NAME} PUBLIC ${PATH_TO_X86}) +set(LLVM_TEST_DEPENDS ${TARGET_NAME} ${LLVM_TEST_DEPENDS} PARENT_SCOPE) diff --git a/llvm/compiler-course/backend/example/ExamplePass.cpp b/llvm/compiler-course/backend/example/ExamplePass.cpp new file mode 100644 index 0000000000000..2af4287a11d6a --- /dev/null +++ b/llvm/compiler-course/backend/example/ExamplePass.cpp @@ -0,0 +1,26 @@ +#include "X86.h" +#include "X86InstrInfo.h" +#include "X86Subtarget.h" +#include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/CodeGen/MachineInstrBuilder.h" + +using namespace llvm; + +namespace { +class ExamplePass : public MachineFunctionPass { +public: + static char ID; + ExamplePass() : MachineFunctionPass(ID) {} + bool runOnMachineFunction(MachineFunction &MF) override; +}; + +char ExamplePass::ID = 0; + +bool ExamplePass::runOnMachineFunction(MachineFunction &func) { + llvm::outs() << func.getName() << '\n'; + return true; +} +} // namespace + +static RegisterPass X("example-x86", "description pass", false, + false); diff --git a/llvm/compiler-course/llvm-ir/CMakeLists.txt b/llvm/compiler-course/llvm-ir/CMakeLists.txt new file mode 100644 index 0000000000000..3d9d084895148 --- /dev/null +++ b/llvm/compiler-course/llvm-ir/CMakeLists.txt @@ -0,0 +1,3 @@ +list_subdirs(subdirs ${CMAKE_CURRENT_SOURCE_DIR}) +add_subdirs(subdirs "COMPILER COURSE (LLVM-IR)") +set(LLVM_TEST_DEPENDS ${LLVM_TEST_DEPENDS} PARENT_SCOPE) diff --git a/llvm/compiler-course/llvm-ir/example/CMakeLists.txt b/llvm/compiler-course/llvm-ir/example/CMakeLists.txt new file mode 100644 index 0000000000000..1f4b067737c3d --- /dev/null +++ b/llvm/compiler-course/llvm-ir/example/CMakeLists.txt @@ -0,0 +1,14 @@ +set(Title "ExamplePass") +set(Student "Ivanov_Ivan") +set(Group "FIIT0") +set(TARGET_NAME "${Title}_${Student}_${Group}_LLVM_IR") + +if (NOT WIN32 AND NOT CYGWIN) + file(GLOB_RECURSE SOURCES *.cpp *.h *.hpp) + add_llvm_pass_plugin(${TARGET_NAME} ${SOURCES} + DEPENDS + intrinsics_gen + BUILDTREE_ONLY + ) + set(LLVM_TEST_DEPENDS ${TARGET_NAME} ${LLVM_TEST_DEPENDS} PARENT_SCOPE) +endif() diff --git a/llvm/compiler-course/llvm-ir/example/ExamplePass.cpp b/llvm/compiler-course/llvm-ir/example/ExamplePass.cpp new file mode 100644 index 0000000000000..e4ea86c5762fa --- /dev/null +++ b/llvm/compiler-course/llvm-ir/example/ExamplePass.cpp @@ -0,0 +1,33 @@ +#include "llvm/IR/Function.h" +#include "llvm/IR/Instructions.h" +#include "llvm/Passes/PassBuilder.h" +#include "llvm/Passes/PassPlugin.h" +#include "llvm/Support/raw_ostream.h" + +namespace { +struct ExamplePass : llvm::PassInfoMixin { + llvm::PreservedAnalyses run(llvm::Function &func, + llvm::FunctionAnalysisManager &) { + llvm::outs() << func.getName() << '\n'; + return llvm::PreservedAnalyses::all(); + } + + static bool isRequired() { return true; } +}; +} // namespace + +extern "C" LLVM_ATTRIBUTE_WEAK ::llvm::PassPluginLibraryInfo +llvmGetPassPluginInfo() { + return {LLVM_PLUGIN_API_VERSION, "ExamplePass", "0.1", + [](llvm::PassBuilder &PB) { + PB.registerPipelineParsingCallback( + [](llvm::StringRef name, llvm::FunctionPassManager &FPM, + llvm::ArrayRef) -> bool { + if (name == "example") { + FPM.addPass(ExamplePass{}); + return true; + } + return false; + }); + }}; +} diff --git a/llvm/test/CMakeLists.txt b/llvm/test/CMakeLists.txt index 6b7f2b58e603e..92d2ef3a1d452 100644 --- a/llvm/test/CMakeLists.txt +++ b/llvm/test/CMakeLists.txt @@ -56,7 +56,7 @@ configure_lit_site_cfg( # Set the depends list as a variable so that it can grow conditionally. # NOTE: Sync the substitutions in test/lit.cfg when adding to this list. -set(LLVM_TEST_DEPENDS +set(LLVM_TEST_DEPENDS ${LLVM_TEST_DEPENDS} BugpointPasses FileCheck LLVMWindowsDriver diff --git a/llvm/test/compiler-course/example/test_backend.mir b/llvm/test/compiler-course/example/test_backend.mir new file mode 100644 index 0000000000000..633deb89708aa --- /dev/null +++ b/llvm/test/compiler-course/example/test_backend.mir @@ -0,0 +1,98 @@ +# RUN: llc -mtriple x86_64-unknown-linux-gnu --load=%llvmshlibdir/ExamplePass_Ivanov_Ivan_FIIT0_BACKEND%shlibext \ +# RUN: -run-pass=example-x86 %s -o - | FileCheck %s + + +# Source files + +# test.cpp +# +# [[nodiscard]] bool isEven(int value) noexcept { return value % 2 == 0; } + +# test.ll (-O2) +# +# define dso_local noundef zeroext i1 @_Z6isEveni(i32 noundef %0) local_unnamed_addr { +# %2 = and i32 %0, 1 +# %3 = icmp eq i32 %2, 0 +# ret i1 %3 +# } + + +--- | + ; ModuleID = 'test.ll' + source_filename = "test.ll" + target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128" + + define dso_local noundef zeroext i1 @_Z6isEveni(i32 noundef %0) local_unnamed_addr { + %2 = and i32 %0, 1 + %3 = icmp eq i32 %2, 0 + ret i1 %3 + } + +... +--- +# CHECK: _Z6isEveni +# CHECK: name: _Z6isEveni +name: _Z6isEveni +alignment: 16 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +failedISel: false +tracksRegLiveness: true +hasWinCFI: false +callsEHReturn: false +callsUnwindInit: false +hasEHCatchret: false +hasEHScopes: false +hasEHFunclets: false +isOutlined: false +debugInstrRef: true +failsVerification: false +tracksDebugUserValues: true +registers: [] +liveins: + - { reg: '$edi', virtual-reg: '' } +frameInfo: + isFrameAddressTaken: false + isReturnAddressTaken: false + hasStackMap: false + hasPatchPoint: false + stackSize: 0 + offsetAdjustment: 0 + maxAlignment: 1 + adjustsStack: false + hasCalls: false + stackProtector: '' + functionContext: '' + maxCallFrameSize: 0 + cvBytesOfCalleeSavedRegisters: 0 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + hasTailCall: false + isCalleeSavedInfoValid: true + localFrameSize: 0 + savePoint: '' + restorePoint: '' +fixedStack: [] +stack: [] +entry_values: [] +callSites: [] +debugValueSubstitutions: [] +constants: [] +machineFunctionInfo: + amxProgModel: None +body: | + bb.0 (%ir-block.1): + liveins: $edi + + ; CHECK: TEST8ri renamable $dil, 1, implicit-def $eflags, implicit killed $edi + ; CHECK-NEXT: renamable $al = SETCCr 4, implicit killed $eflags + ; CHECK-NEXT: RET64 $al + + TEST8ri renamable $dil, 1, implicit-def $eflags, implicit killed $edi + renamable $al = SETCCr 4, implicit killed $eflags + RET64 $al + +... diff --git a/llvm/test/compiler-course/example/test_llvm_ir.ll b/llvm/test/compiler-course/example/test_llvm_ir.ll new file mode 100644 index 0000000000000..0b1cab6f66341 --- /dev/null +++ b/llvm/test/compiler-course/example/test_llvm_ir.ll @@ -0,0 +1,13 @@ +; RUN: opt -load-pass-plugin %llvmshlibdir/ExamplePass_Ivanov_Ivan_FIIT0_LLVM_IR%pluginext\ +; RUN: -passes=example -S %s | FileCheck %s + +; CHECK: _Z6isEveni + +define dso_local noundef zeroext i1 @_Z6isEveni(i32 noundef %0) { + %2 = alloca i32, align 4 + store i32 %0, ptr %2, align 4 + %3 = load i32, ptr %2, align 4 + %4 = srem i32 %3, 2 + %5 = icmp eq i32 %4, 0 + ret i1 %5 +} diff --git a/llvm/test/tools/opt-viewer/lit.local.cfg b/llvm/test/tools/opt-viewer/lit.local.cfg index d181a93eb8464..c8d3f305562db 100644 --- a/llvm/test/tools/opt-viewer/lit.local.cfg +++ b/llvm/test/tools/opt-viewer/lit.local.cfg @@ -8,3 +8,6 @@ if "have_opt_viewer_modules" not in config.available_features: # can be resolved. if sys.platform == "win32": config.unsupported = True + +if sys.platform == "darwin": + config.unsupported = True diff --git a/mlir/CMakeLists.txt b/mlir/CMakeLists.txt index c6d44908a1111..f4f9b404dac98 100644 --- a/mlir/CMakeLists.txt +++ b/mlir/CMakeLists.txt @@ -285,3 +285,8 @@ endif() if(MLIR_STANDALONE_BUILD) llvm_distribution_add_targets() endif() + +# BEGIN COMPILER COURSE +include(${LLVM_COMMON_CMAKE_UTILS}/Modules/UtilsCompilerCourse.cmake) +add_subdirectory(compiler-course) +# END COMPILER COURSE diff --git a/mlir/compiler-course/CMakeLists.txt b/mlir/compiler-course/CMakeLists.txt new file mode 100644 index 0000000000000..9b996b6f55c01 --- /dev/null +++ b/mlir/compiler-course/CMakeLists.txt @@ -0,0 +1,3 @@ +list_subdirs(subdirs ${CMAKE_CURRENT_SOURCE_DIR}) +add_subdirs(subdirs "COMPILER COURSE (MLIR)") +set(MLIR_TEST_DEPENDS ${MLIR_TEST_DEPENDS} PARENT_SCOPE) diff --git a/mlir/compiler-course/example/CMakeLists.txt b/mlir/compiler-course/example/CMakeLists.txt new file mode 100644 index 0000000000000..2da67471abf54 --- /dev/null +++ b/mlir/compiler-course/example/CMakeLists.txt @@ -0,0 +1,16 @@ +set(Title "ExamplePass") +set(Student "Ivanov_Ivan") +set(Group "FIIT0") +set(TARGET_NAME "${Title}_${Student}_${Group}_MLIR") + +file(GLOB_RECURSE SOURCES *.cpp *.h *.hpp) + +add_llvm_pass_plugin(${TARGET_NAME} + ${SOURCES} + DEPENDS + intrinsics_gen + MLIRBuiltinLocationAttributesIncGen + BUILDTREE_ONLY +) + +set(MLIR_TEST_DEPENDS ${TARGET_NAME} ${MLIR_TEST_DEPENDS} PARENT_SCOPE) diff --git a/mlir/compiler-course/example/ExamplePass.cpp b/mlir/compiler-course/example/ExamplePass.cpp new file mode 100644 index 0000000000000..513a19fb54b2d --- /dev/null +++ b/mlir/compiler-course/example/ExamplePass.cpp @@ -0,0 +1,40 @@ +#include "mlir/Dialect/LLVMIR/LLVMDialect.h" +#include "mlir/IR/PatternMatch.h" +#include "mlir/Pass/Pass.h" +#include "mlir/Tools/Plugins/PassPlugin.h" +#include "llvm/Support/raw_ostream.h" + +using namespace mlir; + +namespace { +class ExamplePass : public PassWrapper> { +public: + StringRef getArgument() const final { + return "ExamplePass_Ivanov_Ivan_FIIT0_MLIR"; + } + StringRef getDescription() const final { return "Description pass"; } + + void runOnOperation() override { + ModuleOp moduleOp = getOperation(); + OpBuilder builder(moduleOp); + + auto countOp = 0; + moduleOp.walk([&](Operation *op) { ++countOp; }); + + llvm::outs() << "Count operations: " << countOp << '\n'; + } +}; +} // namespace + +MLIR_DECLARE_EXPLICIT_TYPE_ID(ExamplePass) +MLIR_DEFINE_EXPLICIT_TYPE_ID(ExamplePass) + +mlir::PassPluginLibraryInfo getFunctionCallCounterPassPluginInfo() { + return {MLIR_PLUGIN_API_VERSION, "ExamplePass", "1.0", + []() { mlir::PassRegistration(); }}; +} + +extern "C" LLVM_ATTRIBUTE_WEAK mlir::PassPluginLibraryInfo +mlirGetPassPluginInfo() { + return getFunctionCallCounterPassPluginInfo(); +} diff --git a/mlir/test/compiler-course/example/test.mlir b/mlir/test/compiler-course/example/test.mlir new file mode 100644 index 0000000000000..aa981364978f7 --- /dev/null +++ b/mlir/test/compiler-course/example/test.mlir @@ -0,0 +1,23 @@ +// RUN: mlir-opt -load-pass-plugin=%mlir_lib_dir/ExamplePass_Ivanov_Ivan_FIIT0_MLIR%shlibext \ +// RUN: --pass-pipeline="builtin.module(ExamplePass_Ivanov_Ivan_FIIT0_MLIR)" %s | FileCheck %s + +// CHECK: Count operations: 7 +// CHECK-NEXT: module attributes {{.*}} { +// CHECK-NEXT: llvm.func local_unnamed_addr @_Z6isEveni(%arg0: i32 {llvm.noundef}) -> (i1 {llvm.noundef, llvm.zeroext}) attributes {{.*}} { +// CHECK-NEXT: %0 = llvm.mlir.constant(1 : i32) : i32 +// CHECK-NEXT: %1 = llvm.mlir.constant(0 : i32) : i32 +// CHECK-NEXT: %2 = llvm.and %arg0, %0 : i32 +// CHECK-NEXT: %3 = llvm.icmp "eq" %2, %1 : i32 +// CHECK-NEXT: llvm.return %3 : i1 +// CHECK-NEXT: } +// CHECK-NEXT: } + +module attributes {dlti.dl_spec = #dlti.dl_spec<#dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry, dense<32> : vector<4xi64>>, #dlti.dl_entry, dense<32> : vector<4xi64>>, #dlti.dl_entry, dense<64> : vector<4xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<4xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry<"dlti.endianness", "little">, #dlti.dl_entry<"dlti.stack_alignment", 128 : i64>>} { + llvm.func local_unnamed_addr @_Z6isEveni(%arg0: i32 {llvm.noundef}) -> (i1 {llvm.noundef, llvm.zeroext}) attributes {memory = #llvm.memory_effects, no_unwind, passthrough = ["mustprogress", "nofree", "norecurse", "nosync", ["uwtable", "2"], ["min-legal-vector-width", "0"], ["no-trapping-math", "true"], ["stack-protector-buffer-size", "8"], ["target-cpu", "x86-64"]], target_cpu = "x86-64", target_features = #llvm.target_features<["+cmov", "+cx8", "+fxsr", "+mmx", "+sse", "+sse2", "+x87"]>, tune_cpu = "generic", will_return} { + %0 = llvm.mlir.constant(1 : i32) : i32 + %1 = llvm.mlir.constant(0 : i32) : i32 + %2 = llvm.and %arg0, %0 : i32 + %3 = llvm.icmp "eq" %2, %1 : i32 + llvm.return %3 : i1 + } +}