-
Notifications
You must be signed in to change notification settings - Fork 86
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
[CIR] Vector types, comparison operators #420
Closed
Closed
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
There is no really good way to test this since `-verify` does not really care how many times the same diagnostics shows up (somehow it already dedups). This improves user experience a tiny bit :)
Before this fix foo(1, 1) returned 255 in int foo(int a, int b) { return a && b; }
Whenever a variable declaration is found, it is created as a global variable in the module. In C, these variables must be instantiated with the CIRGenBuilder::createVersionedGlobal to prevent naming conflicts when multiple static variables are declared across the compilation unit. In C++, name mangling is used to prevent naming conflicts.
Remove boilerplate code for replacing a CIR global op with a region initialized LLVM global op and mark variables as constant whenever possible. ghstack-source-id: dcf7ff7183426700a780f08cc2e29268b10a50c5 Pull Request resolved: llvm#199
At its core, this patch fixes an issue where the ConstStruct parser would infer its type from the list of elements and override its explicit attribute type that had already been parsed. This caused type mismatches since the name of the StructType would be dropped. Since `cir.typeinfo` depended on this broken parsing method to work, it was also fixed to use a `ArrayAttr` instead of a `cir.const_struct` to store its values. To simplify parsing and printing struct member on both `cir.typeinfo` and `cir.const_struct`, the custom `ConstStructMembers` parser/printer was renamed to `StructMembers` and is now used on both attributes. It was also refactored to patch malformed spacing between members and to simplify the code. ghstack-source-id: 1c913c6c00b2826fd0dac3dd18e7cb56bfe2e737 Pull Request resolved: llvm#200
Adds support for CIR globals with basic struct initializers. This patch tackes only primitive, pointers, and simple nested structs. Arrays, char pointers, and other more complex types are not supported yet. ghstack-source-id: a077f04ca9ddb2649bcba0e986280ab19eaabe79 Pull Request resolved: llvm#201
Lowers the particular case where an array of structs is constant-initialized. ghstack-source-id: f8389d899e07f73485658d86469d7595a4373901 Pull Request resolved: llvm#202
Updates the lowering of cir.const to support #cir.const_struct as a initializer, allowing the initialization of local structs with said attribute. ghstack-source-id: cc6c1378775bd2239c821c357e281bbc8cc3b0a7 Pull Request resolved: llvm#203
Global addresses are constant, so we can initialize them at compile time using CIR's global_view attribute. This patch adds codegen support for the initialization of variables with constant global addresses. Since a builder method was added for global_view, the patch also updates the codegen of global variables to use it wherever possible. ghstack-source-id: 513365c52ac1ca603a81fcf3ff124b5da39f6f14 Pull Request resolved: llvm#204
Adds lowering logic for CIR's global_view attributes with no indexes. This is done by converting the global to a region-initialized LLVM global operation, where the region returns the address of the global used in the gloval_view initializer attribute. ghstack-source-id: a9452eddbd516553273461a8187afcebc211e4d3 Pull Request resolved: llvm#205
Constant initialization of static local arrays would fail due to a mismatch between the variable and the initializer type size. This patch fixes the data layout interface implementation for the cir.array type. A complete array in C/C++ should have its type size in bits equal to the size of the array times the size of the element type. ghstack-source-id: 56f3f2918b23309210ad026017bafa37ca03b2d4 Pull Request resolved: llvm#206
ghstack-source-id: 1f793b2abcb144ab10b1ddbd99f12d1dcc6c8707 Pull Request resolved: llvm#207
…es instead of region initializers.
PR llvm#200 broke the vtableAttr usage, as it was not properly refactored to use ArrayAttr instead of ConstStructAttr to store its members.
This change does the CIR generation for globals initialized by a constructor call. It currently only covers C++ to CIR generation. The corresponding LLVM lowering will be in a follow-up commit. A motivating example is ``` class Init { friend class ios_base; public: Init(bool); ~Init(); private: static bool _S_synced_with_stdio; }; static Init ioinit(true); ``` Unlike what the default Clang codegen generates LLVM that detaches the initialization code from the global var definition (like below), we are taking a different approach that keeps them together, which we think will make the later dataflow analysis/transform easier. ``` @_ZL8ioinit = internal global %class.Init zeroinitializer, align 1, !dbg !0 define internal void @cxx_global_var_init() #0 section ".text.startup" !dbg !23 { entry: call void @_ZN4InitC2Ev(ptr noundef nonnull align 1 dereferenceable(1) @_ZL8ioinit), !dbg !27 %0 = call i32 @cxa_atexit(ptr @_ZN4InitD1Ev, ptr @_ZL8ioinit, ptr @dso_handle) llvm#3, !dbg !29 ret void, !dbg !27 } ``` So on CIR, we have something like: ``` cir.global "private" internal @_ZL8__ioinit = ctor : !ty_22class2EInit22 { %0 = cir.get_global @_ZL8__ioinit : cir.ptr <!ty_22class2EInit22> loc(#loc8) %1 = cir.const(#true) : !cir.bool loc(#loc5) cir.call @_ZN4InitC1Eb(%0, %1) : (!cir.ptr<!ty_22class2EInit22>, !cir.bool) -> () loc(#loc6) } ``` The destructor support will also be in a separate change.
This PR fixes lowering for `break/continue` in loops. The idea is to replace `cir.yield break` and `cir.yield continue` with the branch operations to the corresponding blocks. Note, that we need to ignore nesting loops and don't touch `break` in switch operations. Also, `yield` from `if` need to be considered only when it's not the loop `yield` and `continue` in switch is ignored since it's processed in the loops lowering. Fixes llvm#160
…cations are the same
Essentially emits an LValue for the struct and then passes it as a call argument.
Enabling IR printing with --mlir-print-ir-after=passName1, passName2. This requires all CIR passes to be registered at startup time.
Summary: Setting the Optnone attribute for CIR functions and progating it all the way down to LLVM IR for those not supposed to be optimized.
This change is a prerequisite of llvm#235
The next step for inline assembly. Sorry, maybe it looks too big on the first glance. And it's kind of hard to extract something well-grained from the code and introduce it as a separate PR, but I try. Actually there is nothing really interesting done here, and the next will (I hope :) ) simplify your review process. 1) In this PR we introduce operand's constraints and the task is to collect them (and maybe transform a little) 2) There are two big functions copy-pasted from the traditional `Codegen` and I doubt they need to be reviewed. 3) We still don't do anything CIR-specific. Basically, we just work with strings in the same way like traditional `Codegen` does. 4) We just iterate over the input and output operands and collect the constraints 5) We still follow to the traditional `CodeGen` and don't do anything new, except a separate function that collects constraints infos in the very beginning of the `buildStmt`. Also, I renamed `AsmDialect` to `AsmFlavor` as you asked in llvm#326
This PR fixes CIR lowering for the next case. ``` void foo() { struct { int a; int b; } a[1] = {{0,1}}; } ``` Note, we don't create attribute here and lower such const arrays as values.
When introducing attribute `#cir.int`, the constant type verification is not updated. If a `cir.const` operation produces an integral constant from a `#cir.int` attribute, the integer's type is not verified: ```mlir %1 = cir.const(#cir.int<0> : !cir.int<s, 8>) : !cir.int<u, 8> // Not verified: !cir.int<s, 8> differs from !cir.int<u, 8> ``` The corresponding test is also wrong but fail to be detected. This patch fixes this issue.
This is part 2 of implementing vector types and vector operations in ClangIR, issue llvm#284. Create new operation `cir.vec.insert`, which changes one element of an existing vector object and returns the modified vector object. The input and output vectors are prvalues; this operation does not touch memory. The assembly format and the order of the arguments match that of llvm.insertelement in the LLVM dialect, since the operations have identical semantics. Implement vector element lvalues in class `LValue`, adding member functions `getVectorAddress()`, `getVectorPointer()`, `getVectorIdx()`, and `MakeVectorElt(...)`. The assembly format for operation `cir.vec.extract` was changed to match that of llvm.extractelement in the LLVM dialect, since the operations have identical semantics. These two features, `cir.vec.insert` and vector element lvalues, are used to implement `v[n] = e`, where `v` is a vector. This is a little tricky, because `v[n]` isn't really an lvalue, as its address cannot be taken. The only place it can be used as an lvalue is on the left-hand side of an assignment. Implement unary operators on vector objects (except for logical not on a vector mask, which will be covered in a future commit for boolean vectors). The code for lowering cir.unary for all types, in `CIRUnaryOpLowering::matchAndRewrite`, was largely rewritten. Support for unary `+` on non-vector pointer types was added. (It was already supported and tested in AST->ClangIR CodeGen, but was missing from ClangIR->LLVM Dialect lowering.) Add tests for all binary vector arithmetic operations other than relational operators and shift operators. There were all working after the previous vector types commit, but only addition had beet tested at the time. Co-authored-by: Bruno Cardoso Lopes <bcardosolopes@users.noreply.github.com>
Detaches the representation of the C/C++ `continue` statement into a separate operation. This simplifies mostly lowering and verifications related to `continue` statements, as well as the definition and lowering of the `cir.yield` operation. A few checks regarding region terminators were also removed from the lowering stage, since they are already enforced by MLIR. ghstack-source-id: 1810a48ada88fe7ef5638b0758a2298d9cfbdb8b Pull Request resolved: llvm#394
Same rationale as `cir.continue`, it detaches the representation of the C/C++ `break` statement into a separate operation. This simplifies lowering and verifications related to `break` statements, as well as the definition and lowering of the `cir.yield` operation. ghstack-source-id: 929cf96c3abe51d717c2fa6ca9e0073e42e770c6 Pull Request resolved: llvm#395
This changes the `cir.await` operation to expect a `cir.condition` as the terminator for the ready region. This simplifies the `cir.await` while also simplifying the `cir.yield`. If `cir.condition` holds a true value, then the `cir.await` will continue the coroutine, otherwise, it will suspend its execution. The `cir.condition` op was also updated to allow `cir.await` as its parent operation. ghstack-source-id: 1ebeb2cfbdeff6f289936d16354cba534e093ea7 Pull Request resolved: llvm#396
Instead of having a `cir.yield fallthrough` operation, the default branching behavior of the parent operation is denoted by `cir.yield`. In other words, a `cir.yield` operation in a switch case region represents the default branching behavior of the switch operation, which is a fallthrough. The `cir.yield` operation now represents the default branching behavior of the parent operation's region. For example, in a if-else region, a `cir.yield` operation represents a branch to the exit block. ghstack-source-id: 713c457dfb2228fbdf63ba72dd6396665512bb9d Pull Request resolved: llvm#397
…tcase - Add cir.try_call parsing. - Add block destinations and hookup exception info type. - Properly implement interface methods. Printer is still missing, but coming next.
After some discussions with @sitio-couto, it might be better if we use a simplified version that doesn't take the labels into account just yet. `cir.try_call` should have the same semantics as `cir.break`, in the sense that it needs further expansion when getting rid of structured control flow. Early lowering here would complicate CIR generated code and make it harder to analyse. Further CIR to CIR passes will properly expand this at some point prior to LLVM lowering.
We can now handle more of EHScope::Catch and lay out the skeleton for CIR's version of that, adding tons of asserts for cases not currently handled. As part of this we're able to build the clause list as part of CatchOp based on the handlers, and create allocation for the exception_info type. In the next part (where we currently hit an assert) of this work, the CatchOp will then get its regions populated. Incremental steps into getting basic exceptions to work, not enough for a testcase just yet.
Doesn't do a lot of things compared to LLVM traditional codegen, one more step towards basic exception support. No testcase possible just yet.
- Add an extra CatchOp region to hold fallback (where EH usually resumes or rethrows as part of try/catch). - Emit `cir.resume` on the fallback region. Incremental step into the next assertion, still missing pieces before adding the first testcase.
This commit supports the codegen of wide string literals, including `wchar_t` string literals, `char16_t` string literals, and `char32_t` string literals. I'm not following the proposal in llvm#374. The clang frontend doesn't record the literal string. It only records the encoded code units for wide string literals. So I believe that a dedicated string attribute with an encoding tag as described in llvm#374 may not be that helpful as I thought.
This patch introduces initial support for: ``` pragma omp parallel ``` This patch doesn't add support for any of the `parallel` clauses, including variable privatization; thus, all variables are handled as shared. This PR fixes issue llvm#285.
Adds an interface to generically handle lowering and analysis of loop operations in CIR. It can also perform verification of invariants common to all loop operations. ghstack-source-id: 0e413b14ea063a2b0d75aeaca0af88e547c15277 Pull Request resolved: llvm#405
Leverages the new LoopOpInterface for lowering instead of the LoopOp operation. This is a step towards removing the LoopOp operation. ghstack-source-id: 28c1294833a12669d222a293de76609d2cf19148 Pull Request resolved: llvm#406
Creates a separate C/C++ operation for do-while loops, while keeping the LoopOpInterface to generically handle loops. This simplifies the IR generation and printing/parsing of do-while loops. It also allows us to define it regions in the order that they are executed, which is useful for the lifetime analysis. ghstack-source-id: b4d9517197b8f82ae677dc2684101fe5762b21b7 Pull Request resolved: llvm#407
Creates a separate C/C++ operation for while loops, while keeping the LoopOpInterface to generically handle loops. This simplifies the IR generation and printing/parsing of while loops. ghstack-source-id: 29a6d7530263a4f96dbe6ce3052875831126005d Pull Request resolved: llvm#408
This patch completes the deprecation of the generic `cir.loop` operation by adding a new `cir.for` operation and removing the `cir.loop` op. The new representation removes some bloat and places the regions in order of execution. ghstack-source-id: 886e0dacc632e5809015e2212810d690ef3ec294 Pull Request resolved: llvm#409
…rations More machinery for exceptions. This time around we finally emit a cir.catch and fix the order of emitting operations. This allows a testcase to be added. I also added `CatchParamOp`, which fetches the arguments for the clauses from the !cir.eh_info object. Work coming next: - Dtors. - Use cir.try instead of cir.scope. - Eesume. - Documentation.`
This is part 3 of implementing vector types and vector operations in ClangIR, issue llvm#284. Create new operation `cir.vec.cmp` which implements the relational comparison operators (`== != < > <= >=`) on vector types. A new operation was created rather than reusing `cir.cmp` because the result is a vector of a signed intergral type, not a `bool`. Add CodeGen and Lowering tests for vector comparisons. Fix the floating-point comparison predicate when lowering to LLVM. To handle NaN values correctly, the comparisons need to be ordered rather than unordered. (Except for `!=`, which needs to be unordered.) For example, "ueq" was changed to "oeq".
4e069c6
to
79d4dc7
Compare
@lanza just rebased and this has the side effect of breaking GH PR workflow, making it impossible to review, apologies. Please rebase! |
I couldn't figure out how to correctly update my branch after the rebase, and it was trivial to create a new branch with the correct contents. So I created a new PR, #432. I am abandoning this one. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This is part 3 of implementing vector types and vector operations in ClangIR, issue #284.
Create new operation
cir.vec.cmp
which implements the relational comparison operators (== != < > <= >=
) on vector types. A new operation was created rather than reusingcir.cmp
because the result is a vector of a signed intergral type, not abool
.Add CodeGen and Lowering tests for vector comparisons.
Fix the floating-point comparison predicate when lowering to LLVM. To handle NaN values correctly, the comparisons need to be ordered rather than unordered. (Except for
!=
, which needs to be unordered.) For example, "ueq" was changed to "oeq".