-
Notifications
You must be signed in to change notification settings - Fork 155
[CIR][CodeGen] Adds support for inline assembler #308
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Thanks for contributing support for this in ClangIR, much welcome feature.
This one. I rather do it closer to original (to the most extend as possible) - easy for new people getting involved in the project to catch up and help.
This is fine, let's go incremental here.
You could also copy the tests from the original codegen and make sure it passes.
As long as you add an assert for other arches, x86 is fine.
My take here is to add some simple tests first and later start copy-n-paste the original ones, and make sure they pass.
Gotcha! Big patches are hard to review, I'm currently the only one doing PR reviews, so if we go even more incrementally it helps me build context and accept your patches faster. Can you break this down further? For example, the first PR could just add empty asm string, a very simple initial operation without all operands or attributes. Each following PR can then add constraints, etc. You can still keep this PR open with the complete work you have already, and slowly build the feature upstream one little piece at a time. |
Well, hard task! Let's try to do it. |
I will break the PR #308 into pieces and submit them one-by-one. The first PR introduce CIR operation and the `buildAsmStmt` function. The latter is the main place for the future changesm and the former was taken directly from MLIR LLVM IR dialect. As a result, there is nothing really interesting happen here, but now we can at least emit cir for an empty inline assembler. And as a first step
globals.cir should be fixed, goto.cir is dead given that we aren't supporting ThroughMLIR
In C, whenever we logically compare two values, we may store the result in any variable type. In this case, the boolean result should be cast to whatever type the variable is. This patch adds support for this.
This refactor merges the lowering logic of all the different kinds of loops into a single function. It also removes unnecessary LIT tests that validate LLVM dialect to LLVM IR lowering, as this functionality is not within CIR's scope. Fixes llvm#153 ghstack-source-id: ebaab85 Pull Request resolved: llvm#156
…lineAttr (llvm#134) Setting inline attributes based on user input and command line options. This is optional as functions do not need such an attribute will not get the attribute.
… assist clangir dev
cir.binop has the constraints on operands and results types than cannot support shifts with amount types different from the value getting shift. Adding cir.shift is a closer map.
LLVM's dialect does not have (at the time of writing) a way to represent zero-initializers. And, despite being possible to represent null pointers, it requires it to use a region-based initialization. To avoid this, LLVM operations that use either of these attributes are marked with a cir.zero attribute that will be identified by the LowerAttrToLLVMIR interface and patch the LLVM IR operation to be initialized with a zero-initializer or null. ghstack-source-id: 1872476 Pull Request resolved: llvm#163
Incremental work towards tracking exploded structs, no testcase just yet.
This change introduces `cir-translate` as a replacement of `mlir-translate` to convert CIR directly to LLVM IR. The main benefit of this is to utilize the CIR attribute interface to handle CIR-specific attributes such as `cir.extra`. Other advantages at this time, besides the cir attribute support, could be that we can go directly from CIR to LLVMIR without exposing the intermediate MLIR LLVM dialect form. Previously `cir-tool` emit the LLVM dialect form and `milr-translate` took it from there. Now `cir-translate` can directly take CIR and yield LLVMIR. I'm also renaming `cir-tool` to `cir-opt` which eventually would be just a CIR-to-CIR transformer, but for now I'm keeping the functionality of CIR to LLVM dialect. So, `cir-opt` will do all CIR-to-CIR transforms, just like LLVM `opt` or `mlir-opt`, and `cir-translate` will handle CIR to LLVMIR translation, and LLVMIR-to-LLVMIR transforms, like the LLVM `llc` or the `mlir-translate`
…vm#356) This PR adds a support for the multi-block case statements. Previously, the code example below caused crash in cir verification Lowering to the `llvm` dialect is pretty straightforward: the same logic as before is applied to all the region's blocks with no successors, i.e. we no longer think a case/default region contains only one block. The `CodeGen` part is a little bit tricky. Previously, any sub-statement of `case` or`default`, that was not any of them (i.e. neither `case` nor `default`) was processed with an insertion guard, meaning that the next sub-statement in the same clause was inserted again in the same block as the first one. It would be fine, once sub-statement didn't generate any blocks as well. For instance, ``` void foo(int a) { switch (a) { case 3: return; break; } } ``` The `return` statement actually emit a new block after, where the unreachable code with `break` should be inserted in. That's why we also need to update `lastCaseBlock` while generating `cir.switch` This is quite frequent bug in `llvm-test-suite`
This contains just the skeleton, but the idea is that this pass is going to contain transformations done on top CIR generated by the C/C++ idiom recognizer.
4e069c6
to
79d4dc7
Compare
I will break the PR #308 into pieces and submit them one-by-one. The first PR introduce CIR operation and the `buildAsmStmt` function. The latter is the main place for the future changesm and the former was taken directly from MLIR LLVM IR dialect. As a result, there is nothing really interesting happen here, but now we can at least emit cir for an empty inline assembler. And as a first step
ed3955a
to
8b7417c
Compare
I will break the PR #308 into pieces and submit them one-by-one. The first PR introduce CIR operation and the `buildAsmStmt` function. The latter is the main place for the future changesm and the former was taken directly from MLIR LLVM IR dialect. As a result, there is nothing really interesting happen here, but now we can at least emit cir for an empty inline assembler. And as a first step
I will break the PR llvm#308 into pieces and submit them one-by-one. The first PR introduce CIR operation and the `buildAsmStmt` function. The latter is the main place for the future changesm and the former was taken directly from MLIR LLVM IR dialect. As a result, there is nothing really interesting happen here, but now we can at least emit cir for an empty inline assembler. And as a first step
I will break the PR llvm#308 into pieces and submit them one-by-one. The first PR introduce CIR operation and the `buildAsmStmt` function. The latter is the main place for the future changesm and the former was taken directly from MLIR LLVM IR dialect. As a result, there is nothing really interesting happen here, but now we can at least emit cir for an empty inline assembler. And as a first step
@gitoleg can we close this? |
I will break the PR #308 into pieces and submit them one-by-one. The first PR introduce CIR operation and the `buildAsmStmt` function. The latter is the main place for the future changesm and the former was taken directly from MLIR LLVM IR dialect. As a result, there is nothing really interesting happen here, but now we can at least emit cir for an empty inline assembler. And as a first step
I will break the PR #308 into pieces and submit them one-by-one. The first PR introduce CIR operation and the `buildAsmStmt` function. The latter is the main place for the future changesm and the former was taken directly from MLIR LLVM IR dialect. As a result, there is nothing really interesting happen here, but now we can at least emit cir for an empty inline assembler. And as a first step
I will break the PR llvm#308 into pieces and submit them one-by-one. The first PR introduce CIR operation and the `buildAsmStmt` function. The latter is the main place for the future changesm and the former was taken directly from MLIR LLVM IR dialect. As a result, there is nothing really interesting happen here, but now we can at least emit cir for an empty inline assembler. And as a first step
I will break the PR #308 into pieces and submit them one-by-one. The first PR introduce CIR operation and the `buildAsmStmt` function. The latter is the main place for the future changesm and the former was taken directly from MLIR LLVM IR dialect. As a result, there is nothing really interesting happen here, but now we can at least emit cir for an empty inline assembler. And as a first step
I will break the PR llvm#308 into pieces and submit them one-by-one. The first PR introduce CIR operation and the `buildAsmStmt` function. The latter is the main place for the future changesm and the former was taken directly from MLIR LLVM IR dialect. As a result, there is nothing really interesting happen here, but now we can at least emit cir for an empty inline assembler. And as a first step
I will break the PR llvm#308 into pieces and submit them one-by-one. The first PR introduce CIR operation and the `buildAsmStmt` function. The latter is the main place for the future changesm and the former was taken directly from MLIR LLVM IR dialect. As a result, there is nothing really interesting happen here, but now we can at least emit cir for an empty inline assembler. And as a first step
I will break the PR llvm#308 into pieces and submit them one-by-one. The first PR introduce CIR operation and the `buildAsmStmt` function. The latter is the main place for the future changesm and the former was taken directly from MLIR LLVM IR dialect. As a result, there is nothing really interesting happen here, but now we can at least emit cir for an empty inline assembler. And as a first step
I will break the PR #308 into pieces and submit them one-by-one. The first PR introduce CIR operation and the `buildAsmStmt` function. The latter is the main place for the future changesm and the former was taken directly from MLIR LLVM IR dialect. As a result, there is nothing really interesting happen here, but now we can at least emit cir for an empty inline assembler. And as a first step
I will break the PR #308 into pieces and submit them one-by-one. The first PR introduce CIR operation and the `buildAsmStmt` function. The latter is the main place for the future changesm and the former was taken directly from MLIR LLVM IR dialect. As a result, there is nothing really interesting happen here, but now we can at least emit cir for an empty inline assembler. And as a first step
This PR adds support for the inline assembly in CIR.
The PR is explicitly marked as a draft, since some discussion needed.
As usually, I started with the original codegen (
clang/lib/Codegen
), and here is a first thing we need to agree on. The original code is kind of hard to read and the first desire is to refactor the code in this PR so that it can be readable or maintainable or both. Or at least do something - actually I already did some preliminary things to clean up a little.Another approach - we may leave the code closer to the original one in order to make it simpler to reflect all the future changes in the original codegen in CIR. So it's up to you to decide which approach to apply.
Now, the PR itself.
First of all, there are several unimplemented features and limitations:
llvm.assume
or bundles.Tests
The main question is about tests. As usually we want to have such tests, that cover all use cases, every branch of the code.
But the point is - we don't need to repeat all the assembler tests from the original codegen. E.g. we don't need to check how the parse functions work. We may assume that such things are checked there.
The same is true for the different architectures support. Probably, we will need to add something arch-specific in some point of time. But it's ok for now to check everything just for x86. By "everything" I mean the code, that is CIR specific, give or take, e.g. we emit the value/operation where we need to.
Thus, for now I added just several tests and I kind of feel shame for this small number of checks I do. I'm sure we want to have more tests. And I will definitely add more. But in the same time I'm sure we don't need too much. So, I would be happy to hear your point of view.
So far, some trivial examples work and you are welcome to check (or break something :) )
UPD:
Added tests from the the
clang/test/CodeGen/asm.c
with no checks included (so far). Just to make sure we don't crush in these scenario. Only three of them skipped: module level asm, vector types and goto.