Coder Social home page Coder Social logo

llvm / polygeist Goto Github PK

View Code? Open in Web Editor NEW
435.0 21.0 98.0 1.06 GB

C/C++ frontend for MLIR. Also features polyhedral optimizations, parallel optimizations, and more!

Home Page: https://polygeist.llvm.org

License: Other

CMake 1.12% C++ 60.82% C 16.58% MLIR 11.01% Python 0.31% Perl 0.28% R 0.22% Shell 2.13% Cuda 3.21% Dockerfile 0.04% Makefile 0.05% SWIG 4.21% TeX 0.02%

polygeist's Introduction

Build instructions

Requirements

  • Working C and C++ toolchains(compiler, linker)
  • cmake
  • make or ninja

1. Clone Polygeist

git clone --recursive https://github.com/llvm/Polygeist
cd Polygeist

2. Install LLVM, MLIR, Clang, and Polygeist

Option 1: Using pre-built LLVM, MLIR, and Clang

Polygeist can be built by providing paths to a pre-built MLIR and Clang toolchain.

  1. Build LLVM, MLIR, and Clang:
mkdir llvm-project/build
cd llvm-project/build
cmake -G Ninja ../llvm \
  -DLLVM_ENABLE_PROJECTS="mlir;clang" \
  -DLLVM_TARGETS_TO_BUILD="host" \
  -DLLVM_ENABLE_ASSERTIONS=ON \
  -DCMAKE_BUILD_TYPE=DEBUG
ninja
ninja check-mlir

To enable compilation to cuda add -DMLIR_ENABLE_CUDA_RUNNER=1 and remove -DLLVM_TARGETS_TO_BUILD="host" from the cmake arguments. (You may need to specify CUDACXX, CUDA_PATH, and/or -DCMAKE_CUDA_COMPILER)

To enable the ROCM backend add -DMLIR_ENABLE_ROCM_RUNNER=1 and remove -DLLVM_TARGETS_TO_BUILD="host" from the cmake arguments. (You may need to specify -DHIP_CLANG_INCLUDE_PATH, and/or ROCM_PATH)

For faster compilation we recommend using -DLLVM_USE_LINKER=lld.

  1. Build Polygeist:
mkdir build
cd build
cmake -G Ninja .. \
  -DMLIR_DIR=$PWD/../llvm-project/build/lib/cmake/mlir \
  -DCLANG_DIR=$PWD/../llvm-project/build/lib/cmake/clang \
  -DLLVM_TARGETS_TO_BUILD="host" \
  -DLLVM_ENABLE_ASSERTIONS=ON \
  -DCMAKE_BUILD_TYPE=DEBUG
ninja
ninja check-polygeist-opt && ninja check-cgeist

For faster compilation we recommend using -DPOLYGEIST_USE_LINKER=lld.

1. GPU backends

To enable the CUDA backend add -DPOLYGEIST_ENABLE_CUDA=1

To enable the ROCM backend add -DPOLYGEIST_ENABLE_ROCM=1

2. Polymer

To enable polymer, add -DPOLYGEIST_ENABLE_POLYMER=1

This will cause the cmake invokation to pull and build the dependencies for polymer. To specify a custom directory for the dependencies, specify -DPOLYMER_DEP_DIR=<absolute-dir>. The dependencies will be build using the tools/polymer/build_polymer_deps.sh.

To run the polymer tests, use ninja check-polymer.

Option 2: Using unified LLVM, MLIR, Clang, and Polygeist build

Polygeist can also be built as an external LLVM project using LLVM_EXTERNAL_PROJECTS.

  1. Build LLVM, MLIR, Clang, and Polygeist:
mkdir build
cd build
cmake -G Ninja ../llvm-project/llvm \
  -DLLVM_ENABLE_PROJECTS="clang;mlir" \
  -DLLVM_EXTERNAL_PROJECTS="polygeist" \
  -DLLVM_EXTERNAL_POLYGEIST_SOURCE_DIR=.. \
  -DLLVM_TARGETS_TO_BUILD="host" \
  -DLLVM_ENABLE_ASSERTIONS=ON \
  -DCMAKE_BUILD_TYPE=DEBUG
ninja
ninja check-polygeist-opt && ninja check-cgeist

ninja check-polygeist-opt runs the tests in Polygeist/test/polygeist-opt ninja check-cgeist runs the tests in Polygeist/tools/cgeist/Test

Citing Polygeist

If you use Polygeist, please consider citing the relevant publications:

@inproceedings{polygeistPACT,
  title = {Polygeist: Raising C to Polyhedral MLIR},
  author = {Moses, William S. and Chelini, Lorenzo and Zhao, Ruizhe and Zinenko, Oleksandr},
  booktitle = {Proceedings of the ACM International Conference on Parallel Architectures and Compilation Techniques},
  numpages = {12},
  location = {Virtual Event},
  series = {PACT '21},
  publisher = {Association for Computing Machinery},
  year = {2021},
  address = {New York, NY, USA},
  keywords = {Polygeist, MLIR, Polyhedral, LLVM, Compiler, C++, Pluto, Polly, OpenScop, Parallel, OpenMP, Affine, Raising, Transformation, Splitting, Automatic-Parallelization, Reduction, Polybench},
}
@inproceedings{10.1145/3572848.3577475,
  author = {Moses, William S. and Ivanov, Ivan R. and Domke, Jens and Endo, Toshio and Doerfert, Johannes and Zinenko, Oleksandr},
  title = {High-Performance GPU-to-CPU Transpilation and Optimization via High-Level Parallel Constructs},
  year = {2023},
  isbn = {9798400700156},
  publisher = {Association for Computing Machinery},
  address = {New York, NY, USA},
  url = {https://doi.org/10.1145/3572848.3577475},
  doi = {10.1145/3572848.3577475},
  booktitle = {Proceedings of the 28th ACM SIGPLAN Annual Symposium on Principles and Practice of Parallel Programming},
  pages = {119–134},
  numpages = {16},
  keywords = {MLIR, polygeist, CUDA, barrier synchronization},
  location = {Montreal, QC, Canada},
  series = {PPoPP '23}
}
@inproceedings{10444828,
  author = {Ivanov, Ivan R. and Zinenko, Oleksandr and Domke, Jens and Endo, Toshio and Moses, William S.},
  booktitle = {2024 IEEE/ACM International Symposium on Code Generation and Optimization (CGO)},
  title = {Retargeting and Respecializing GPU Workloads for Performance Portability},
  year = {2024},
  volume = {},
  issn = {},
  pages = {119-132},
  doi = {10.1109/CGO57630.2024.10444828},
  url = {https://doi.ieeecomputersociety.org/10.1109/CGO57630.2024.10444828},
  publisher = {IEEE Computer Society},
  address = {Los Alamitos, CA, USA},
  month = {mar}
}

polygeist's People

Contributors

andidr avatar anniezfy avatar aobolensk avatar arpitj1 avatar chelini avatar fanfuqiang-mt avatar ftynse avatar groverkss avatar gysit avatar hanchenye avatar ivanradanov avatar j2kun avatar jle-quel avatar keryell avatar kumasento avatar mikeurbach avatar mmoadeli avatar mortbopet avatar pietroghg avatar stephenneuendorffer avatar victor-eds avatar waautomaton avatar wsmoses avatar yangwang92 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

polygeist's Issues

Can you please provide use cases on how to run polybench?

I am trying to run the polybench with

./mlir-clang/mlir-clang ../mlir-clang/Test/polybench/linear-algebra/blas/gemm/gemm.c ../mlir-clang/Test/polybench/linear-algebra/blas/gemm/gemm.h ../mlir-clang/Test/polybench/utilities/polybench.h -S

But the compiler complains at #include <polybench.h>:

../mlir-clang/Test/polybench/linear-algebra/blas/gemm/gemm.c:37:10: fatal error: 'polybench.h' file not found

Could someone please provide me the correct command to run it?

Also, I see the interesting function EmitGPUCallExpr in mlir-clang/Lib/clang-mlir.cc. It seems now mlir-clang can emit GPU backend. Could you please also provide some examples on how to generate it?

Unexpectedly failed tests on M1 Mac

I'm trying to build on my M1 Mac and some tests are failing unexpectedly.

❯ clang --version
Apple clang version 13.0.0 (clang-1300.0.29.30)
Target: arm64-apple-darwin21.2.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin

This is how I built.

cmake -G Ninja ../llvm-project/llvm \
  -DDEFAULT_SYSROOT="$(xcrun --show-sdk-path)"\     # Needed for Mac Includes
  -DLLVM_ENABLE_PROJECTS="clang;mlir" \
  -DLLVM_EXTERNAL_PROJECTS="polygeist" \
  -DLLVM_EXTERNAL_POLYGEIST_SOURCE_DIR=.. \
  -DLLVM_TARGETS_TO_BUILD="host" \
  -DLLVM_ENABLE_ASSERTIONS=ON \
  -DCMAKE_BUILD_TYPE=DEBUG
ninja -j6
ninja check-mlir-clang

The failures look similar to this one.

********************
FAIL: mlir-clang :: polybench/linear-algebra/blas/gemm/gemm.c (39 of 129)
******************** TEST 'mlir-clang :: polybench/linear-algebra/blas/gemm/gemm.c' FAILED ********************
Script:
--
: 'RUN: at line 1';   /Users/than/Development/c680/Polygeist/build/bin/mlir-clang /Users/than/Development/c680/Polygeist/tools/mlir-clang/Test/polybench/linear-algebra/blas/gemm/gemm.c -I /../clang/lib/Headers -I /Users/than/Development/c680/Polygeist/tools/mlir-clang/Test/polybench/utilities -S | /Users/than/Development/c680/Polygeist/build/bin/FileCheck /Users/than/Development/c680/Polygeist/tools/mlir-clang/Test/polybench/linear-algebra/blas/gemm/gemm.c
: 'RUN: at line 2';   /Users/than/Development/c680/Polygeist/build/bin/mlir-clang /Users/than/Development/c680/Polygeist/tools/mlir-clang/Test/polybench/linear-algebra/blas/gemm/gemm.c -I /../clang/lib/Headers -I /Users/than/Development/c680/Polygeist/tools/mlir-clang/Test/polybench/utilities -S --memref-fullrank | /Users/than/Development/c680/Polygeist/build/bin/FileCheck /Users/than/Development/c680/Polygeist/tools/mlir-clang/Test/polybench/linear-algebra/blas/gemm/gemm.c --check-prefix=FULLRANK
: 'RUN: at line 3';   /Users/than/Development/c680/Polygeist/build/bin/clang /Users/than/Development/c680/Polygeist/tools/mlir-clang/Test/polybench/linear-algebra/blas/gemm/gemm.c -O3 -I /../clang/lib/Headers -I /Users/than/Development/c680/Polygeist/tools/mlir-clang/Test/polybench/utilities /Users/than/Development/c680/Polygeist/tools/mlir-clang/Test/polybench/utilities/polybench.c -D POLYBENCH_DUMP_ARRAYS -D POLYBENCH_NO_FLUSH_CACHE -D MINI_DATASET -o /Users/than/Development/c680/Polygeist/tools/mlir-clang/Test/polybench/linear-algebra/blas/gemm/gemm.c.exec1 && /Users/than/Development/c680/Polygeist/tools/mlir-clang/Test/polybench/linear-algebra/blas/gemm/gemm.c.exec1 &> /Users/than/Development/c680/Polygeist/tools/mlir-clang/Test/polybench/linear-algebra/blas/gemm/gemm.c.out1
: 'RUN: at line 4';   /Users/than/Development/c680/Polygeist/build/bin/mlir-clang /Users/than/Development/c680/Polygeist/tools/mlir-clang/Test/polybench/linear-algebra/blas/gemm/gemm.c /Users/than/Development/c680/Polygeist/tools/mlir-clang/Test/polybench/utilities/polybench.c -D POLYBENCH_DUMP_ARRAYS -D POLYBENCH_NO_FLUSH_CACHE -D MINI_DATASET -I /../clang/lib/Headers -I /Users/than/Development/c680/Polygeist/tools/mlir-clang/Test/polybench/utilities -O3 -o /Users/than/Development/c680/Polygeist/tools/mlir-clang/Test/polybench/linear-algebra/blas/gemm/gemm.c.execm && /Users/than/Development/c680/Polygeist/tools/mlir-clang/Test/polybench/linear-algebra/blas/gemm/gemm.c.execm &> /Users/than/Development/c680/Polygeist/tools/mlir-clang/Test/polybench/linear-algebra/blas/gemm/gemm.c.out2
: 'RUN: at line 5';   rm -f /Users/than/Development/c680/Polygeist/tools/mlir-clang/Test/polybench/linear-algebra/blas/gemm/gemm.c.exec1 /Users/than/Development/c680/Polygeist/tools/mlir-clang/Test/polybench/linear-algebra/blas/gemm/gemm.c.execm
: 'RUN: at line 6';   diff /Users/than/Development/c680/Polygeist/tools/mlir-clang/Test/polybench/linear-algebra/blas/gemm/gemm.c.out1 /Users/than/Development/c680/Polygeist/tools/mlir-clang/Test/polybench/linear-algebra/blas/gemm/gemm.c.out2
: 'RUN: at line 7';   rm -f /Users/than/Development/c680/Polygeist/tools/mlir-clang/Test/polybench/linear-algebra/blas/gemm/gemm.c.out1 /Users/than/Development/c680/Polygeist/tools/mlir-clang/Test/polybench/linear-algebra/blas/gemm/gemm.c.out2
: 'RUN: at line 8';   /Users/than/Development/c680/Polygeist/build/bin/mlir-clang /Users/than/Development/c680/Polygeist/tools/mlir-clang/Test/polybench/linear-algebra/blas/gemm/gemm.c /Users/than/Development/c680/Polygeist/tools/mlir-clang/Test/polybench/utilities/polybench.c -D POLYBENCH_TIME -D POLYBENCH_NO_FLUSH_CACHE -D MINI_DATASET -I /../clang/lib/Headers -I /Users/than/Development/c680/Polygeist/tools/mlir-clang/Test/polybench/utilities -O3 -o /Users/than/Development/c680/Polygeist/tools/mlir-clang/Test/polybench/linear-algebra/blas/gemm/gemm.c.execm && /Users/than/Development/c680/Polygeist/tools/mlir-clang/Test/polybench/linear-algebra/blas/gemm/gemm.c.execm > /Users/than/Development/c680/Polygeist/tools/mlir-clang/Test/polybench/linear-algebra/blas/gemm/gemm.c.mlir.time; cat /Users/than/Development/c680/Polygeist/tools/mlir-clang/Test/polybench/linear-algebra/blas/gemm/gemm.c.mlir.time | /Users/than/Development/c680/Polygeist/build/bin/FileCheck /Users/than/Development/c680/Polygeist/tools/mlir-clang/Test/polybench/linear-algebra/blas/gemm/gemm.c --check-prefix EXEC
: 'RUN: at line 9';   /Users/than/Development/c680/Polygeist/build/bin/clang /Users/than/Development/c680/Polygeist/tools/mlir-clang/Test/polybench/linear-algebra/blas/gemm/gemm.c -O3 /Users/than/Development/c680/Polygeist/tools/mlir-clang/Test/polybench/utilities/polybench.c -D POLYBENCH_TIME -D POLYBENCH_NO_FLUSH_CACHE -D MINI_DATASET -I /../clang/lib/Headers -I /Users/than/Development/c680/Polygeist/tools/mlir-clang/Test/polybench/utilities -o /Users/than/Development/c680/Polygeist/tools/mlir-clang/Test/polybench/linear-algebra/blas/gemm/gemm.c.exec2 && /Users/than/Development/c680/Polygeist/tools/mlir-clang/Test/polybench/linear-algebra/blas/gemm/gemm.c.exec2 > /Users/than/Development/c680/Polygeist/tools/mlir-clang/Test/polybench/linear-algebra/blas/gemm/gemm.c.clang.time; cat /Users/than/Development/c680/Polygeist/tools/mlir-clang/Test/polybench/linear-algebra/blas/gemm/gemm.c.clang.time | /Users/than/Development/c680/Polygeist/build/bin/FileCheck /Users/than/Development/c680/Polygeist/tools/mlir-clang/Test/polybench/linear-algebra/blas/gemm/gemm.c --check-prefix EXEC
: 'RUN: at line 10';   rm -f /Users/than/Development/c680/Polygeist/tools/mlir-clang/Test/polybench/linear-algebra/blas/gemm/gemm.c.exec2 /Users/than/Development/c680/Polygeist/tools/mlir-clang/Test/polybench/linear-algebra/blas/gemm/gemm.c.execm
: 'RUN: at line 12';   /Users/than/Development/c680/Polygeist/build/bin/clang /Users/than/Development/c680/Polygeist/tools/mlir-clang/Test/polybench/linear-algebra/blas/gemm/gemm.c -O3 -I /../clang/lib/Headers -I /Users/than/Development/c680/Polygeist/tools/mlir-clang/Test/polybench/utilities /Users/than/Development/c680/Polygeist/tools/mlir-clang/Test/polybench/utilities/polybench.c -D POLYBENCH_DUMP_ARRAYS -D POLYBENCH_NO_FLUSH_CACHE -D MINI_DATASET -o /Users/than/Development/c680/Polygeist/tools/mlir-clang/Test/polybench/linear-algebra/blas/gemm/gemm.c.exec1 && /Users/than/Development/c680/Polygeist/tools/mlir-clang/Test/polybench/linear-algebra/blas/gemm/gemm.c.exec1 &> /Users/than/Development/c680/Polygeist/tools/mlir-clang/Test/polybench/linear-algebra/blas/gemm/gemm.c.out1
: 'RUN: at line 13';   /Users/than/Development/c680/Polygeist/build/bin/mlir-clang /Users/than/Development/c680/Polygeist/tools/mlir-clang/Test/polybench/linear-algebra/blas/gemm/gemm.c /Users/than/Development/c680/Polygeist/tools/mlir-clang/Test/polybench/utilities/polybench.c -D POLYBENCH_DUMP_ARRAYS -D POLYBENCH_NO_FLUSH_CACHE -D MINI_DATASET -I /../clang/lib/Headers -I /Users/than/Development/c680/Polygeist/tools/mlir-clang/Test/polybench/utilities -detect-reduction -O3 -o /Users/than/Development/c680/Polygeist/tools/mlir-clang/Test/polybench/linear-algebra/blas/gemm/gemm.c.execm && /Users/than/Development/c680/Polygeist/tools/mlir-clang/Test/polybench/linear-algebra/blas/gemm/gemm.c.execm &> /Users/than/Development/c680/Polygeist/tools/mlir-clang/Test/polybench/linear-algebra/blas/gemm/gemm.c.out2
: 'RUN: at line 14';   rm -f /Users/than/Development/c680/Polygeist/tools/mlir-clang/Test/polybench/linear-algebra/blas/gemm/gemm.c.exec1 /Users/than/Development/c680/Polygeist/tools/mlir-clang/Test/polybench/linear-algebra/blas/gemm/gemm.c.execm
: 'RUN: at line 15';   diff /Users/than/Development/c680/Polygeist/tools/mlir-clang/Test/polybench/linear-algebra/blas/gemm/gemm.c.out1 /Users/than/Development/c680/Polygeist/tools/mlir-clang/Test/polybench/linear-algebra/blas/gemm/gemm.c.out2
: 'RUN: at line 16';   rm -f /Users/than/Development/c680/Polygeist/tools/mlir-clang/Test/polybench/linear-algebra/blas/gemm/gemm.c.out1 /Users/than/Development/c680/Polygeist/tools/mlir-clang/Test/polybench/linear-algebra/blas/gemm/gemm.c.out2
--
Exit Code: 2

Command Output (stderr):
--
RecordType 0x1518703c0 'struct __sFILEX'
`-Record 0x151870338 '__sFILEX'
ST: %struct.__sFILEX = type opaque
fields
types
Assertion failed: (types.size()), function getMLIRType, file clang-mlir.cc, line 6005.
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.
Stack dump:
0.	Program arguments: /Users/than/Development/c680/Polygeist/build/bin/mlir-clang /Users/than/Development/c680/Polygeist/tools/mlir-clang/Test/polybench/linear-algebra/blas/gemm/gemm.c -I /../clang/lib/Headers -I /Users/than/Development/c680/Polygeist/tools/mlir-clang/Test/polybench/utilities -S
1.	<eof> parser at end of file
Stack dump without symbol names (ensure you have llvm-symbolizer in your PATH or set the environment var `LLVM_SYMBOLIZER_PATH` to point to it):
0  mlir-clang               0x0000000102e7aef8 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) + 68
1  mlir-clang               0x0000000102e7b3ec PrintStackTraceSignalHandler(void*) + 28
2  mlir-clang               0x0000000102e79558 llvm::sys::RunSignalHandlers() + 132
3  mlir-clang               0x0000000102e7d0cc SignalHandler(int) + 220
4  libsystem_platform.dylib 0x00000001c459c4e4 _sigtramp + 56
5  libsystem_pthread.dylib  0x00000001c4584eb0 pthread_kill + 288
6  libsystem_c.dylib        0x00000001c44c2314 abort + 164
7  libsystem_c.dylib        0x00000001c44c172c err + 0
8  mlir-clang               0x00000001001e9f4c MLIRASTConsumer::getMLIRType(clang::QualType, bool*, bool) + 3812
9  mlir-clang               0x00000001001e9108 MLIRASTConsumer::getMLIRType(clang::QualType, bool*, bool) + 160
10 mlir-clang               0x00000001001ea8b0 MLIRASTConsumer::getMLIRType(clang::QualType, bool*, bool) + 6216
11 mlir-clang               0x00000001001e9bec MLIRASTConsumer::getMLIRType(clang::QualType, bool*, bool) + 2948
12 mlir-clang               0x00000001001e9108 MLIRASTConsumer::getMLIRType(clang::QualType, bool*, bool) + 160
13 mlir-clang               0x00000001001e92a0 MLIRASTConsumer::getMLIRType(clang::QualType, bool*, bool) + 568
14 mlir-clang               0x00000001001ea8b0 MLIRASTConsumer::getMLIRType(clang::QualType, bool*, bool) + 6216
15 mlir-clang               0x00000001001ea8b0 MLIRASTConsumer::getMLIRType(clang::QualType, bool*, bool) + 6216
16 mlir-clang               0x0000000100223138 MLIRScanner::VisitDeclRefExpr(clang::DeclRefExpr*) + 996
17 mlir-clang               0x00000001001ef700 clang::StmtVisitorBase<std::__1::add_pointer, MLIRScanner, ValueCategory>::Visit(clang::Stmt*) + 5072
18 mlir-clang               0x00000001001fa72c MLIRScanner::VisitCastExpr(clang::CastExpr*) + 5564
19 mlir-clang               0x0000000100276cc4 clang::StmtVisitorBase<std::__1::add_pointer, MLIRScanner, ValueCategory>::VisitImplicitCastExpr(clang::ImplicitCastExpr*) + 32
20 mlir-clang               0x00000001001ef640 clang::StmtVisitorBase<std::__1::add_pointer, MLIRScanner, ValueCategory>::Visit(clang::Stmt*) + 4880
21 mlir-clang               0x0000000100210998 MLIRScanner::VisitCallExpr(clang::CallExpr*)::$_5::operator()(clang::Expr*) const + 48
22 mlir-clang               0x000000010020f138 MLIRScanner::VisitCallExpr(clang::CallExpr*) + 27108
23 mlir-clang               0x00000001001ef4f0 clang::StmtVisitorBase<std::__1::add_pointer, MLIRScanner, ValueCategory>::Visit(clang::Stmt*) + 4544
24 mlir-clang               0x00000001002d8214 MLIRScanner::VisitCompoundStmt(clang::CompoundStmt*) + 136
25 mlir-clang               0x00000001001ee950 clang::StmtVisitorBase<std::__1::add_pointer, MLIRScanner, ValueCategory>::Visit(clang::Stmt*) + 1568
26 mlir-clang               0x00000001001e8928 MLIRScanner::init(mlir::FuncOp, clang::FunctionDecl const*) + 4684
27 mlir-clang               0x000000010022869c MLIRASTConsumer::run() + 696
28 mlir-clang               0x00000001002296bc MLIRASTConsumer::HandleTranslationUnit(clang::ASTContext&) + 28
29 mlir-clang               0x0000000108709378 clang::ParseAST(clang::Sema&, bool, bool) + 732
30 mlir-clang               0x000000010539f2f8 clang::ASTFrontendAction::ExecuteAction() + 264
31 mlir-clang               0x000000010539e9f4 clang::FrontendAction::Execute() + 120
32 mlir-clang               0x000000010022ef98 parseMLIR(char const*, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >, mlir::OwningOpRef<mlir::ModuleOp>&, llvm::Triple&, llvm::DataLayout&) + 4204
33 mlir-clang               0x000000010022bb1c main + 2980
34 dyld                     0x000000012b4e90f4 start + 520
FileCheck error: '<stdin>' is empty.
FileCheck command line:  /Users/than/Development/c680/Polygeist/build/bin/FileCheck /Users/than/Development/c680/Polygeist/tools/mlir-clang/Test/polybench/linear-algebra/blas/gemm/gemm.c

--

These are the failed tests.

********************
********************
Failed Tests (32):
  mlir-clang :: Verification/fscanf.c
  mlir-clang :: Verification/gettimeofday.c
  mlir-clang :: polybench/datamining/correlation/correlation.c
  mlir-clang :: polybench/datamining/covariance/covariance.c
  mlir-clang :: polybench/linear-algebra/blas/gemm/gemm.c
  mlir-clang :: polybench/linear-algebra/blas/gemver/gemver.c
  mlir-clang :: polybench/linear-algebra/blas/gesummv/gesummv.c
  mlir-clang :: polybench/linear-algebra/blas/symm/symm.c
  mlir-clang :: polybench/linear-algebra/blas/syr2k/syr2k.c
  mlir-clang :: polybench/linear-algebra/blas/syrk/syrk.c
  mlir-clang :: polybench/linear-algebra/blas/trmm/trmm.c
  mlir-clang :: polybench/linear-algebra/kernels/2mm/2mm.c
  mlir-clang :: polybench/linear-algebra/kernels/3mm/3mm.c
  mlir-clang :: polybench/linear-algebra/kernels/atax/atax.c
  mlir-clang :: polybench/linear-algebra/kernels/bicg/bicg.c
  mlir-clang :: polybench/linear-algebra/kernels/doitgen/doitgen.c
  mlir-clang :: polybench/linear-algebra/kernels/mvt/mvt.c
  mlir-clang :: polybench/linear-algebra/solvers/cholesky/cholesky.c
  mlir-clang :: polybench/linear-algebra/solvers/durbin/durbin.c
  mlir-clang :: polybench/linear-algebra/solvers/gramschmidt/gramschmidt.c
  mlir-clang :: polybench/linear-algebra/solvers/lu/lu.c
  mlir-clang :: polybench/linear-algebra/solvers/ludcmp/ludcmp.c
  mlir-clang :: polybench/linear-algebra/solvers/trisolv/trisolv.c
  mlir-clang :: polybench/medley/deriche/deriche.c
  mlir-clang :: polybench/medley/floyd-warshall/floyd-warshall.c
  mlir-clang :: polybench/medley/nussinov/nussinov.c
  mlir-clang :: polybench/stencils/adi/adi.c
  mlir-clang :: polybench/stencils/fdtd-2d/fdtd-2d.c
  mlir-clang :: polybench/stencils/heat-3d/heat-3d.c
  mlir-clang :: polybench/stencils/jacobi-1d/jacobi-1d.c
  mlir-clang :: polybench/stencils/jacobi-2d/jacobi-2d.c
  mlir-clang :: polybench/stencils/seidel-2d/seidel-2d.c


Testing Time: 11.87s
  Passed           : 92
  Expectedly Failed:  5
  Failed           : 32
FAILED: tools/polygeist/tools/mlir-clang/Test/CMakeFiles/check-mlir-clang /Users/than/Development/c680/Polygeist/build/tools/polygeist/tools/mlir-clang/Test/CMakeFiles/check-mlir-clang
cd /Users/than/Development/c680/Polygeist/build/tools/polygeist/tools/mlir-clang/Test && /opt/homebrew/Frameworks/Python.framework/Versions/3.9/bin/python3.9 /Users/than/Development/c680/Polygeist/build/bin/llvm-lit -sv /Users/than/Development/c680/Polygeist/build/tools/polygeist/tools/mlir-clang/Test
ninja: build stopped: subcommand failed.

Am I missing some information here? Have I done something wrong in the build process?

Any advice would be greatly appreciated.

Undefined reference to `cc1_main` during linking time

Hi,

First of all, super cool work. I watched your presentation at PACT and had to try this project out.
But I am running into an issue during compilation.

Error:

ninja check-mlir-clang
[1/2] Linking CXX executable mlir-clang/mlir-clang
FAILED: mlir-clang/mlir-clang
: && /usr/bin/clang++-10 -fPIC -fvisibility-inlines-hidden -Werror=date-time -Werror=unguarded-availability-new -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -Wimplicit-fallthrough -Wcovered-switch-default -Wno-noexcept-type -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wstring-conversion -Wmisleading-indentation -fdiagnostics-color -g -Wl,-rpath-link, mlir-clang/CMakeFiles/mlir-clang.dir/__/llvm-project/clang/tools/driver/cc1_main.cpp.o mlir-clang/CMakeFiles/mlir-clang.dir/__/llvm-project/clang/tools/driver/cc1as_main.cpp.o mlir-clang/CMakeFiles/mlir-clang.dir/__/llvm-project/clang/tools/driver/cc1gen_reproducer_main.cpp.o mlir-clang/CMakeFiles/mlir-clang.dir/mlir-clang.cc.o mlir-clang/CMakeFiles/mlir-clang.dir/Lib/utils.cc.o mlir-clang/CMakeFiles/mlir-clang.dir/Lib/AffineUtils.cc.o mlir-clang/CMakeFiles/mlir-clang.dir/Lib/pragmaHandler.cc.o mlir-clang/CMakeFiles/mlir-clang.dir/Lib/ValueCategory.cc.o mlir-clang/CMakeFiles/mlir-clang.dir/Lib/CGStmt.cc.o -o mlir-clang/mlir-clang -L/working_dir/llvm-project/build/./lib -Wl,-rpath,"\$ORIGIN/../lib:/working_dir/llvm-project/build/./lib"  ../llvm-project/build/lib/libLLVMX86CodeGen.a  ../llvm-project/build/lib/libLLVMX86AsmParser.a  ../llvm-project/build/lib/libLLVMX86Desc.a  ../llvm-project/build/lib/libLLVMX86Disassembler.a  ../llvm-project/build/lib/libLLVMX86Info.a  ../llvm-project/build/lib/libLLVMAnalysis.a  ../llvm-project/build/lib/libLLVMCodeGen.a  ../llvm-project/build/lib/libLLVMCore.a  ../llvm-project/build/lib/libLLVMAggressiveInstCombine.a  ../llvm-project/build/lib/libLLVMInstCombine.a  ../llvm-project/build/lib/libLLVMInstrumentation.a  ../llvm-project/build/lib/libLLVMMC.a  ../llvm-project/build/lib/libLLVMMCParser.a  ../llvm-project/build/lib/libLLVMObjCARCOpts.a  ../llvm-project/build/lib/libLLVMOption.a  ../llvm-project/build/lib/libLLVMScalarOpts.a  ../llvm-project/build/lib/libLLVMSupport.a  ../llvm-project/build/lib/libLLVMTransformUtils.a  ../llvm-project/build/lib/libLLVMVectorize.a  -lpthread  ../llvm-project/build/lib/libMLIRSCFTransforms.a  lib/polygeist/libMLIRPolygeist.a  ../llvm-project/build/lib/libMLIRSupport.a  ../llvm-project/build/lib/libMLIRIR.a  ../llvm-project/build/lib/libMLIRAnalysis.a  ../llvm-project/build/lib/libMLIRLLVMIR.a  ../llvm-project/build/lib/libMLIRNVVMIR.a  ../llvm-project/build/lib/libMLIROpenMP.a  ../llvm-project/build/lib/libMLIRGPUOps.a  ../llvm-project/build/lib/libMLIRTransforms.a  ../llvm-project/build/lib/libMLIRSCFToStandard.a  ../llvm-project/build/lib/libMLIRStandardToLLVM.a  ../llvm-project/build/lib/libMLIRAffineTransforms.a  ../llvm-project/build/lib/libMLIRAffineToStandard.a  ../llvm-project/build/lib/libMLIRMathToLLVM.a  ../llvm-project/build/lib/libMLIRTargetLLVMIRImport.a  lib/polygeist/Passes/libMLIRPolygeistTransforms.a  ../llvm-project/build/lib/libMLIRLLVMToLLVMIRTranslation.a  ../llvm-project/build/lib/libMLIRSCFToOpenMP.a  ../llvm-project/build/lib/libMLIROpenMPToLLVM.a  ../llvm-project/build/lib/libMLIROpenMPToLLVMIRTranslation.a  ../llvm-project/build/lib/libclangAST.a  ../llvm-project/build/lib/libclangBasic.a  ../llvm-project/build/lib/libclangCodeGen.a  ../llvm-project/build/lib/libclangDriver.a  ../llvm-project/build/lib/libclangFrontend.a  ../llvm-project/build/lib/libclangFrontendTool.a  ../llvm-project/build/lib/libclangLex.a  ../llvm-project/build/lib/libclangSerialization.a  ../llvm-project/build/lib/libLLVMAsmPrinter.a  ../llvm-project/build/lib/libLLVMDebugInfoDWARF.a  ../llvm-project/build/lib/libLLVMDebugInfoMSF.a  ../llvm-project/build/lib/libLLVMGlobalISel.a  ../llvm-project/build/lib/libLLVMSelectionDAG.a  ../llvm-project/build/lib/libLLVMCFGuard.a  ../llvm-project/build/lib/libLLVMMCDisassembler.a  ../llvm-project/build/lib/libMLIRVectorToLLVM.a  ../llvm-project/build/lib/libMLIRArmNeon.a  ../llvm-project/build/lib/libMLIRArmSVETransforms.a  ../llvm-project/build/lib/libMLIRArmSVE.a  ../llvm-project/build/lib/libMLIRAMXTransforms.a  ../llvm-project/build/lib/libMLIRAMX.a  ../llvm-project/build/lib/libMLIRX86VectorTransforms.a  ../llvm-project/build/lib/libMLIRX86Vector.a  lib/polygeist/libMLIRPolygeist.a  ../llvm-project/build/lib/libMLIRNVVMIR.a  ../llvm-project/build/lib/libMLIRGPUOps.a  ../llvm-project/build/lib/libMLIRDLTI.a  ../llvm-project/build/lib/libMLIRSCFToStandard.a  ../llvm-project/build/lib/libMLIRStandardOpsTransforms.a  ../llvm-project/build/lib/libMLIRArithmeticTransforms.a  ../llvm-project/build/lib/libMLIRStandardToLLVM.a  ../llvm-project/build/lib/libMLIRArithmeticToLLVM.a  ../llvm-project/build/lib/libMLIRMemRefToLLVM.a  ../llvm-project/build/lib/libMLIRLLVMCommonConversion.a  ../llvm-project/build/lib/libMLIRTransforms.a  ../llvm-project/build/lib/libMLIRCopyOpInterface.a  ../llvm-project/build/lib/libMLIRVector.a  ../llvm-project/build/lib/libMLIRAffineUtils.a  ../llvm-project/build/lib/libMLIRTransformUtils.a  ../llvm-project/build/lib/libMLIRRewrite.a  ../llvm-project/build/lib/libMLIRPDLToPDLInterp.a  ../llvm-project/build/lib/libMLIRPDLInterp.a  ../llvm-project/build/lib/libMLIRPDL.a  ../llvm-project/build/lib/libMLIRLoopAnalysis.a  ../llvm-project/build/lib/libMLIRPresburger.a  ../llvm-project/build/lib/libMLIRLinalg.a
 ../llvm-project/build/lib/libMLIRAffine.a  ../llvm-project/build/lib/libMLIRSCF.a  ../llvm-project/build/lib/libMLIRMemRef.a  ../llvm-project/build/lib/libMLIRMemRefUtils.a  ../llvm-project/build/lib/libMLIRLoopLikeInterface.a  ../llvm-project/build/lib/libMLIRTensor.a  ../llvm-project/build/lib/libMLIRStandard.a  ../llvm-project/build/lib/libMLIRArithmetic.a  ../llvm-project/build/lib/libMLIRVectorInterfaces.a  ../llvm-project/build/lib/libMLIRCastInterfaces.a  ../llvm-project/build/lib/libMLIRMath.a  ../llvm-project/build/lib/libMLIRDialect.a  ../llvm-project/build/lib/libMLIRDialectUtils.a  ../llvm-project/build/lib/libMLIRTilingInterface.a
../llvm-project/build/lib/libMLIROpenMP.a  ../llvm-project/build/lib/libMLIRTargetLLVMIRExport.a  ../llvm-project/build/lib/libMLIRTranslation.a  ../llvm-project/build/lib/libMLIRParser.a  ../llvm-project/build/lib/libMLIRLLVMIRTransforms.a  ../llvm-project/build/lib/libMLIRLLVMIR.a  ../llvm-project/build/lib/libMLIRPass.a  ../llvm-project/build/lib/libMLIRAnalysis.a  ../llvm-project/build/lib/libMLIRCallInterfaces.a  ../llvm-project/build/lib/libMLIRControlFlowInterfaces.a  ../llvm-project/build/lib/libMLIRDataLayoutInterfaces.a  ../llvm-project/build/lib/libMLIRInferTypeOpInterface.a  ../llvm-project/build/lib/libMLIRSideEffectInterfaces.a  ../llvm-project/build/lib/libMLIRViewLikeInterface.a  ../llvm-project/build/lib/libMLIRIR.a  ../llvm-project/build/lib/libMLIRSupport.a  ../llvm-project/build/lib/libclangCodeGen.a  ../llvm-project/build/lib/libLLVMCoverage.a  ../llvm-project/build/lib/libLLVMLTO.a  ../llvm-project/build/lib/libLLVMCodeGen.a  ../llvm-project/build/lib/libLLVMExtensions.a  ../llvm-project/build/lib/libLLVMPasses.a  ../llvm-project/build/lib/libLLVMObjCARCOpts.a  ../llvm-project/build/lib/libLLVMTarget.a  ../llvm-project/build/lib/libLLVMCoroutines.a  ../llvm-project/build/lib/libLLVMipo.a  ../llvm-project/build/lib/libLLVMInstrumentation.a  ../llvm-project/build/lib/libLLVMVectorize.a  ../llvm-project/build/lib/libLLVMBitWriter.a  ../llvm-project/build/lib/libLLVMIRReader.a  ../llvm-project/build/lib/libLLVMAsmParser.a  ../llvm-project/build/lib/libLLVMLinker.a  ../llvm-project/build/lib/libclangRewriteFrontend.a  ../llvm-project/build/lib/libclangARCMigrate.a  ../llvm-project/build/lib/libclangStaticAnalyzerFrontend.a  ../llvm-project/build/lib/libclangStaticAnalyzerCheckers.a  ../llvm-project/build/lib/libclangStaticAnalyzerCore.a  ../llvm-project/build/lib/libclangCrossTU.a  ../llvm-project/build/lib/libclangIndex.a  ../llvm-project/build/lib/libclangFrontend.a  ../llvm-project/build/lib/libclangDriver.a
 ../llvm-project/build/lib/libLLVMOption.a  ../llvm-project/build/lib/libclangParse.a  ../llvm-project/build/lib/libclangSerialization.a  ../llvm-project/build/lib/libclangSema.a  ../llvm-project/build/lib/libclangAnalysis.a  ../llvm-project/build/lib/libclangASTMatchers.a  ../llvm-project/build/lib/libclangEdit.a  ../llvm-project/build/lib/libclangAST.a  ../llvm-project/build/lib/libLLVMFrontendOpenMP.a  ../llvm-project/build/lib/libLLVMScalarOpts.a  ../llvm-project/build/lib/libLLVMAggressiveInstCombine.a  ../llvm-project/build/lib/libLLVMInstCombine.a  ../llvm-project/build/lib/libLLVMTransformUtils.a  ../llvm-project/build/lib/libLLVMAnalysis.a  ../llvm-project/build/lib/libLLVMProfileData.a  ../llvm-project/build/lib/libLLVMObject.a  ../llvm-project/build/lib/libLLVMMCParser.a  ../llvm-project/build/lib/libLLVMMC.a  ../llvm-project/build/lib/libLLVMDebugInfoCodeView.a  ../llvm-project/build/lib/libLLVMBitReader.a  ../llvm-project/build/lib/libLLVMTextAPI.a  ../llvm-project/build/lib/libLLVMCore.a  ../llvm-project/build/lib/libLLVMBinaryFormat.a  ../llvm-project/build/lib/libLLVMRemarks.a  ../llvm-project/build/lib/libLLVMBitstreamReader.a  ../llvm-project/build/lib/libclangFormat.a  ../llvm-project/build/lib/libclangToolingInclusions.a  ../llvm-project/build/lib/libclangToolingCore.a  ../llvm-project/build/lib/libclangRewrite.a  ../llvm-project/build/lib/libclangLex.a  ../llvm-project/build/lib/libclangBasic.a  ../llvm-project/build/lib/libLLVMSupport.a  -lrt  -ldl  -lpthread  -lm  /usr/lib/x86_64-linux-gnu/libz.so  /usr/lib/x86_64-linux-gnu/libtinfo.so  ../llvm-project/build/lib/libLLVMDemangle.a && :
/usr/bin/ld: mlir-clang/CMakeFiles/mlir-clang.dir/mlir-clang.cc.o: in function `ExecuteCC1Tool(llvm::SmallVectorImpl<char const*>&)':
/working_dir/build/../mlir-clang/mlir-clang.cc:182: undefined reference to `cc1_main(llvm::ArrayRef<char const*>, char const*, void*)'
clang: error: linker command failed with exit code 1 (use -v to see invocation)
ninja: build stopped: subcommand failed.

When?

While following the Readme instructions for option 1, building llvm and polygeist code with two cmake commands.

System:

I have a build image clang-10, gcc-9, cmake, ninja installed. I used clang-10 to compile llvm without problems, but it fails with the error above during the final linking steps of ninja check-mlir-clang

Questions?

External cc1_main seem to be included from the llvm-project. Maybe there is a library inclusion missing in the mlir-clang's CMakeLists file during polygeist compilation? Or maybe there is something missing in my system.

Have you seen this error before?

Missing operation in loop-carried values

Lowering the following function

int if_loop_1(int a[100], int n) {
  int i, tmp;
  int sum = 0;
  for (i = 0; i < n; i++) {
    tmp = a[i] * 5;
    if (tmp > 10)
      sum = tmp + sum;
  }
  return sum;
}

results in

func @if_loop_1(%arg0: memref<?xi32>, %arg1: i32) -> i32 attributes {llvm.linkage = #llvm.linkage<external>} {
    %c1 = arith.constant 1 : index
    %c0 = arith.constant 0 : index
    %c10_i32 = arith.constant 10 : i32
    %c5_i32 = arith.constant 5 : i32
    %c0_i32 = arith.constant 0 : i32
    %0 = memref.alloca() : memref<1xi32>
    affine.store %c0_i32, %0[0] : memref<1xi32>
    %1 = arith.index_cast %arg1 : i32 to index
    scf.for %arg2 = %c0 to %1 step %c1 {
      %3 = memref.load %arg0[%arg2] : memref<?xi32>
      %4 = arith.muli %3, %c5_i32 : i32
      %5 = arith.cmpi sgt, %4, %c10_i32 : i32
      scf.if %5 {
        affine.store %4, %0[0] : memref<1xi32>
      }
    }
    %2 = affine.load %0[0] : memref<1xi32>
    return %2 : i32
  }

The issue here is in the inner scf.if; the sum = tmp + sum line somehow got lost in translation!

Hitting asserts in initializeValueByInitListExpr

I hit asserts in initializeValueByInitListExpr
assert(toInit.getType().isa<MemRefType>() && "The value initialized by an InitListExpr should be a MemRef.");
and
assert(memTy.hasStaticShape() && "The memref to be initialized by InitListExpr should have static " "shape.");

Below presents the bt for assert.

frame #3: 0x00007ffff7a31f36 libc.so.6__assert_fail + 70
frame #4: 0x0000555555fed898 mlir-clang::initializeValueByInitListExpr(toInit=Value @ 0x00007fffffffb9a8, expr=0x00007ffff4f9f610, scanner=0x00007fffffffc030) at clang-mlir.cc:486:3 frame #5: 0x0000555555fee399 mlir-clangMLIRScanner::VisitVarDecl(this=0x00007fffffffc030, decl=0x00007ffff4f9f5a8) at clang-mlir.cc:648:36
frame #6: 0x00005555560bcc06 mlir-clangMLIRScanner::VisitDeclStmt(this=0x00007fffffffc030, decl=0x00007ffff4f9f660) at CGStmt.cc:260:22 frame #7: 0x00005555560356d1 mlir-clangclang::StmtVisitorBase<std::add_pointer, MLIRScanner, ValueCategory>::Visit(this=0x00007fffffffc030, S=0x00007ffff4f9f660) at StmtNodes.inc:97:1
frame #8: 0x00005555560bceac mlir-clangMLIRScanner::VisitCompoundStmt(this=0x00007fffffffc030, stmt=0x00007ffff4fa50f8) at CGStmt.cc:281:12 frame #9: 0x0000555556035671 mlir-clangclang::StmtVisitorBase<std::add_pointer, MLIRScanner, ValueCategory>::Visit(this=0x00007fffffffc030, S=0x00007ffff4fa50f8) at StmtNodes.inc:73:1
frame #10: 0x0000555555febc8a mlir-clangMLIRScanner::MLIRScanner(this=0x00007fffffffc030, Glob=0x00005555652dec50, function=FuncOp @ 0x00007fffffffbe68, fd=0x00007ffff4f9f488, module=0x00007fffffffd0a8, LTInfo=0x00005555652e07d8) at clang-mlir.cc:291:13

and the dump for init in MLIRScanner::VisitVarDecl is:

InitListExpr 0x7ffff4f9f610 'class sycl::detail::RoundedRangeKernel<class sycl::item<2, true>, 2, class (lambda at /home/mahmoud/cp/Polygeist/llvm-project/build/test/blur.cpp:24:59)>' |-CXXConstructExpr 0x7ffff4f9fa38 'range<2>':'class sycl::range<2>' 'void (const range<2> &) noexcept' | -ImplicitCastExpr 0x7ffff4f9fa20 'const range<2>':'const class sycl::range<2>' lvalue
| -DeclRefExpr 0x7ffff4f9f730 'range<2>':'class sycl::range<2>' lvalue ParmVar 0x7ffff4f9f6c8 '_arg_NumWorkItems' 'range<2>':'class sycl::range<2>' -InitListExpr 0x7ffff4f9fa68 'class (lambda at /home/mahmoud/cp/Polygeist/llvm-project/build/test/blur.cpp:24:59)'
|-ImplicitCastExpr 0x7ffff4f9fbc0 'int'
| -DeclRefExpr 0x7ffff4f9fba0 'int' lvalue ParmVar 0x7ffff4f9fb38 '_arg_' 'int' |-CXXConstructExpr 0x7ffff4f9fe18 'class sycl::accessor<int, 1, sycl::access::mode::read, sycl::access::target::global_buffer, sycl::access::placeholder::false_t, class sycl::ext::oneapi::accessor_property_list<> >':'class sycl::accessor<int, 1, sycl::access::mode::read, sycl::access::target::global_buffer, sycl::access::placeholder::false_t, class sycl::ext::oneapi::accessor_property_list<> >' 'void (void)' |-CXXConstructExpr 0x7ffff4fa1a58 'class sycl::accessor<int, 1, sycl::access::mode::read, sycl::access::target::global_buffer, sycl::access::placeholder::false_t, class sycl::ext::oneapi::accessor_property_list<> >':'class sycl::accessor<int, 1, sycl::access::mode::read, sycl::access::target::global_buffer, sycl::access::placeholder::false_t, class sycl::ext::oneapi::accessor_property_list<> >' 'void (void)' -CXXConstructExpr 0x7ffff4fa35b0 'class sycl::accessor<int, 1, sycl::access::mode::write, sycl::access::target::global_buffer, sycl::access::placeholder::false_t, class sycl::ext::oneapi::accessor_property_list<> >':'class sycl::accessor<int, 1, sycl::access::mode::write, sycl::access::target::global_buffer, sycl::access::placeholder::false_t, class sycl::ext::oneapi::accessor_property_list<> >' 'void (void)'`

the call to createAllocOp in VisitVarDecl has below arguments. This call creates the Value which causes the asserts.
MLIRScanner::createAllocOp(this=0x00007fffffffc030, t=Type @ 0x00007fffffffb980, name=0x00007ffff4f9f5a8, memspace=0, isArray=false, LLVMABI=true) at clang-mlir.cc:310:20

I am currently looking into this issue. Any advise / suggestions would be appreciated.

[PASS][Mem2Reg] A corner case of switch

int foo(int t) {
  int n = 10;
  switch (t) {
  case 1:
    n = 20;
    break;
  case 2:
    n = 30;
    break;
  default:
    return -1;
  }
  return n;
}

Error log:

mlir-clang: ../lib/polygeist/Passes/Mem2Reg.cpp:833: bool (anonymous namespace)::Mem2Reg::forwardStoreToLoad(mlir::Value, std::vector<ssize_t>, SmallVectorImpl<mlir::Operation *> &): Assertion `pval' failed.
PLEASE submit a bug report to https://bugs.llvm.org/ and include the crash backtrace.
Stack dump:
0.	Program arguments: ./mlir-clang/mlir-clang ../mlir-clang/Test/Verification/switch.c -I ../llvm-project/build/lib/clang/14.0.0/include -S --function=foo
 #0 0x000000000621125a llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) /mnt/ccnas2/bdp/rz3515/projects/phism/polygeist/llvm-project/llvm/lib/Support/Unix/Signals.inc:565:11
 #1 0x000000000621142b PrintStackTraceSignalHandler(void*) /mnt/ccnas2/bdp/rz3515/projects/phism/polygeist/llvm-project/llvm/lib/Support/Unix/Signals.inc:632:1
 #2 0x000000000620f9fb llvm::sys::RunSignalHandlers() /mnt/ccnas2/bdp/rz3515/projects/phism/polygeist/llvm-project/llvm/lib/Support/Signals.cpp:96:5
 #3 0x0000000006211b71 SignalHandler(int) /mnt/ccnas2/bdp/rz3515/projects/phism/polygeist/llvm-project/llvm/lib/Support/Unix/Signals.inc:407:1
 #4 0x00007f29d5833630 __restore_rt (/lib64/libpthread.so.0+0xf630)
 #5 0x00007f29d43593d7 raise (/lib64/libc.so.6+0x363d7)
 #6 0x00007f29d435aac8 abort (/lib64/libc.so.6+0x37ac8)
 #7 0x00007f29d43521a6 __assert_fail_base (/lib64/libc.so.6+0x2f1a6)
 #8 0x00007f29d4352252 (/lib64/libc.so.6+0x2f252)
 #9 0x0000000006affa22 (anonymous namespace)::Mem2Reg::forwardStoreToLoad(mlir::Value, std::vector<long, std::allocator<long> >, llvm::SmallVectorImpl<mlir::Operation*>&) /mnt/ccnas2/bdp/rz3515/projects/phism/polygeist/build/../lib/polygeist/Passes/Mem2Reg.cpp:834:7
#10 0x0000000006afcf4b (anonymous namespace)::Mem2Reg::runOnFunction() /mnt/ccnas2/bdp/rz3515/projects/phism/polygeist/build/../lib/polygeist/Passes/Mem2Reg.cpp:1311:20
#11 0x0000000006a272b8 mlir::FunctionPass::runOnOperation() /mnt/ccnas2/bdp/rz3515/projects/phism/polygeist/llvm-project/mlir/include/mlir/Pass/Pass.h:395:3
#12 0x0000000008f7cbc8 mlir::detail::OpToOpPassAdaptor::run(mlir::Pass*, mlir::Operation*, mlir::AnalysisManager, bool, unsigned int) /mnt/ccnas2/bdp/rz3515/projects/phism/polygeist/llvm-project/mlir/lib/Pass/Pass.cpp:386:21
#13 0x0000000008f7d18d mlir::detail::OpToOpPassAdaptor::runPipeline(llvm::iterator_range<llvm::pointee_iterator<std::unique_ptr<mlir::Pass, std::default_delete<mlir::Pass> >*, mlir::Pass> >, mlir::Operation*, mlir::AnalysisManager, bool, unsigned int, mlir::PassInstrumentor*, mlir::PassInstrumentation::PipelineParentInfo const*) /mnt/ccnas2/bdp/rz3515/projects/phism/polygeist/llvm-project/mlir/lib/Pass/Pass.cpp:445:16
#14 0x0000000008f7dec4 mlir::detail::OpToOpPassAdaptor::runOnOperationImpl(bool) /mnt/ccnas2/bdp/rz3515/projects/phism/polygeist/llvm-project/mlir/lib/Pass/Pass.cpp:541:20
#15 0x0000000008f7cea3 mlir::detail::OpToOpPassAdaptor::runOnOperation(bool) /mnt/ccnas2/bdp/rz3515/projects/phism/polygeist/llvm-project/mlir/lib/Pass/Pass.cpp:523:1
#16 0x0000000008f7cbb6 mlir::detail::OpToOpPassAdaptor::run(mlir::Pass*, mlir::Operation*, mlir::AnalysisManager, bool, unsigned int) /mnt/ccnas2/bdp/rz3515/projects/phism/polygeist/llvm-project/mlir/lib/Pass/Pass.cpp:383:5
#17 0x0000000008f7d18d mlir::detail::OpToOpPassAdaptor::runPipeline(llvm::iterator_range<llvm::pointee_iterator<std::unique_ptr<mlir::Pass, std::default_delete<mlir::Pass> >*, mlir::Pass> >, mlir::Operation*, mlir::AnalysisManager, bool, unsigned int, mlir::PassInstrumentor*, mlir::PassInstrumentation::PipelineParentInfo const*) /mnt/ccnas2/bdp/rz3515/projects/phism/polygeist/llvm-project/mlir/lib/Pass/Pass.cpp:445:16
#18 0x0000000008f7e83e mlir::PassManager::runPasses(mlir::Operation*, mlir::AnalysisManager) /mnt/ccnas2/bdp/rz3515/projects/phism/polygeist/llvm-project/mlir/lib/Pass/Pass.cpp:689:10
#19 0x0000000008f7e720 mlir::PassManager::run(mlir::Operation*) /mnt/ccnas2/bdp/rz3515/projects/phism/polygeist/llvm-project/mlir/lib/Pass/Pass.cpp:669:60
#20 0x000000000443e800 main /mnt/ccnas2/bdp/rz3515/projects/phism/polygeist/build/../mlir-clang/mlir-clang.cc:445:25
#21 0x00007f29d4345555 __libc_start_main (/lib64/libc.so.6+0x22555)
#22 0x00000000043e2029 _start (./mlir-clang/mlir-clang+0x43e2029)

cc @wsmoses

Unable to parse struct copy

See the following code:

typedef struct {
  float x;
  float y;
} MyStruct;

void test() {
  MyStruct a = {0, 0};
  MyStruct b = {1, 1};
  a = b;
}

mlir-clang will get the following error:

mlir-clang: ../tools/mlir-clang/Lib/ValueCategory.cc:44: mlir::Value ValueCategory::getValue(mlir::OpBuilder &) const: Assertion `mt.getShape().size() == 1 && "must have shape 1"' failed.

[RFC] C/C++ compiler directives for MLIR dialect lowering

Recently I keep wondering if it is nice for Polygeist to have such a feature: in the source C/C++ code, we can provide custom directives that instructs Polygeist to lower which C/C++ function to which MLIR function.

A motivating example

One example is, suppose we have a program that calls a Convolution function (yes, it is a CNN):

void ConvNet(float *X, float *W1, float *W2, float *Y1, float *Y2) {
  Convolution(X, W1, Y1);
  Convolution(Y1, W2, Y2);
}

Instead of providing an implementation to Convolution in C/C++, could we just define its interface, and point that to @linalg.conv in the following form:

#pragma lower_to("@linalg.conv")
extern void Convolution(float *filters, float *input, float *output);

Given this information, Polygeist can smartly lower the C/C++ code into:

func @ConvNet(memref<?xf32> %X, memref<?xf32> %W1, memref<?xf32> %W2, memref<?xf32> %Y1, memref<?xf32> %Y2) {
  call @linalg.conv(%X, %W1, %Y1)
  call @linalg.conv(%Y1, %W2, %Y2)
  return
}

Why we need this feature?

The lowering scenario that Polygeist support is mainly to scf + std, with or without raising to affine.
This should be sufficient if we only deal with code that has all the functions (of interest, i.e., exclude things like printf) fully implemented, e.g., kernels in Polybench.
If the implementation is not available, what we can do is only declaring the callee as a private function.

What if we have a clear mind of what that unimplemented function should be lowered to in MLIR?
The MLIR counterpart of that function could be in one of the "official" dialects, e.g., linalg, or others not very official, e.g., mhlo, or even some DSL you invent in MLIR.
That MLIR counterpart might already have its well-optimized lowering mechanism implemented.
In that case, instead of providing a C/C++ implementation of that function and lowering that to affine/scf/std, it can be much better to just lower that function to its MLIR counterpart, since we can save the C/C++ implementation time and the optimization effort.

How to implement?

Suppose the compiler directive is #pragma lower_to("<MLIR function symbol>"), there are two things we should do to implement the whole feature:

  1. Build the mapping from C/C++ function to the symbol of its MLIR counterpart based on the directive;
  2. Create the MLIR function call.

The first part seems to be straightforward, while the second is not.

The biggest challenge is (AFAIK) to handle the differences between the operand types in C and MLIR.
Suppose we have an operand x has type Tc in the source C/C++, and that type can be mapped to Tm1 in MLIR, and the desired argument type in the target MLIR function is Tm2.
There are the following 3 scenarios:

  1. If Tc has only one available mapping to Tm1, and Tm1 is equivalent (or can be safely cast) to Tm2, then things should be fine, we just need to insert typecast operations on demand.
  2. If Tc has multiple valid mappings, and some of them are equivalent (or can be safely cast) to Tm2, then we should probably rank these choices and select the best option, which is not a trivial task.
  3. If any Tc mapping cannot reach to Tm2, then the type check should fail.

To me I think there should be a viable solution overall, and these challenges can be addressed given some time for consideration and implementation, but still achievable.

Summary

I'm thinking of enabling Polygeist to process special compiler directives that maps C/C++ function interfaces to specific MLIR functions.

I'm going to give it a go in the following weeks. Please let me know if you have better solutions/ideas!

Assert in Mem2Reg.cpp due to memref.load type and llvm.load type mismatch

func @_ZN2cl4sycl4itemILi2ELb1EEC1ILb1EEERNSt9enable_ifIXT_EKNS0_5rangeILi2EEEE4typeERKNS0_2idILi2EEESE_(%arg0: !llvm.ptr<struct<(struct<(struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>)>)>>, %arg1: !llvm.ptr<struct<(struct<(array<2 x i64>)>)>>, %arg2: !llvm.ptr<struct<(struct<(array<2 x i64>)>)>>, %arg3: !llvm.ptr<struct<(struct<(array<2 x i64>)>)>>) attributes {llvm.linkage = #llvm.linkage<linkonce_odr>} {
  %c0_i32 = arith.constant 0 : i32
  %c1_i64 = arith.constant 1 : i64
  %c0 = arith.constant 0 : index
  %c1 = arith.constant 1 : index
  %c2 = arith.constant 2 : index
  %0 = llvm.alloca %c1_i64 x !llvm.struct<(struct<(array<2 x i64>)>)> : (i64) -> !llvm.ptr<struct<(struct<(array<2 x i64>)>)>>
  %1 = llvm.alloca %c1_i64 x !llvm.struct<(struct<(array<2 x i64>)>)> : (i64) -> !llvm.ptr<struct<(struct<(array<2 x i64>)>)>>
  %2 = llvm.alloca %c1_i64 x !llvm.struct<(struct<(array<2 x i64>)>)> : (i64) -> !llvm.ptr<struct<(struct<(array<2 x i64>)>)>>
  %3 = memref.alloca() : memref<1x!llvm.struct<(struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>)>>
  call @_ZN2cl4sycl5rangeILi2EEC1ERKS2_(%2, %arg1) : (!llvm.ptr<struct<(struct<(array<2 x i64>)>)>>, !llvm.ptr<struct<(struct<(array<2 x i64>)>)>>) -> ()
  %4 = llvm.load %2 : !llvm.ptr<struct<(struct<(array<2 x i64>)>)>>
  memref.store %4, %3[%c0] : memref<1x!llvm.struct<(struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>)>>
  call @_ZN2cl4sycl2idILi2EEC1ERKS2_(%1, %arg2) : (!llvm.ptr<struct<(struct<(array<2 x i64>)>)>>, !llvm.ptr<struct<(struct<(array<2 x i64>)>)>>) -> ()
  %5 = llvm.load %1 : !llvm.ptr<struct<(struct<(array<2 x i64>)>)>>
  memref.store %5, %3[%c1] : memref<1x!llvm.struct<(struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>)>>
  call @_ZN2cl4sycl2idILi2EEC1ERKS2_(%0, %arg3) : (!llvm.ptr<struct<(struct<(array<2 x i64>)>)>>, !llvm.ptr<struct<(struct<(array<2 x i64>)>)>>) -> ()
  %6 = llvm.load %0 : !llvm.ptr<struct<(struct<(array<2 x i64>)>)>>
  memref.store %6, %3[%c2] : memref<1x!llvm.struct<(struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>)>>
  %7 = llvm.getelementptr %arg0[%c0_i32, %c0_i32] : (!llvm.ptr<struct<(struct<(struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>)>)>>, i32, i32) -> !llvm.ptr<struct<(struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>)>>
  %8 = memref.load %3[%c0] : memref<1x!llvm.struct<(struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>)>>
  llvm.store %8, %7 : !llvm.ptr<struct<(struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>)>>
  return
}

Which relates to the constructor function below:

  template <bool has_offset = with_offset>
  item(detail::enable_if_t<has_offset, const range<dimensions>> &extent,
       const id<dimensions> &index, const id<dimensions> &offset)
      : MImpl{extent, index, offset} {}

Processing the above function using Mem2Reg results in below assert.
!llvm.struct<(struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>)> -
!llvm.struct<(struct<(array<2 x i64>)>)>
mlir-clang: /home/m/Polygeist/lib/polygeist/Passes/Mem2Reg.cpp:641: {anonymous}::Mem2Reg::forwardStoreToLoad(mlir::Value, std::vector<long int, std::allocator >, llvm::SmallVectorImplmlir::Operation*&)::<lambda(mlir::Block&, mlir::Value)>: Assertion `loadOp.getType() == lastVal.getType() && "mismatched load type"' failed.

In above assert, loadOp is
%8 = memref.load %3[%c0] : memref<1x!llvm.struct<(struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>)>>
and lastVal is
%4 = llvm.load %2 : !llvm.ptr<struct<(struct<(array<2 x i64>)>)>>

I am wondering if it's fine to relax the comparison of types of memref.load and llmv.load to avoid the assert.

`SubToSubView` canonicalization disabled

Noticed that the SubToSubView canonicalization was disabled in a recent commit:

https://github.com/wsmoses/Polygeist/blob/main/lib/polygeist/Ops.cpp#L681

What was the reason for this? If it is interfering with the application order of the other canonicalization patterns, should it instead be moved to a separate pass?
I'm asking because for my use-case (and i presume in general) it's fairly important that the Polygeist dialect operations have been lowered to that available in upstream MLIR.

[WhileToFor] If not moved into after region

As an example:

unsigned hash_thingy(unsigned v) {
  for (int i = 0; i < 3; ++i) {
    v = (v ^ 234567) ^ (v >> 16);
  }
  for (int i = 0; i < 3; ++i) {
    v = (v ^ 12345) ^ (v >> 16);
  }
  return v;
}

lowers to:

  func @hash_thingy(%arg0: i32) -> i32 attributes {llvm.linkage = #llvm.linkage<external>} {
    %c0 = arith.constant 0 : index
    %c0_i32 = arith.constant 0 : i32
    %c3_i32 = arith.constant 3 : i32
    %c234567_i32 = arith.constant 234567 : i32
    %c16_i32 = arith.constant 16 : i32
    %c1_i32 = arith.constant 1 : i32
    %c3 = arith.constant 3 : index
    %c1 = arith.constant 1 : index
    %0:3 = scf.while (%arg1 = %c0_i32, %arg2 = %arg0) : (i32, i32) -> (i32, i32, i32) {
      %2 = arith.cmpi slt, %arg1, %c3_i32 : i32
      %3:3 = scf.if %2 -> (i32, i32, i32) {
        %4 = arith.xori %arg2, %c234567_i32 : i32
        %5 = arith.shrui %arg2, %c16_i32 : i32
        %6 = arith.xori %4, %5 : i32
        %7 = arith.addi %arg1, %c1_i32 : i32
        %8 = llvm.mlir.undef : i32
        scf.yield %7, %6, %8 : i32, i32, i32
      } else {
        scf.yield %arg1, %arg2, %arg2 : i32, i32, i32
      }
      scf.condition(%2) %3#0, %3#1, %3#2 : i32, i32, i32
    } do {
    ^bb0(%arg1: i32, %arg2: i32, %arg3: i32):  // no predecessors
      scf.yield %arg1, %arg2 : i32, i32
    }
    %1:2 = scf.for %arg1 = %c0 to %c3 step %c1 iter_args(%arg2 = %0#2, %arg3 = %0#2) -> (i32, i32) {
      %2 = arith.xori %arg2, %c234567_i32 : i32
      %3 = arith.shrui %arg2, %c16_i32 : i32
      %4 = arith.xori %2, %3 : i32
      scf.yield %4, %4 : i32, i32
    }
    return %1#1 : i32
  }

The second loop makes good sense, but the first one is a bit strange due to being lowered to a while loop as well as the existence of the llvm.mlir.undef operation.

Building with Polymer

Hi, I'm following https://polygeist.mit.edu/Installation/ to build Polygeist with Polymer:

Polymer is a submodule to Polygeist, and you can build Polymer together with Polygeist.

In order to do that, please make sure you have already sync-ed up the submodules by -

git submodule init
git submodule update --recursive

And you should find Polymer under mlir/tools/polymer.

Next, make sure you have the Polymer option ON when calling cmake -DBUILD_POLYMER=ON

It seems there's no(?) Polymer submodule (e.g. in .gitmodules) and also no mention of BUILD_POLYMER in the repo ("Manually-specified variables were not used by the project: BUILD_POLYMER").
Do we need to build with Polymer to run the schedule optimization or this is no longer needed?

`polygeist.subindex` not lowered when callee has external linkage

An example:

#define N 20
int bar(int a[N]);
int foo(int a[N][N], int j) { return bar(a[j]); }

running:

mlir-clang example.c --function=* -S --memref-fullrank

we get:

module attributes {llvm.data_layout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128", llvm.target_triple = "x86_64-unknown-linux-gnu"}  {
  func @foo(%arg0: memref<20x20xi32>, %arg1: i32) -> i32 attributes {llvm.linkage = #llvm.linkage<external>} {
    %c0 = arith.constant 0 : index
    %0 = arith.index_cast %arg1 : i32 to index
    %1 = "polygeist.subindex"(%arg0, %0) : (memref<20x20xi32>, index) -> memref<?x20xi32>
    %2 = "polygeist.subindex"(%1, %c0) : (memref<?x20xi32>, index) -> memref<20xi32>
    %3 = call @bar(%2) : (memref<20xi32>) -> i32
    return %3 : i32
  }
  func private @bar(memref<20xi32>) -> i32 attributes {llvm.linkage = #llvm.linkage<external>}
}

Build fails

Hello, I was following instruction from your website to build using the command:

mkdir build
cd build
cmake -G Ninja ../llvm-project/llvm \
  -DLLVM_ENABLE_PROJECTS="clang;mlir" \
  -DLLVM_EXTERNAL_PROJECTS="polygeist" \
  -DLLVM_EXTERNAL_POLYGEIST_SOURCE_DIR=.. \
  -DLLVM_TARGETS_TO_BUILD="host" \
  -DLLVM_ENABLE_ASSERTIONS=ON \
  -DCMAKE_BUILD_TYPE=DEBUG
ninja

However, the build fails with the following error:

[3/5] Linking CXX executable bin/mlir-clang
FAILED: bin/mlir-clang 
: && /usr/bin/c++ -fPIC -fno-semantic-interposition -fvisibility-inlines-hidden -Werror=date-time -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wno-missing-field-initializers -pedantic -Wno-long-long -Wimplicit-fallthrough -Wno-maybe-uninitialized -Wno-class-memaccess -Wno-redundant-move -Wno-pessimizing-move -Wno-noexcept-type -Wdelete-non-virtual-dtor -Wsuggest-override -Wno-comment -Wmisleading-indentation -fdiagnostics-color -fPIC -fno-semantic-interposition -fvisibility-inlines-hidden -Werror=date-time -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wno-missing-field-initializers -pedantic -Wno-long-long -Wimplicit-fallthrough -Wno-maybe-uninitialized -Wno-class-memaccess -Wno-redundant-move -Wno-pessimizing-move -Wno-noexcept-type -Wdelete-non-virtual-dtor -Wsuggest-override -Wno-comment -Wmisleading-indentation -fdiagnostics-color -g -Wl,-rpath-link,/home/Polygeist/build/./lib tools/polygeist/mlir-clang/CMakeFiles/mlir-clang.dir/mlir-clang.cc.o tools/polygeist/mlir-clang/CMakeFiles/mlir-clang.dir/Lib/CGStmt.cc.o tools/polygeist/mlir-clang/CMakeFiles/mlir-clang.dir/__/llvm-project/clang/tools/driver/cc1_main.cpp.o tools/polygeist/mlir-clang/CMakeFiles/mlir-clang.dir/__/llvm-project/clang/tools/driver/cc1as_main.cpp.o tools/polygeist/mlir-clang/CMakeFiles/mlir-clang.dir/__/llvm-project/clang/tools/driver/cc1gen_reproducer_main.cpp.o tools/polygeist/mlir-clang/CMakeFiles/mlir-clang.dir/Lib/pragmaHandler.cc.o tools/polygeist/mlir-clang/CMakeFiles/mlir-clang.dir/Lib/AffineUtils.cc.o tools/polygeist/mlir-clang/CMakeFiles/mlir-clang.dir/Lib/ValueCategory.cc.o tools/polygeist/mlir-clang/CMakeFiles/mlir-clang.dir/Lib/utils.cc.o tools/polygeist/mlir-clang/CMakeFiles/mlir-clang.dir/Lib/IfScope.cc.o -o bin/mlir-clang  -Wl,-rpath,"\$ORIGIN/../lib"  lib/libLLVMAArch64CodeGen.a  lib/libLLVMAArch64AsmParser.a  lib/libLLVMAArch64Desc.a  lib/libLLVMAArch64Disassembler.a  lib/libLLVMAArch64Info.a  lib/libLLVMAArch64Utils.a  lib/libLLVMAnalysis.a  lib/libLLVMCodeGen.a  lib/libLLVMCore.a  lib/libLLVMAggressiveInstCombine.a  lib/libLLVMInstCombine.a  lib/libLLVMInstrumentation.a  lib/libLLVMMC.a  lib/libLLVMMCParser.a  lib/libLLVMObjCARCOpts.a  lib/libLLVMOption.a  lib/libLLVMScalarOpts.a  lib/libLLVMSupport.a  lib/libLLVMTransformUtils.a  lib/libLLVMVectorize.a  -lpthread  lib/libMLIRSCFTransforms.a  lib/libMLIRPolygeist.a  lib/libMLIRSupport.a  lib/libMLIRIR.a  lib/libMLIRAnalysis.a  lib/libMLIRLLVMIR.a  lib/libMLIRNVVMIR.a  lib/libMLIROpenMP.a  lib/libMLIRGPUOps.a  lib/libMLIRTransforms.a  lib/libMLIRSCFToStandard.a  lib/libMLIRStandardToLLVM.a  lib/libMLIRAffineTransforms.a  lib/libMLIRAffineToStandard.a  lib/libMLIRMathToLLVM.a  lib/libMLIRTargetLLVMIRImport.a  lib/libMLIRPolygeistTransforms.a  lib/libMLIRLLVMToLLVMIRTranslation.a  lib/libMLIRSCFToOpenMP.a  lib/libMLIROpenMPToLLVM.a  lib/libMLIROpenMPToLLVMIRTranslation.a  lib/libclangAST.a  lib/libclangBasic.a  lib/libclangCodeGen.a  lib/libclangDriver.a  lib/libclangFrontend.a  lib/libclangFrontendTool.a  lib/libclangLex.a  lib/libclangSerialization.a  lib/libLLVMAsmPrinter.a  lib/libLLVMDebugInfoDWARF.a  lib/libLLVMDebugInfoMSF.a  lib/libLLVMGlobalISel.a  lib/libLLVMSelectionDAG.a  lib/libLLVMCFGuard.a  lib/libLLVMAArch64Desc.a  lib/libLLVMAArch64Info.a  lib/libLLVMAArch64Utils.a  lib/libLLVMMCDisassembler.a  lib/libMLIRVectorToLLVM.a  lib/libMLIRArmNeon.a  lib/libMLIRArmSVETransforms.a  lib/libMLIRArmSVE.a  lib/libMLIRAMXTransforms.a  lib/libMLIRAMX.a  lib/libMLIRX86VectorTransforms.a  lib/libMLIRX86Vector.a  lib/libMLIRPolygeist.a  lib/libMLIRNVVMIR.a  lib/libMLIRGPUOps.a  lib/libMLIRDLTI.a  lib/libMLIRSCFToStandard.a  lib/libMLIRStandardOpsTransforms.a  lib/libMLIRArithmeticTransforms.a  lib/libMLIRStandardToLLVM.a  lib/libMLIRArithmeticToLLVM.a  lib/libMLIRMemRefToLLVM.a  lib/libMLIRLLVMCommonConversion.a  lib/libMLIRTransforms.a  lib/libMLIRCopyOpInterface.a  lib/libMLIRVector.a  lib/libMLIRAffineUtils.a  lib/libMLIRTransformUtils.a  lib/libMLIRRewrite.a  lib/libMLIRPDLToPDLInterp.a  lib/libMLIRPDLInterp.a  lib/libMLIRPDL.a  lib/libMLIRLoopAnalysis.a  lib/libMLIRPresburger.a  lib/libMLIRLinalg.a  lib/libMLIRAffine.a  lib/libMLIRSCF.a  lib/libMLIRMemRef.a  lib/libMLIRMemRefUtils.a  lib/libMLIRLoopLikeInterface.a  lib/libMLIRTensor.a  lib/libMLIRStandard.a  lib/libMLIRArithmetic.a  lib/libMLIRVectorInterfaces.a  lib/libMLIRCastInterfaces.a  lib/libMLIRMath.a  lib/libMLIRDialect.a  lib/libMLIRDialectUtils.a  lib/libMLIRBufferizableOpInterface.a  lib/libMLIRTilingInterface.a  lib/libMLIROpenMP.a  lib/libMLIRTargetLLVMIRExport.a  lib/libMLIRTranslation.a  lib/libMLIRParser.a  lib/libMLIRLLVMIRTransforms.a  lib/libMLIRLLVMIR.a  lib/libMLIRPass.a  lib/libMLIRAnalysis.a  lib/libMLIRCallInterfaces.a  lib/libMLIRControlFlowInterfaces.a  lib/libMLIRDataLayoutInterfaces.a  lib/libMLIRInferTypeOpInterface.a  lib/libMLIRSideEffectInterfaces.a  lib/libMLIRViewLikeInterface.a  lib/libMLIRIR.a  lib/libMLIRSupport.a  lib/libclangCodeGen.a  lib/libLLVMCoverage.a  lib/libLLVMLTO.a  lib/libLLVMCodeGen.a  lib/libLLVMExtensions.a  lib/libLLVMPasses.a  lib/libLLVMObjCARCOpts.a  lib/libLLVMTarget.a  lib/libLLVMCoroutines.a  lib/libLLVMipo.a  lib/libLLVMInstrumentation.a  lib/libLLVMVectorize.a  lib/libLLVMBitWriter.a  lib/libLLVMIRReader.a  lib/libLLVMAsmParser.a  lib/libLLVMLinker.a  lib/libclangRewriteFrontend.a  lib/libclangARCMigrate.a  lib/libclangStaticAnalyzerFrontend.a  lib/libclangStaticAnalyzerCheckers.a  lib/libclangStaticAnalyzerCore.a  lib/libclangCrossTU.a  lib/libclangIndex.a  lib/libclangFrontend.a  lib/libclangDriver.a  lib/libLLVMOption.a  lib/libclangParse.a  lib/libclangSerialization.a  lib/libclangSema.a  lib/libclangAnalysis.a  lib/libclangASTMatchers.a  lib/libclangEdit.a  lib/libclangAST.a  lib/libLLVMFrontendOpenMP.a  lib/libLLVMScalarOpts.a  lib/libLLVMAggressiveInstCombine.a  lib/libLLVMInstCombine.a  lib/libLLVMTransformUtils.a  lib/libLLVMAnalysis.a  lib/libLLVMObject.a  lib/libLLVMMCParser.a  lib/libLLVMMC.a  lib/libLLVMDebugInfoCodeView.a  lib/libLLVMBitReader.a  lib/libLLVMTextAPI.a  lib/libLLVMProfileData.a  lib/libLLVMCore.a  lib/libLLVMBinaryFormat.a  lib/libLLVMRemarks.a  lib/libLLVMBitstreamReader.a  lib/libclangFormat.a  lib/libclangToolingInclusions.a  lib/libclangToolingCore.a  lib/libclangRewrite.a  lib/libclangLex.a  lib/libclangBasic.a  lib/libLLVMSupport.a  -lrt  -ldl  -lpthread  -lm  /usr/lib/aarch64-linux-gnu/libz.so  /usr/lib/aarch64-linux-gnu/libtinfo.so  lib/libLLVMDemangle.a && :
lib/libLLVMProfileData.a(InstrProfReader.cpp.o): In function `__gnu_cxx::new_allocator<llvm::NamedInstrProfRecord>::allocate(unsigned long, void const*)':
/usr/include/c++/9/ext/new_allocator.h:114:(.text._ZN9__gnu_cxx13new_allocatorIN4llvm20NamedInstrProfRecordEE8allocateEmPKv[_ZN9__gnu_cxx13new_allocatorIN4llvm20NamedInstrProfRecordEE8allocateEmPKv]+0x50): relocation truncated to fit: R_AARCH64_CALL26 against symbol `operator new(unsigned long)@@GLIBCXX_3.4' defined in .text section in /usr/lib/gcc/aarch64-linux-gnu/9/libstdc++.so
lib/libLLVMProfileData.a(InstrProfReader.cpp.o): In function `std::__cxx11::list<InstrProfValueData, std::allocator<InstrProfValueData> >::operator=(std::__cxx11::list<InstrProfValueData, std::allocator<InstrProfValueData> > const&)':
/usr/include/c++/9/bits/list.tcc:289:(.text._ZNSt7__cxx114listI18InstrProfValueDataSaIS1_EEaSERKS3_[_ZNSt7__cxx114listI18InstrProfValueDataSaIS1_EEaSERKS3_]+0x118): relocation truncated to fit: R_AARCH64_CALL26 against symbol `__stack_chk_fail@@GLIBC_2.17' defined in .text section in /lib/aarch64-linux-gnu/libc.so.6
lib/libLLVMProfileData.a(InstrProfReader.cpp.o): In function `std::__cxx11::list<InstrProfValueData, std::allocator<InstrProfValueData> >::list(std::__cxx11::list<InstrProfValueData, std::allocator<InstrProfValueData> > const&)':
/usr/include/c++/9/bits/stl_list.h:734:(.text._ZNSt7__cxx114listI18InstrProfValueDataSaIS1_EEC2ERKS3_[_ZNSt7__cxx114listI18InstrProfValueDataSaIS1_EEC5ERKS3_]+0xa8): relocation truncated to fit: R_AARCH64_CALL26 against symbol `__stack_chk_fail@@GLIBC_2.17' defined in .text section in /lib/aarch64-linux-gnu/libc.so.6
lib/libLLVMProfileData.a(InstrProfReader.cpp.o): In function `std::vector<InstrProfValueData, std::allocator<InstrProfValueData> >::_S_max_size(std::allocator<InstrProfValueData> const&)':
/usr/include/c++/9/bits/stl_vector.h:1781:(.text._ZNSt6vectorI18InstrProfValueDataSaIS0_EE11_S_max_sizeERKS1_[_ZNSt6vectorI18InstrProfValueDataSaIS0_EE11_S_max_sizeERKS1_]+0x3c): relocation truncated to fit: R_AARCH64_CALL26 against symbol `unsigned long const& std::min<unsigned long>(unsigned long const&, unsigned long const&)' defined in .text._ZSt3minImERKT_S2_S2_[_ZSt3minImERKT_S2_S2_] section in tools/polygeist/mlir-clang/CMakeFiles/mlir-clang.dir/mlir-clang.cc.o
/usr/include/c++/9/bits/stl_vector.h:1782:(.text._ZNSt6vectorI18InstrProfValueDataSaIS0_EE11_S_max_sizeERKS1_[_ZNSt6vectorI18InstrProfValueDataSaIS0_EE11_S_max_sizeERKS1_]+0x64): relocation truncated to fit: R_AARCH64_CALL26 against symbol `__stack_chk_fail@@GLIBC_2.17' defined in .text section in /lib/aarch64-linux-gnu/libc.so.6
lib/libLLVMProfileData.a(InstrProfReader.cpp.o): In function `__gnu_cxx::new_allocator<InstrProfValueData>::allocate(unsigned long, void const*)':
/usr/include/c++/9/ext/new_allocator.h:105:(.text._ZN9__gnu_cxx13new_allocatorI18InstrProfValueDataE8allocateEmPKv[_ZN9__gnu_cxx13new_allocatorI18InstrProfValueDataE8allocateEmPKv]+0x38): relocation truncated to fit: R_AARCH64_CALL26 against symbol `std::__throw_bad_alloc()@@GLIBCXX_3.4' defined in .text section in /usr/lib/gcc/aarch64-linux-gnu/9/libstdc++.so
/usr/include/c++/9/ext/new_allocator.h:114:(.text._ZN9__gnu_cxx13new_allocatorI18InstrProfValueDataE8allocateEmPKv[_ZN9__gnu_cxx13new_allocatorI18InstrProfValueDataE8allocateEmPKv]+0x44): relocation truncated to fit: R_AARCH64_CALL26 against symbol `operator new(unsigned long)@@GLIBCXX_3.4' defined in .text section in /usr/lib/gcc/aarch64-linux-gnu/9/libstdc++.so
lib/libLLVMProfileData.a(InstrProfReader.cpp.o): In function `std::vector<llvm::NamedInstrProfRecord, std::allocator<llvm::NamedInstrProfRecord> >::vector(std::vector<llvm::NamedInstrProfRecord, std::allocator<llvm::NamedInstrProfRecord> > const&)':
/usr/include/c++/9/bits/stl_vector.h:558:(.text._ZNSt6vectorIN4llvm20NamedInstrProfRecordESaIS1_EEC2ERKS3_[_ZNSt6vectorIN4llvm20NamedInstrProfRecordESaIS1_EEC5ERKS3_]+0xdc): relocation truncated to fit: R_AARCH64_CALL26 against symbol `__stack_chk_fail@@GLIBC_2.17' defined in .text section in /lib/aarch64-linux-gnu/libc.so.6
lib/libLLVMProfileData.a(InstrProfReader.cpp.o): In function `void std::__alloc_on_copy<std::allocator<std::_List_node<InstrProfValueData> > >(std::allocator<std::_List_node<InstrProfValueData> >&, std::allocator<std::_List_node<InstrProfValueData> > const&)':
/usr/include/c++/9/bits/alloc_traits.h:535:(.text._ZSt15__alloc_on_copyISaISt10_List_nodeI18InstrProfValueDataEEEvRT_RKS4_[_ZSt15__alloc_on_copyISaISt10_List_nodeI18InstrProfValueDataEEEvRT_RKS4_]+0x50): relocation truncated to fit: R_AARCH64_CALL26 against symbol `__stack_chk_fail@@GLIBC_2.17' defined in .text section in /lib/aarch64-linux-gnu/libc.so.6
lib/libLLVMProfileData.a(InstrProfReader.cpp.o): In function `void std::__cxx11::list<InstrProfValueData, std::allocator<InstrProfValueData> >::_M_assign_dispatch<std::_List_const_iterator<InstrProfValueData> >(std::_List_const_iterator<InstrProfValueData>, std::_List_const_iterator<InstrProfValueData>, std::__false_type)':
/usr/include/c++/9/bits/list.tcc:321:(.text._ZNSt7__cxx114listI18InstrProfValueDataSaIS1_EE18_M_assign_dispatchISt20_List_const_iteratorIS1_EEEvT_S7_St12__false_type[_ZNSt7__cxx114listI18InstrProfValueDataSaIS1_EE18_M_assign_dispatchISt20_List_const_iteratorIS1_EEEvT_S7_St12__false_type]+0x144): relocation truncated to fit: R_AARCH64_CALL26 against symbol `__stack_chk_fail@@GLIBC_2.17' defined in .text section in /lib/aarch64-linux-gnu/libc.so.6
lib/libLLVMProfileData.a(InstrProfReader.cpp.o): In function `__gnu_cxx::__alloc_traits<std::allocator<std::_List_node<InstrProfValueData> >, std::_List_node<InstrProfValueData> >::_S_select_on_copy(std::allocator<std::_List_node<InstrProfValueData> > const&)':
/usr/include/c++/9/ext/alloc_traits.h:98:(.text._ZN9__gnu_cxx14__alloc_traitsISaISt10_List_nodeI18InstrProfValueDataEES3_E17_S_select_on_copyERKS4_[_ZN9__gnu_cxx14__alloc_traitsISaISt10_List_nodeI18InstrProfValueDataEES3_E17_S_select_on_copyERKS4_]+0x50): additional relocation overflows omitted from the output
collect2: error: ld returned 1 exit status
[4/5] Linking CXX shared library lib/libclang-cpp.so.14git
ninja: build stopped: subcommand failed.

Loops are optimized away when placing a label beforehand

As an example, running mlir-clang on the following:

int fir (int d_i[1000], int idx[1000] ) {
	int i;
	int tmp=0;

	for_loop:
	for (i=0;i<1000;i++) {
		tmp += idx [i] * d_i[999-i];

	}
	return tmp;
}

yields:

module attributes {llvm.data_layout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128", llvm.target_triple = "x86_64-unknown-linux-gnu"}  {
  func @fir(%arg0: memref<1000xi32>, %arg1: memref<1000xi32>) -> i32 attributes {llvm.linkage = #llvm.linkage<external>} {
    %c0_i32 = arith.constant 0 : i32
    return %c0_i32 : i32
  }
}

Whereas removing the label yields:

module attributes {llvm.data_layout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128", llvm.target_triple = "x86_64-unknown-linux-gnu"}  {
  func @fir(%arg0: memref<1000xi32>, %arg1: memref<1000xi32>) -> i32 attributes {llvm.linkage = #llvm.linkage<external>} {
    %c1 = arith.constant 1 : index
    %c0 = arith.constant 0 : index
    %c1000 = arith.constant 1000 : index
    %c999 = arith.constant 999 : index
    %c0_i32 = arith.constant 0 : i32
    %0:3 = scf.while (%arg2 = %c0, %arg3 = %c0_i32, %arg4 = %c0_i32) : (index, i32, i32) -> (index, i32, i32) {
      %1 = arith.cmpi slt, %arg2, %c1000 : index
      scf.condition(%1) %arg2, %arg3, %arg4 : index, i32, i32
    } do {
    ^bb0(%arg2: index, %arg3: i32, %arg4: i32):  // no predecessors
      %1 = arith.addi %arg2, %c1 : index
      %2 = memref.load %arg1[%arg2] : memref<1000xi32>
      %3 = arith.subi %c999, %arg2 : index
      %4 = memref.load %arg0[%3] : memref<1000xi32>
      %5 = arith.muli %2, %4 : i32
      %6 = arith.addi %arg3, %5 : i32
      scf.yield %1, %6, %6 : index, i32, i32
    }
    return %0#2 : i32
  }
}

General Cleanups

Website/Branding:

  • polygeist.mit.edu @wsmoses [almost done, pending https and some fastcgi fixes].
  • Include relevant content [initially forked enzyme.mit.edu]
  • Logo!
  • Rename repo @wsmoses
  • Merge in Polymer repo @kumasento

Upstreaming:

  • Loop Naturalization [form scf.while from cfg]
  • Loop canonicalizaation [e.g. scf.while to scf.for]
  • Remaining SCF canonicalizations [like if]
  • Integer math canoncalization
  • AffineCFG

Features/Improvements:

compiling OpenMP programs

Hello, I get an error compiling a simple OpenMP program. Could you please help?

vinodt@m2000host0:/localdata/vinod/Polygeist/Heat3DOpenMP$ mlir-clang -I../llvm-project/clang/lib/Headers main.c
mlir-clang: /localdata/vinod/Polygeist/lib/polygeist/Passes/LoopRestructure.cpp:647: void {anonymous}::LoopRestructure::runOnRegion(mlir::DominanceInfo&, mlir::Region&): Assertion `loop.before().getBlocks().size() == 1' failed.
PLEASE submit a bug report to https://bugs.llvm.org/ and include the crash backtrace.
Stack dump:
0. Program arguments: mlir-clang -I ../llvm-project/clang/lib/Headers main.c
#0 0x00005582c9fca00a llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) /localdata/vinod/Polygeist/llvm-project/llvm/lib/Support/Unix/Signals.inc:565:0
#1 0x00005582c9fca0c1 PrintStackTraceSignalHandler(void*) /localdata/vinod/Polygeist/llvm-project/llvm/lib/Support/Unix/Signals.inc:632:0
#2 0x00005582c9fc7d75 llvm::sys::RunSignalHandlers() /localdata/vinod/Polygeist/llvm-project/llvm/lib/Support/Signals.cpp:97:0
#3 0x00005582c9fc998b SignalHandler(int) /localdata/vinod/Polygeist/llvm-project/llvm/lib/Support/Unix/Signals.inc:407:0
#4 0x00007fe4c613b980 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x12980)
#5 0x00007fe4c4decfb7 raise /build/glibc-S9d2JN/glibc-2.27/signal/../sysdeps/unix/sysv/linux/raise.c:51:0
#6 0x00007fe4c4dee921 abort /build/glibc-S9d2JN/glibc-2.27/stdlib/abort.c:81:0
#7 0x00007fe4c4dde48a __assert_fail_base /build/glibc-S9d2JN/glibc-2.27/assert/assert.c:89:0
#8 0x00007fe4c4dde502 (/lib/x86_64-linux-gnu/libc.so.6+0x30502)
#9 0x00005582ca899740 (anonymous namespace)::LoopRestructure::runOnRegion(mlir::DominanceInfo&, mlir::Region&) /localdata/vinod/Polygeist/lib/polygeist/Passes/LoopRestructure.cpp:648:0
#10 0x00005582ca8962d9 (anonymous namespace)::LoopRestructure::runOnFunction() /localdata/vinod/Polygeist/lib/polygeist/Passes/LoopRestructure.cpp:283:0
#11 0x00005582ca816edf mlir::FunctionPass::runOnOperation() /localdata/vinod/Polygeist/llvm-project/mlir/include/mlir/Pass/Pass.h:395:0
#12 0x00005582ccdc53d9 mlir::detail::OpToOpPassAdaptor::run(mlir::Pass*, mlir::Operation*, mlir::AnalysisManager, bool, unsigned int) /localdata/vinod/Polygeist/llvm-project/mlir/lib/Pass/Pass.cpp:393:0
#13 0x00005582ccdc56ab mlir::detail::OpToOpPassAdaptor::runPipeline(llvm::iterator_range<llvm::pointee_iterator<std::unique_ptr<mlir::Pass, std::default_deletemlir::Pass >, mlir::Pass> >, mlir::Operation, mlir::AnalysisManager, bool, unsigned int, mlir::PassInstrumentor*, mlir::PassInstrumentation::PipelineParentInfo const*) /localdata/vinod/Polygeist/llvm-project/mlir/lib/Pass/Pass.cpp:452:0
#14 0x00005582ccdc611d mlir::detail::OpToOpPassAdaptor::runOnOperationImpl(bool) /localdata/vinod/Polygeist/llvm-project/mlir/lib/Pass/Pass.cpp:548:0
#15 0x00005582ccdc5e71 mlir::detail::OpToOpPassAdaptor::runOnOperation(bool) /localdata/vinod/Polygeist/llvm-project/mlir/lib/Pass/Pass.cpp:530:0
#16 0x00005582ccdc53ba mlir::detail::OpToOpPassAdaptor::run(mlir::Pass*, mlir::Operation*, mlir::AnalysisManager, bool, unsigned int) /localdata/vinod/Polygeist/llvm-project/mlir/lib/Pass/Pass.cpp:390:0
#17 0x00005582ccdc56ab mlir::detail::OpToOpPassAdaptor::runPipeline(llvm::iterator_range<llvm::pointee_iterator<std::unique_ptr<mlir::Pass, std::default_deletemlir::Pass >, mlir::Pass> >, mlir::Operation, mlir::AnalysisManager, bool, unsigned int, mlir::PassInstrumentor*, mlir::PassInstrumentation::PipelineParentInfo const*) /localdata/vinod/Polygeist/llvm-project/mlir/lib/Pass/Pass.cpp:452:0
#18 0x00005582ccdc6da0 mlir::PassManager::runPasses(mlir::Operation*, mlir::AnalysisManager) /localdata/vinod/Polygeist/llvm-project/mlir/lib/Pass/Pass.cpp:697:0
#19 0x00005582ccdc6be8 mlir::PassManager::run(mlir::Operation*) /localdata/vinod/Polygeist/llvm-project/mlir/lib/Pass/Pass.cpp:676:0
#20 0x00005582c843eb96 main /localdata/vinod/Polygeist/tools/mlir-clang/mlir-clang.cc:447:0
#21 0x00007fe4c4dcfbf7 __libc_start_main /build/glibc-S9d2JN/glibc-2.27/csu/../csu/libc-start.c:344:0
#22 0x00005582c840fb4a _start (/localdata/vinod/Polygeist/build/bin/mlir-clang+0x858b4a)

Copy constructor

It seems that the copy constructor cannot be properly handled by mlir-clang.

Input:

struct Tensor {
  Tensor(const Tensor &) {}
};

Tensor Add(const Tensor &, const Tensor &);

Tensor test(Tensor &A) {
  Tensor B = Add(A, A);
  return B;
}

Error:

cleanup of materialized not handledCXXConstructExpr 0x92adba8 'struct Tensor' 'void (const struct Tensor &)' elidable
`-MaterializeTemporaryExpr 0x92adb90 'const struct Tensor' lvalue
  `-ImplicitCastExpr 0x92adb78 'const struct Tensor' <NoOp>
    `-CallExpr 0x92ad910 'struct Tensor'
      |-ImplicitCastExpr 0x92ad8f8 'struct Tensor (*)(const struct Tensor &, const struct Tensor &)' <FunctionToPointerDecay>
      | `-DeclRefExpr 0x92ad8b0 'struct Tensor (const struct Tensor &, const struct Tensor &)' lvalue Function 0x92ad518 'Add' 'struct Tensor (const struct Tensor &, const struct Tensor &)'
      |-ImplicitCastExpr 0x92ad940 'const struct Tensor' lvalue <NoOp>
      | `-DeclRefExpr 0x92ad870 'struct Tensor' lvalue ParmVar 0x92ad648 'A' 'struct Tensor &'
      `-ImplicitCastExpr 0x92ad958 'const struct Tensor' lvalue <NoOp>
        `-DeclRefExpr 0x92ad890 'struct Tensor' lvalue ParmVar 0x92ad648 'A' 'struct Tensor &'
cleanup not handled
module attributes {llvm.data_layout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128", llvm.target_triple = "x86_64-unknown-linux-gnu"}  {
  func @_Z4testR6Tensor(%arg0: !llvm.ptr<struct<(i8)>>) -> !llvm.struct<(i8)> attributes {llvm.linkage = #llvm.linkage<external>} {
    %c1_i64 = arith.constant 1 : i64
    %0 = llvm.alloca %c1_i64 x !llvm.struct<(i8)> : (i64) -> !llvm.ptr<struct<(i8)>>
    %1 = llvm.alloca %c1_i64 x !llvm.struct<(i8)> : (i64) -> !llvm.ptr<struct<(i8)>>
    %2 = llvm.alloca %c1_i64 x !llvm.struct<(i8)> : (i64) -> !llvm.ptr<struct<(i8)>>
    %3 = llvm.alloca %c1_i64 x !llvm.struct<(i8)> : (i64) -> !llvm.ptr<struct<(i8)>>
    %4 = call @_Z3AddRK6TensorS1_(%arg0, %arg0) : (!llvm.ptr<struct<(i8)>>, !llvm.ptr<struct<(i8)>>) -> !llvm.struct<(i8)>
    llvm.store %4, %2 : !llvm.ptr<struct<(i8)>>
    %5 = llvm.load %3 : !llvm.ptr<struct<(i8)>>
    llvm.store %5, %1 : !llvm.ptr<struct<(i8)>>
    %6 = llvm.load %0 : !llvm.ptr<struct<(i8)>>
    return %6 : !llvm.struct<(i8)>
  }
  func private @_Z3AddRK6TensorS1_(!llvm.ptr<struct<(i8)>>, !llvm.ptr<struct<(i8)>>) -> !llvm.struct<(i8)> attributes {llvm.linkage = #llvm.linkage<external>}
  func @_ZN6TensorC1ERKS_(%arg0: !llvm.ptr<struct<(i8)>>, %arg1: !llvm.ptr<struct<(i8)>>) attributes {llvm.linkage = #llvm.linkage<linkonce_odr>} {
    return
  }
}

The generated MLIR seems to make sense though.

How to avoid inlining Polybench kernels?

Hi there,

It seems that the latest mlir-clang would automatically inline function calls, typically, for polybench kernels.

For instance, this is the @main I got from applying mlir-clang on jacobi-1d, with -O0 turned on:

 func @main(%arg0: i32, %arg1: !llvm.ptr<ptr<i8>>) -> i32 attributes {llvm.linkage = #llvm.linkage<external>} {
    %c0_i32 = constant 0 : i32
    %c120_i32 = constant 120 : i32
    %c1_i64 = constant 1 : i64
    %c1 = constant 1 : index
    %c0 = constant 0 : index
    %c3_i32 = constant 3 : i32
    %c2_i32 = constant 2 : i32
    %c120 = constant 120 : index
    %cst = constant 3.333300e-01 : f64
    %0 = llvm.alloca %c1_i64 x !llvm.ptr<ptr<i8>> : (i64) -> !llvm.ptr<ptr<ptr<i8>>>
    llvm.store %arg1, %0 : !llvm.ptr<ptr<ptr<i8>>>
    %1 = memref.alloc() : memref<120xf64>
    %2 = memref.alloc() : memref<120xf64>
    scf.for %arg2 = %c0 to %c120 step %c1 {
      %3 = index_cast %arg2 : index to i32
      %4 = sitofp %3 : i32 to f64
      %5 = sitofp %c2_i32 : i32 to f64
      %6 = addf %4, %5 : f64
      %7 = sitofp %c120_i32 : i32 to f64
      %8 = divf %6, %7 : f64
      memref.store %8, %1[%arg2] : memref<120xf64>
      %9 = sitofp %c3_i32 : i32 to f64
      %10 = addf %4, %9 : f64
      %11 = divf %10, %7 : f64
      memref.store %11, %2[%arg2] : memref<120xf64>
    }
    affine.for %arg2 = 0 to 40 {
      affine.for %arg3 = 1 to 119 {
        %3 = affine.load %1[%arg3 - 1] : memref<120xf64>
        %4 = affine.load %1[%arg3] : memref<120xf64>
        %5 = addf %3, %4 : f64
        %6 = affine.load %1[%arg3 + 1] : memref<120xf64>
        %7 = addf %5, %6 : f64
        %8 = mulf %cst, %7 : f64
        affine.store %8, %2[%arg3] : memref<120xf64>
      }
      affine.for %arg3 = 1 to 119 {
        %3 = affine.load %2[%arg3 - 1] : memref<120xf64>
        %4 = affine.load %2[%arg3] : memref<120xf64>
        %5 = addf %3, %4 : f64
        %6 = affine.load %2[%arg3 + 1] : memref<120xf64>
        %7 = addf %5, %6 : f64
        %8 = mulf %cst, %7 : f64
        affine.store %8, %1[%arg3] : memref<120xf64>
      }
    }
    call @print_array(%c120_i32, %1) : (i32, memref<120xf64>) -> ()
    memref.dealloc %1 : memref<120xf64>
    memref.dealloc %2 : memref<120xf64>
    return %c0_i32 : i32
  }

There is no call to the expected @kernel_jacobi_1d.

Did I miss any command line argument?

Simple matmul function cannot be raised to affine

The input C code is like this:

#define N 200
#define M 300
#define K 400
#define DATA_TYPE float

void matmul(DATA_TYPE A[N][K], DATA_TYPE B[K][M], DATA_TYPE C[N][M]) {
  int i, j, k;
  for (i = 0; i < N; i++)
    for (j = 0; j < M; j++)
      for (k = 0; k < K; k++)
        C[i][j] += A[i][k] * B[k][j];
}

I tried to feed this to mlir-clang by -

mlir-clang --function=matmul matmul.c

What I got is:

module attributes {llvm.data_layout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128", llvm.target_triple = "x86_64-unknown-linux-gnu"}  {
  func @matmul(%arg0: memref<?x400xf32>, %arg1: memref<?x300xf32>, %arg2: memref<?x300xf32>) {
    %c200 = constant 200 : index
    %c300 = constant 300 : index
    %c400 = constant 400 : index
    %c0 = constant 0 : index
    %c1 = constant 1 : index
    scf.for %arg3 = %c0 to %c200 step %c1 {
      scf.for %arg4 = %c0 to %c300 step %c1 {
        scf.for %arg5 = %c0 to %c400 step %c1 {
          %0 = memref.load %arg0[%arg3, %arg5] : memref<?x400xf32>
          %1 = memref.load %arg1[%arg5, %arg4] : memref<?x300xf32>
          %2 = mulf %0, %1 : f32
          %3 = memref.load %arg2[%arg3, %arg4] : memref<?x300xf32>
          %4 = addf %3, %2 : f32
          memref.store %4, %arg2[%arg3, %arg4] : memref<?x300xf32>
        }
      }
    }
    return
  }
}

I'm wondering whether it is possible to have the output MLIR in Affine?

Thanks!

Cpuification of Rodinia Task List

[ ] @wsmoses finish upstreaming cmpf
[ ] @ftynse correct struct layout calculation
[ ] check out & simplify break code
[ ] @wsmoses parallel distribute on affine as well
[ ] alloca hoisting in parallel loop

Optimizations:
[ ] @wsmoses graph cut caching
[ ] ? loop-invariant iter-args
[ ] generic while raising
[ ] improved if
[ ] @ftynse store forwarding
[ ] sync opts

Advice on getting libstdc++ headers?

First up, just wanted to say this is a really interesting project, I've got some curiosity about using it to do embedded DSL's in C++ through MLIR. If I'm barking up the wrong tree there, feel free to let me know.

But I'm testing this out on a small app

#include<Kokkos_Core.hpp>
int main(int argc, char* argv[]){
  Kokkos::initialize();
  Kokkos::finalize();
}

I can point mlir-clang at the Kokkos_Core header, but that includes and the like, and compilation dies when it sees stdarg and the like. I know that gcc-toolchain isn't supported, so I try a -I /home/projects/x86-64/gcc/11.1/include/c++/11.1.0/. Which bumps me into various versions of

/home/projects/x86-64/gcc/11.1/include/c++/11.1.0/bits/stringfwd.h:70:1: error: unknown type name '_GLIBCXX_BEGIN_NAMESPACE_CXX11'
_GLIBCXX_BEGIN_NAMESPACE_CXX11

Pretty much just "everything about _GLIBCXX doesn't exist." Any thoughts on a path forward here? Should I build libc++ and use that? Am I missing something obvious? Am I trying to do something the project isn't yet trying to support?

In any case, very cool idea, really looking forward to what you're doing here

Compiling function-local static variables

Currently, when compiling programs with function-local static variables, the static declaration is ignored. i.e.:

#define N 8
int foo() {
  static int bar[N];
  return bar[0];
}

and

#define N 8
int foo() {
  int bar[N];
  return bar[0];
}

both compile to:

module attributes {llvm.data_layout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128", llvm.target_triple = "x86_64-unknown-linux-gnu"}  {
  func @foo() -> i32 {
    %0 = memref.alloca() : memref<8xi32>
    %c0 = constant 0 : index
    %1 = memref.load %0[%c0] : memref<8xi32>
    return %1 : i32
  }
}

The expected behaviour would be something akin to what happens when moving the static variable into global scope, but further restricted such that the symbol @bar can only be referenced within function @foo:

module attributes {llvm.data_layout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128", llvm.target_triple = "x86_64-unknown-linux-gnu"}  {
  memref.global "private" @bar : memref<8xi32> = uninitialized
  func @foo() -> i32 {
    %0 = memref.get_global @bar : memref<8xi32>
    %c0 = constant 0 : index
    %1 = memref.load %0[%c0] : memref<8xi32>
    return %1 : i32
  }
}

Major Cleanups

  • Merge linkage cleanups @wsmoses
  • Merge address sanitizer @chelini
  • Rename / reorganize files
  • Organize Codegen Abstractions
  • Cleanup Codegen Methods
  • Cleanup MLIR Passes
  • Cleanup Driver Pass Infrastructure
  • Add license on all files @chelini
  • Agree on how to use namesapce, should we import them or using prefix like mlir::

MemRef type in interface

It is a follow-up to #44, and maybe I've asked about this earlier: could we generate function interface that has MemRef types with explicit dimensionality? For example, take the code from #44:

module attributes {llvm.data_layout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128", llvm.target_triple = "x86_64-unknown-linux-gnu"}  {
  func @matmul(%arg0: memref<?x400xf32>, %arg1: memref<?x300xf32>, %arg2: memref<?x300xf32>) {
    affine.for %arg3 = 0 to 200 {
      affine.for %arg4 = 0 to 300 {
        affine.for %arg5 = 0 to 400 {
          %0 = affine.load %arg0[%arg3, %arg5] : memref<?x400xf32>
          %1 = affine.load %arg1[%arg5, %arg4] : memref<?x300xf32>
          %2 = mulf %0, %1 : f32
          %3 = affine.load %arg2[%arg3, %arg4] : memref<?x300xf32>
          %4 = addf %3, %2 : f32
          affine.store %4, %arg2[%arg3, %arg4] : memref<?x300xf32>
        }
      }
    }
    return
  }
}

How could we make the interface of @matmul to be:

func @matmul(%arg0: memref<200x400xf32>, %arg1: memref<400x300xf32>, %arg2: memref<200x300xf32>)

Thanks!

Linkage issue with the latest commit in main

Hey guys,

I cannot compile with the option 2 - https://github.com/wsmoses/Polygeist#option-2-using-unified-llvm-mlir-clang-and-polygeist-build

The issue is in linking -

[4352/4352] Linking CXX executable bin/mlir-clang
FAILED: bin/mlir-clang
: && /mnt/ccnas2/bdp/rz3515/cccad/opt/bin/g++ -fPIC -fno-semantic-interposition -fvisibility-inlines-hidden -Werror=date-time -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wno-missing-field-initializers -pedantic -Wno-long-long -Wimplicit-fallthrough -Wno-maybe-uninitialized -Wno-class-memaccess -Wno-redundant-move -Wno-pessimizing-move -Wno-noexcept-type -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wsuggest-override -Wno-comment -Wmisleading-indentation -fdiagnostics-color -fPIC -fno-semantic-interposition -fvisibility-inlines-hidden -Werror=date-time -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wno-missing-field-initializers -pedantic -Wno-long-long -Wimplicit-fallthrough -Wno-maybe-uninitialized -Wno-class-memaccess -Wno-redundant-move -Wno-pessimizing-move -Wno-noexcept-type -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wsuggest-override -Wno-comment -Wmisleading-indentation -fdiagnostics-color -g -Wl,-rpath-link,/mnt/ccnas2/bdp/rz3515/projects/Polygeist/build/./lib tools/polygeist/mlir-clang/CMakeFiles/mlir-clang.dir/__/llvm-project/clang/tools/driver/cc1_main.cpp.o tools/polygeist/mlir-clang/CMakeFiles/mlir-clang.dir/__/llvm-project/clang/tools/driver/cc1as_main.cpp.o tools/polygeist/mlir-clang/CMakeFiles/mlir-clang.dir/__/llvm-project/clang/tools/driver/cc1gen_reproducer_main.cpp.o tools/polygeist/mlir-clang/CMakeFiles/mlir-clang.dir/mlir-clang.cc.o tools/polygeist/mlir-clang/CMakeFiles/mlir-clang.dir/Lib/utils.cc.o tools/polygeist/mlir-clang/CMakeFiles/mlir-clang.dir/Lib/pragmaHandler.cc.o -o bin/mlir-clang  -Wl,-rpath,"\$ORIGIN/../lib"  -lpthread  lib/libMLIRSCFTransforms.a  lib/libMLIRPolygeist.a  lib/libMLIRSupport.a  lib/libMLIRIR.a  lib/libMLIRAnalysis.a  lib/libMLIRLLVMIR.a  lib/libMLIRNVVMIR.a  lib/libMLIROpenMP.a  lib/libMLIRGPUOps.a  lib/libMLIRTransforms.a  lib/libMLIRSCFToStandard.a  lib/libMLIRStandardToLLVM.a  lib/libMLIRAffineTransforms.a  lib/libMLIRAffineToStandard.a  lib/libMLIRMathToLLVM.a  lib/libMLIRTargetLLVMIRImport.a  lib/libMLIRPolygeistTransforms.a  lib/libMLIRLLVMToLLVMIRTranslation.a  lib/libMLIRSCFToOpenMP.a  lib/libMLIROpenMPToLLVM.a  lib/libMLIROpenMPToLLVMIRTranslation.a  lib/libclangAST.a  lib/libclangBasic.a  lib/libclangCodeGen.a  lib/libclangDriver.a  lib/libclangFrontend.a  lib/libclangFrontendTool.a  lib/libclangLex.a  lib/libclangSerialization.a  lib/libMLIRVectorToLLVM.a  lib/libMLIRArmNeon.a  lib/libMLIRArmSVETransforms.a  lib/libMLIRArmSVE.a  lib/libMLIRAMXTransforms.a  lib/libMLIRAMX.a  lib/libMLIRX86VectorTransforms.a  lib/libMLIRX86Vector.a  lib/libMLIRPolygeist.a  lib/libMLIRNVVMIR.a  lib/libMLIRGPUOps.a  lib/libMLIRDLTI.a  lib/libMLIRSCFToStandard.a  lib/libMLIRStandardOpsTransforms.a  lib/libMLIRStandardToLLVM.a  lib/libMLIRMemRefToLLVM.a  lib/libMLIRLLVMCommonConversion.a  lib/libMLIRTransforms.a  lib/libMLIRCopyOpInterface.a  lib/libMLIRVector.a  lib/libMLIRAffineUtils.a  lib/libMLIRTransformUtils.a  lib/libMLIRRewrite.a  lib/libMLIRPDLToPDLInterp.a  lib/libMLIRPDLInterp.a  lib/libMLIRPDL.a  lib/libMLIRLoopAnalysis.a  lib/libMLIRPresburger.a  lib/libMLIROpenMP.a  lib/libMLIRTargetLLVMIRExport.a  lib/libMLIRTranslation.a  lib/libMLIRLLVMIRTransforms.a  lib/libMLIRLLVMIR.a  lib/libMLIRPass.a  lib/libMLIRAnalysis.a  lib/libMLIRDataLayoutInterfaces.a  lib/libMLIRLinalg.a  lib/libMLIRAffine.a  lib/libMLIRSCF.a  lib/libMLIRMemRef.a  lib/libMLIRMemRefUtils.a  lib/libMLIRLoopLikeInterface.a  lib/libMLIRTensor.a  lib/libMLIRStandard.a  lib/libMLIRCallInterfaces.a  lib/libMLIRControlFlowInterfaces.a  lib/libMLIRVectorInterfaces.a  lib/libMLIRCastInterfaces.a  lib/libMLIRInferTypeOpInterface.a  lib/libMLIRSideEffectInterfaces.a  lib/libMLIRMath.a  lib/libMLIRDialect.a  lib/libMLIRDialectUtils.a  lib/libMLIRViewLikeInterface.a  lib/libMLIRParser.a  lib/libMLIRTilingInterface.a  lib/libMLIRIR.a  lib/libMLIRSupport.a  lib/libclangCodeGen.a  lib/libLLVMCoverage.a  lib/libLLVMLTO.a  lib/libLLVMExtensions.a  lib/libLLVMCodeGen.a  lib/libLLVMPasses.a  lib/libLLVMCoroutines.a  lib/libLLVMipo.a  lib/libLLVMBitWriter.a  lib/libLLVMIRReader.a  lib/libLLVMAsmParser.a  lib/libLLVMLinker.a  lib/libLLVMInstrumentation.a  lib/libLLVMObjCARCOpts.a  lib/libLLVMVectorize.a  lib/libLLVMScalarOpts.a  lib/libLLVMAggressiveInstCombine.a  lib/libLLVMInstCombine.a  lib/libLLVMTarget.a  lib/libclangRewriteFrontend.a  lib/libclangARCMigrate.a  lib/libclangStaticAnalyzerFrontend.a  lib/libclangStaticAnalyzerCheckers.a  lib/libclangStaticAnalyzerCore.a  lib/libclangCrossTU.a  lib/libclangIndex.a  lib/libclangFrontend.a  lib/libclangDriver.a  lib/libLLVMOption.a  lib/libclangParse.a  lib/libclangSerialization.a  lib/libclangSema.a  lib/libclangAnalysis.a  lib/libclangASTMatchers.a  lib/libclangEdit.a  lib/libclangAST.a  lib/libLLVMFrontendOpenMP.a  lib/libLLVMTransformUtils.a  lib/libLLVMAnalysis.a  lib/libLLVMObject.a  lib/libLLVMBitReader.a  lib/libLLVMMCParser.a  lib/libLLVMMC.a  lib/libLLVMDebugInfoCodeView.a  lib/libLLVMTextAPI.a  lib/libLLVMProfileData.a  lib/libLLVMCore.a  lib/libLLVMBinaryFormat.a  lib/libLLVMRemarks.a  lib/libLLVMBitstreamReader.a  lib/libclangFormat.a  lib/libclangToolingInclusions.a  lib/libclangToolingCore.a  lib/libclangRewrite.a  lib/libclangLex.a  lib/libclangBasic.a  lib/libLLVMSupport.a  -lrt  -ldl  -lpthread  -lm  /usr/lib64/libz.so  /usr/lib64/libtinfo.so  lib/libLLVMDemangle.a && :
tools/polygeist/mlir-clang/CMakeFiles/mlir-clang.dir/__/llvm-project/clang/tools/driver/cc1_main.cpp.o: In function `llvm::InitializeAllTargetInfos()':
/mnt/ccnas2/bdp/rz3515/projects/Polygeist/build/include/llvm/Config/Targets.def:26: undefined reference to `LLVMInitializeX86TargetInfo'
tools/polygeist/mlir-clang/CMakeFiles/mlir-clang.dir/__/llvm-project/clang/tools/driver/cc1_main.cpp.o: In function `llvm::InitializeAllTargets()':
/mnt/ccnas2/bdp/rz3515/projects/Polygeist/build/include/llvm/Config/Targets.def:26: undefined reference to `LLVMInitializeX86Target'
tools/polygeist/mlir-clang/CMakeFiles/mlir-clang.dir/__/llvm-project/clang/tools/driver/cc1_main.cpp.o: In function `llvm::InitializeAllTargetMCs()':
/mnt/ccnas2/bdp/rz3515/projects/Polygeist/build/include/llvm/Config/Targets.def:26: undefined reference to `LLVMInitializeX86TargetMC'
tools/polygeist/mlir-clang/CMakeFiles/mlir-clang.dir/__/llvm-project/clang/tools/driver/cc1_main.cpp.o: In function `llvm::InitializeAllAsmPrinters()':
/mnt/ccnas2/bdp/rz3515/projects/Polygeist/build/include/llvm/Config/AsmPrinters.def:27: undefined reference to `LLVMInitializeX86AsmPrinter'
tools/polygeist/mlir-clang/CMakeFiles/mlir-clang.dir/__/llvm-project/clang/tools/driver/cc1_main.cpp.o: In function `llvm::InitializeAllAsmParsers()':
/mnt/ccnas2/bdp/rz3515/projects/Polygeist/build/include/llvm/Config/AsmParsers.def:27: undefined reference to `LLVMInitializeX86AsmParser'
collect2: error: ld returned 1 exit status
ninja: build stopped: subcommand failed.

CMakeCache.txt

Missing VisitExtVectorElementExpr implementation

#include <stddef>
#include <cstdint>

typedef size_t size_t_vec __attribute__((ext_vector_type(3)));

size_t test()
{
	size_t_vec stv;
	return stv.x;
}

Running mlir-clang with code above results in below assert:

mlir-clang/Lib/ValueCategory.cc:36: mlir::Value ValueCategory::getValue(mlir::OpBuilder &) const: Assertion `val && "must be not-null"' failed.

Which seems to be related to below function not being implemented.

ValueCategory MLIRScanner::VisitExtVectorElementExpr(clang::ExtVectorElementExpr *);

Wondering if anyone is working on it?

Best,
moadeli

Assert in Mem2Reg.cpp due to pointer address space mismatch

func @_ZN2cl4sycl6detail7declptrINS0_4itemILi2ELb1EEEEEPT_v() -> !llvm.ptr<struct<(struct<(struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>)>)>> attributes {llvm.linkage = #llvm.linkage<linkonce_odr>} {
  %false = arith.constant false
  %true = arith.constant true
  %0 = memref.alloca() : memref<i1>
  memref.store %true, %0[] : memref<i1>
  %1 = memref.alloca() : memref<!llvm.ptr<struct<(struct<(struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>)>)>>>
  %2 = memref.load %0[] : memref<i1>
  %3 = memref.load %1[] : memref<!llvm.ptr<struct<(struct<(struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>)>)>>>
  %4:2 = scf.if %true -> (i1, !llvm.ptr<struct<(struct<(struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>)>)>, 4>) {
    %6 = memref.load %0[] : memref<i1>
    %7:2 = scf.if %true -> (i1, !llvm.ptr<struct<(struct<(struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>)>)>, 4>) {
      %8 = llvm.mlir.null : !llvm.ptr<struct<(struct<(struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>)>)>, 4>
      memref.store %8, %1[] : memref<!llvm.ptr<struct<(struct<(struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>)>)>>>
      memref.store %false, %0[] : memref<i1>
      scf.yield %false, %8 : i1, !llvm.ptr<struct<(struct<(struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>)>)>, 4>
    } else {
      scf.yield %true, %3 : i1, !llvm.ptr<struct<(struct<(struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>)>)>>
    }
    scf.yield %7#0, %7#1 : i1, !llvm.ptr<struct<(struct<(struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>)>)>, 4>
  } else {
    scf.yield %true, %3 : i1, !llvm.ptr<struct<(struct<(struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>)>)>>
  }
  %5 = memref.load %1[] : memref<!llvm.ptr<struct<(struct<(struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>)>)>>>
  return %5 : !llvm.ptr<struct<(struct<(struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>)>)>>
}

The above MLIR representation is related to below code, dumped at the entry to the first call to Mem2Reg pass.

template <typename T> T *declptr() { return static_cast<T *>(nullptr); }

processing the function using Mem2Reg results in below assert.

!llvm.ptr<struct<(struct<(struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>)>)>> - !llvm.ptr<struct<(struct<(struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>, struct<(struct<(array<2 x i64>)>)>)>)>, 4>
mlir-clang: /home/m/Polygeist/lib/polygeist/Passes/Mem2Reg.cpp:641: {anonymous}::Mem2Reg::forwardStoreToLoad(mlir::Value, std::vector<long int, std::allocator<long int> >, llvm::SmallVectorImpl<mlir::Operation*>&)::<lambda(mlir::Block&, mlir::Value)>: Assertion `loadOp.getType() == lastVal.getType() && "mismatched load type"' failed.

The assert is related to mismatch between the address space of the pointer types in lastVal.getType() and loadType.getType.

Processing above as a stand alone C++ function does not result in the above assert. The assert is due to the pointer type being cached with address space of 4 in CodegenTypes::ConvertTypes while processing an earlier function.

To handle the assert above I considering 2 possible approaches:

  • To limit the comparison to ElementType of the pointers and ignore the Address space of the pointer types. Something like below:
    Check equality and assert on loadOp.getType()->getElementType() == lastVal.getType()->getElementType().

  • We could also consider applying the optimisation only when pointers at both load / store share similar address space.

I would appreciate any suggestions on above potential solutions or any other viable solution.

Regards,
Moadeli

Simple C++ Function

I tried to play around with mlir-clang on C++ input, and I found out it is a bit difficult.

void MatrixMult(float A[100][200], float B[200][300], float C[100][300]) {
  int i, j, k;

  for (i = 0; i < 100; i ++) {
    for (j = 0; j < 300; j ++) {
      C[i][j] = 0;
      for (k = 0; k < 200; k ++) {
        C[i][j] += A[i][k] * B[k][j];
      }
    }
  }
}

For example, still a simple matmul input, with the file name ended in .cc, I have output like:

» mlir-clang --function=MatrixMult --raise-scf-to-affine SimpleCXXFunc.cc
unhandled icmpunhandled icmpunhandled icmpunhandled icmpunhandled icmpunhandled icmpunhandled icmpunhandled icmpunhandled icmpunhandled icmpunhandled icmpunhandled icmpunhandled icmpunhandled icmpunhandled icmpunhandled icmpunhandled icmpunhandled icmpunhandled icmpunhandled icmpunhandled icmpunhandled icmpunhandled icmpunhandled icmpunhandled icmpunhandled icmpunhandled icmpmodule attributes {llvm.data_layout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128", llvm.target_triple = "x86_64-unknown-linux-gnu"}  {
  func @_Z10MatrixMultPA200_fPA300_fS2_(%arg0: memref<?x200xf32>, %arg1: memref<?x300xf32>, %arg2: memref<?x300xf32>) {
    %c0_i32 = constant 0 : i32
    %c100_i32 = constant 100 : i32
    %c300_i32 = constant 300 : i32
    %c200_i32 = constant 200 : i32
    %c1_i32 = constant 1 : i32
    %0 = scf.while (%arg3 = %c0_i32) : (i32) -> i32 {
      %1 = cmpi ult, %arg3, %c100_i32 : i32
      scf.condition(%1) %arg3 : i32
    } do {
    ^bb0(%arg3: i32):  // no predecessors
      %1 = index_cast %arg3 : i32 to index
      %2 = scf.while (%arg4 = %c0_i32) : (i32) -> i32 {
        %4 = cmpi ult, %arg4, %c300_i32 : i32
        scf.condition(%4) %arg4 : i32
      } do {
      ^bb0(%arg4: i32):  // no predecessors
        %4 = index_cast %arg4 : i32 to index
        %5 = sitofp %c0_i32 : i32 to f32
        memref.store %5, %arg2[%1, %4] : memref<?x300xf32>
        %6 = scf.while (%arg5 = %c0_i32) : (i32) -> i32 {
          %8 = cmpi ult, %arg5, %c200_i32 : i32
          scf.condition(%8) %arg5 : i32
        } do {
        ^bb0(%arg5: i32):  // no predecessors
          %8 = index_cast %arg5 : i32 to index
          %9 = memref.load %arg0[%1, %8] : memref<?x200xf32>
          %10 = memref.load %arg1[%8, %4] : memref<?x300xf32>
          %11 = mulf %9, %10 : f32
          %12 = memref.load %arg2[%1, %4] : memref<?x300xf32>
          %13 = addf %12, %11 : f32
          memref.store %13, %arg2[%1, %4] : memref<?x300xf32>
          %14 = addi %arg5, %c1_i32 : i32
          scf.yield %14 : i32
        }
        %7 = addi %arg4, %c1_i32 : i32
        scf.yield %7 : i32
      }
      %3 = addi %arg3, %c1_i32 : i32
      scf.yield %3 : i32
    }
    return
  }
}

It is pretty weird to find these icmpunhandled things, and raising seems not working as well. It is not an urgent request, but I'm curious to know why (and happy to help fixing!)

`operand #... does not dominate this use` error on simple program

For the following C program:

int gcd(int m, int n) {
  while (n > 0) {
    int r = m % n;
    m = n;
    n = r;
  }
  return m;
}

Running

mlir-clang -S gcd.c --function=*

produces the following output to stderr:

error: operand #1 does not dominate this use
module attributes {llvm.data_layout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128", llvm.target_triple = "x86_64-unknown-linux-gnu"}  {
  func @gcd(%arg0: i32, %arg1: i32) -> i32 attributes {llvm.linkage = #llvm.linkage<external>} {
    %c0_i32 = arith.constant 0 : i32
    %0:2 = scf.while (%arg2 = %arg1, %arg3 = %arg0) : (i32, i32) -> (i32, i32) {
      %1 = arith.cmpi sgt, %arg2, %c0_i32 : i32
      scf.condition(%1) %arg3, %arg2 : i32, i32
    } do {
    ^bb0(%arg2: i32, %arg3: i32):  // no predecessors
      %1 = arith.remsi %arg2, %arg3 : i32
      scf.yield %1, %arg2 : i32, i32
    }
    return %0#0 : i32
  }

So, while the generated MLIR looks good, the output is printed to stderr and mlir-clang returns 127, making downstream tooling fail.

Error when running polymer-opt on full input file translation

Using this versioning:

  • clang and llvm 11
  • mlir-clang: e5b8b83
  • polybench-c-4.2.1-beta
  • polymer: a7403a9ea584a8de1b3db930e687917cf60b199a

We run into an error.

An example, starting from a home folder that contains polybench-c-4.2.1-beta (kernel function had the 'static' attribute removed), Polygeist, and Polymer.

Running the following:

~/Polygeist/build/bin/mlir-clang ~/polybench-c-4.2.1-beta/linear-algebra/blas/gemm/gemm.c \
                                 -DPOLYBENCH_USE_SCALAR_LB -I ~/Polygeist/llvm-project/clang/lib/Headers \
                                 -I ~/polybench-c-4.2.1-beta/utilities -S --memref-fullrank > gemm.mlir
export LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:~/polymer/build/pluto/lib"
~/polymer/build/bin/polymer-opt gemm.mlir -extract-scop-stmt -pluto-opt > gemm-polymer.mlir

Produces this from Polymer:

 <unknown>:0: error: 'std.return' op has 0 operands, but enclosing function (@main) returns 1
 <unknown>:0: note: see current operation: "std.return"() : () -> ()

When translating only the kernel function with the flag '--kernel-function=kernel_gemm' in mlir-clang, polymer works fine.
However, when trying to translate the entire gemm.c file, we get the above error message.
The error is related to the extracted functions (S0, S1, S2, ...) existing within the main function, but we are unsure as to why.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.