-
Notifications
You must be signed in to change notification settings - Fork 121
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 - part 1 #347
Conversation
This is the first part of implementing vector types and vector operations in ClangIR. This is enough to compile this test program. I haven't tried to do anything beyond that yet. ``` typedef int int4 __attribute__((vector_size(16))); int main(int argc, char** argv) { int4 a = { 1, argc, argc + 1, 4 }; int4 b = { 5, argc + 2, argc + 3, 8 }; int4 c = a + b; return c[1]; } ``` This change includes: * Fixed-sized vector types which are parameterized on the element type and the number of elements. For example, !cir.vector<s32i x 4>. (No scalable vector types yet; those will come later.) * New operation cir.vec which creates an object of a vector type with the given operands. * New operation cir.vec_elem which extracts an element from a vector. (The array subscript operation doesn't work here because the result is an rvalue, not an lvalue.) * Basic binary arithmetic operations on vector types, though only addition has been tested. There are no unary operators, comparison operators, casts, or shuffle operations yet. Those will all come later.
One of the tests failed because apparently the order in which CIR code gen emits the operands is not guaranteed. So I need to change one of the tests that checks the CIR output to be more flexible. |
The order in which CIR is generated is not always guaranteed, so the expected results for code gen tests need to be flexible about the order of operations and the names of MLIR values.
I updated the expected results for the test that failed, and the test now passes. |
Is this due to some non-determinism we should fix or something else? I lost the context! |
The automated CI tests are run on Linux, Windows, and MacOS. On the first two the generated MLIR for the cir.vec_elem op in the vector code gen test was:
On MacOS the generated CIR was slightly different:
I realized just now that this non-determinism is the result of this code in
The C++ standard does not guarantee the order of the two calls to I should probably change the code so the calls to |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is great, excited to have vector support! Comments inline
Thanks for the detailed explanation, very subtle!
That works for me! I wonder if we can find a better way to wrap/abstract these things so we can guarantee some determinism. We could also use the "DAG" stuff from FileCheck, but still annoying! |
Rename `cir.vec` op to `cir.vec.create`, and rename `cir.vec_elem` to `cir.vec.extract`. Rename any associated class types similarly. Add `vectorConstants()` and `scalableVectors()` to class `UnimplementedFeature`. Now that vector types are being implemented, `cirVectorType()` is too broad, and flags are needed for specific vector type features that haven't been implemented yet. When doing CodeGen for `cir.vec.extract`, call `Visit(E->getBase())` and `Visit(E->getIdx())` in separate statements so that their MLIR is always generated in a consistent order.
… into feature/vector-types
I pushed another commit that resolves most of the code review comments, along with promises to resolve the other code review comments in later PRs. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome. One minor comment and one missing bit: the LLVM testcases!
@@ -1110,6 +1110,48 @@ class CIRConstantLowering | |||
} | |||
}; | |||
|
|||
class CIRVectorCreateLowering |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice, great to already add LLVM lowering - can you please add a testcase to either clang/test/CIR/Lowering
or add an extra RUN
step to CodeGen/vectype.cpp
and check for LLVM output?
} | ||
if (!CGM.getCodeGenOpts().PreserveVec3Type && Ty->isVectorType() && | ||
Ty->castAs<clang::VectorType>()->getNumElements() == 3) | ||
llvm_unreachable("NYI: Special treatment of 3-element vectors"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you move this to after the atomic check and wrap it around if (const auto *ClangVecTy = Ty->getAs<VectorType>()) {
? No problem if this comes in a later PR, but I'd prefer if the skeleton is a bit more similar. Similar for buildStoreOfScalar
on the if (const auto *ClangVecTy = Ty->getAs<VectorType>()) {
part.
Actually, since @lanza is going to do a rebase very soon, I'm gonna merge this so you don't have to deal with rebase fall out. Please address both comments in follow up PRs! |
This is the first part of implementing vector types and vector operations in ClangIR, issue #284. This is enough to compile this test program. I haven't tried to do anything beyond that yet. ``` typedef int int4 __attribute__((vector_size(16))); int main(int argc, char** argv) { int4 a = { 1, argc, argc + 1, 4 }; int4 b = { 5, argc + 2, argc + 3, 8 }; int4 c = a + b; return c[1]; } ``` This change includes: * Fixed-sized vector types which are parameterized on the element type and the number of elements. For example, `!cir.vector<s32i x 4>`. (No scalable vector types yet; those will come later.) * New operation `cir.vec` which creates an object of a vector type with the given operands. * New operation `cir.vec_elem` which extracts an element from a vector. (The array subscript operation doesn't work here because the result is an rvalue, not an lvalue.) * Basic binary arithmetic operations on vector types, though only addition has been tested. There are no unary operators, comparison operators, casts, or shuffle operations yet. Those will all come later.
This is the first part of implementing vector types and vector operations in ClangIR, issue #284. This is enough to compile this test program. I haven't tried to do anything beyond that yet. ``` typedef int int4 __attribute__((vector_size(16))); int main(int argc, char** argv) { int4 a = { 1, argc, argc + 1, 4 }; int4 b = { 5, argc + 2, argc + 3, 8 }; int4 c = a + b; return c[1]; } ``` This change includes: * Fixed-sized vector types which are parameterized on the element type and the number of elements. For example, `!cir.vector<s32i x 4>`. (No scalable vector types yet; those will come later.) * New operation `cir.vec` which creates an object of a vector type with the given operands. * New operation `cir.vec_elem` which extracts an element from a vector. (The array subscript operation doesn't work here because the result is an rvalue, not an lvalue.) * Basic binary arithmetic operations on vector types, though only addition has been tested. There are no unary operators, comparison operators, casts, or shuffle operations yet. Those will all come later.
This is the first part of implementing vector types and vector operations in ClangIR, issue #284. This is enough to compile this test program. I haven't tried to do anything beyond that yet. ``` typedef int int4 __attribute__((vector_size(16))); int main(int argc, char** argv) { int4 a = { 1, argc, argc + 1, 4 }; int4 b = { 5, argc + 2, argc + 3, 8 }; int4 c = a + b; return c[1]; } ``` This change includes: * Fixed-sized vector types which are parameterized on the element type and the number of elements. For example, `!cir.vector<s32i x 4>`. (No scalable vector types yet; those will come later.) * New operation `cir.vec` which creates an object of a vector type with the given operands. * New operation `cir.vec_elem` which extracts an element from a vector. (The array subscript operation doesn't work here because the result is an rvalue, not an lvalue.) * Basic binary arithmetic operations on vector types, though only addition has been tested. There are no unary operators, comparison operators, casts, or shuffle operations yet. Those will all come later.
This is the first part of implementing vector types and vector operations in ClangIR, issue llvm#284. This is enough to compile this test program. I haven't tried to do anything beyond that yet. ``` typedef int int4 __attribute__((vector_size(16))); int main(int argc, char** argv) { int4 a = { 1, argc, argc + 1, 4 }; int4 b = { 5, argc + 2, argc + 3, 8 }; int4 c = a + b; return c[1]; } ``` This change includes: * Fixed-sized vector types which are parameterized on the element type and the number of elements. For example, `!cir.vector<s32i x 4>`. (No scalable vector types yet; those will come later.) * New operation `cir.vec` which creates an object of a vector type with the given operands. * New operation `cir.vec_elem` which extracts an element from a vector. (The array subscript operation doesn't work here because the result is an rvalue, not an lvalue.) * Basic binary arithmetic operations on vector types, though only addition has been tested. There are no unary operators, comparison operators, casts, or shuffle operations yet. Those will all come later.
This is the first part of implementing vector types and vector operations in ClangIR, issue llvm#284. This is enough to compile this test program. I haven't tried to do anything beyond that yet. ``` typedef int int4 __attribute__((vector_size(16))); int main(int argc, char** argv) { int4 a = { 1, argc, argc + 1, 4 }; int4 b = { 5, argc + 2, argc + 3, 8 }; int4 c = a + b; return c[1]; } ``` This change includes: * Fixed-sized vector types which are parameterized on the element type and the number of elements. For example, `!cir.vector<s32i x 4>`. (No scalable vector types yet; those will come later.) * New operation `cir.vec` which creates an object of a vector type with the given operands. * New operation `cir.vec_elem` which extracts an element from a vector. (The array subscript operation doesn't work here because the result is an rvalue, not an lvalue.) * Basic binary arithmetic operations on vector types, though only addition has been tested. There are no unary operators, comparison operators, casts, or shuffle operations yet. Those will all come later.
This is the first part of implementing vector types and vector operations in ClangIR, issue #284. This is enough to compile this test program. I haven't tried to do anything beyond that yet. ``` typedef int int4 __attribute__((vector_size(16))); int main(int argc, char** argv) { int4 a = { 1, argc, argc + 1, 4 }; int4 b = { 5, argc + 2, argc + 3, 8 }; int4 c = a + b; return c[1]; } ``` This change includes: * Fixed-sized vector types which are parameterized on the element type and the number of elements. For example, `!cir.vector<s32i x 4>`. (No scalable vector types yet; those will come later.) * New operation `cir.vec` which creates an object of a vector type with the given operands. * New operation `cir.vec_elem` which extracts an element from a vector. (The array subscript operation doesn't work here because the result is an rvalue, not an lvalue.) * Basic binary arithmetic operations on vector types, though only addition has been tested. There are no unary operators, comparison operators, casts, or shuffle operations yet. Those will all come later.
This is the first part of implementing vector types and vector operations in ClangIR, issue #284. This is enough to compile this test program. I haven't tried to do anything beyond that yet. ``` typedef int int4 __attribute__((vector_size(16))); int main(int argc, char** argv) { int4 a = { 1, argc, argc + 1, 4 }; int4 b = { 5, argc + 2, argc + 3, 8 }; int4 c = a + b; return c[1]; } ``` This change includes: * Fixed-sized vector types which are parameterized on the element type and the number of elements. For example, `!cir.vector<s32i x 4>`. (No scalable vector types yet; those will come later.) * New operation `cir.vec` which creates an object of a vector type with the given operands. * New operation `cir.vec_elem` which extracts an element from a vector. (The array subscript operation doesn't work here because the result is an rvalue, not an lvalue.) * Basic binary arithmetic operations on vector types, though only addition has been tested. There are no unary operators, comparison operators, casts, or shuffle operations yet. Those will all come later.
This is the first part of implementing vector types and vector operations in ClangIR, issue llvm#284. This is enough to compile this test program. I haven't tried to do anything beyond that yet. ``` typedef int int4 __attribute__((vector_size(16))); int main(int argc, char** argv) { int4 a = { 1, argc, argc + 1, 4 }; int4 b = { 5, argc + 2, argc + 3, 8 }; int4 c = a + b; return c[1]; } ``` This change includes: * Fixed-sized vector types which are parameterized on the element type and the number of elements. For example, `!cir.vector<s32i x 4>`. (No scalable vector types yet; those will come later.) * New operation `cir.vec` which creates an object of a vector type with the given operands. * New operation `cir.vec_elem` which extracts an element from a vector. (The array subscript operation doesn't work here because the result is an rvalue, not an lvalue.) * Basic binary arithmetic operations on vector types, though only addition has been tested. There are no unary operators, comparison operators, casts, or shuffle operations yet. Those will all come later.
This is the first part of implementing vector types and vector operations in ClangIR, issue #284. This is enough to compile this test program. I haven't tried to do anything beyond that yet. ``` typedef int int4 __attribute__((vector_size(16))); int main(int argc, char** argv) { int4 a = { 1, argc, argc + 1, 4 }; int4 b = { 5, argc + 2, argc + 3, 8 }; int4 c = a + b; return c[1]; } ``` This change includes: * Fixed-sized vector types which are parameterized on the element type and the number of elements. For example, `!cir.vector<s32i x 4>`. (No scalable vector types yet; those will come later.) * New operation `cir.vec` which creates an object of a vector type with the given operands. * New operation `cir.vec_elem` which extracts an element from a vector. (The array subscript operation doesn't work here because the result is an rvalue, not an lvalue.) * Basic binary arithmetic operations on vector types, though only addition has been tested. There are no unary operators, comparison operators, casts, or shuffle operations yet. Those will all come later.
This is the first part of implementing vector types and vector operations in ClangIR, issue llvm#284. This is enough to compile this test program. I haven't tried to do anything beyond that yet. ``` typedef int int4 __attribute__((vector_size(16))); int main(int argc, char** argv) { int4 a = { 1, argc, argc + 1, 4 }; int4 b = { 5, argc + 2, argc + 3, 8 }; int4 c = a + b; return c[1]; } ``` This change includes: * Fixed-sized vector types which are parameterized on the element type and the number of elements. For example, `!cir.vector<s32i x 4>`. (No scalable vector types yet; those will come later.) * New operation `cir.vec` which creates an object of a vector type with the given operands. * New operation `cir.vec_elem` which extracts an element from a vector. (The array subscript operation doesn't work here because the result is an rvalue, not an lvalue.) * Basic binary arithmetic operations on vector types, though only addition has been tested. There are no unary operators, comparison operators, casts, or shuffle operations yet. Those will all come later.
This is the first part of implementing vector types and vector operations in ClangIR, issue llvm#284. This is enough to compile this test program. I haven't tried to do anything beyond that yet. ``` typedef int int4 __attribute__((vector_size(16))); int main(int argc, char** argv) { int4 a = { 1, argc, argc + 1, 4 }; int4 b = { 5, argc + 2, argc + 3, 8 }; int4 c = a + b; return c[1]; } ``` This change includes: * Fixed-sized vector types which are parameterized on the element type and the number of elements. For example, `!cir.vector<s32i x 4>`. (No scalable vector types yet; those will come later.) * New operation `cir.vec` which creates an object of a vector type with the given operands. * New operation `cir.vec_elem` which extracts an element from a vector. (The array subscript operation doesn't work here because the result is an rvalue, not an lvalue.) * Basic binary arithmetic operations on vector types, though only addition has been tested. There are no unary operators, comparison operators, casts, or shuffle operations yet. Those will all come later.
This is the first part of implementing vector types and vector operations in ClangIR, issue llvm#284. This is enough to compile this test program. I haven't tried to do anything beyond that yet. ``` typedef int int4 __attribute__((vector_size(16))); int main(int argc, char** argv) { int4 a = { 1, argc, argc + 1, 4 }; int4 b = { 5, argc + 2, argc + 3, 8 }; int4 c = a + b; return c[1]; } ``` This change includes: * Fixed-sized vector types which are parameterized on the element type and the number of elements. For example, `!cir.vector<s32i x 4>`. (No scalable vector types yet; those will come later.) * New operation `cir.vec` which creates an object of a vector type with the given operands. * New operation `cir.vec_elem` which extracts an element from a vector. (The array subscript operation doesn't work here because the result is an rvalue, not an lvalue.) * Basic binary arithmetic operations on vector types, though only addition has been tested. There are no unary operators, comparison operators, casts, or shuffle operations yet. Those will all come later.
This is the first part of implementing vector types and vector operations in ClangIR, issue #284. This is enough to compile this test program. I haven't tried to do anything beyond that yet. ``` typedef int int4 __attribute__((vector_size(16))); int main(int argc, char** argv) { int4 a = { 1, argc, argc + 1, 4 }; int4 b = { 5, argc + 2, argc + 3, 8 }; int4 c = a + b; return c[1]; } ``` This change includes: * Fixed-sized vector types which are parameterized on the element type and the number of elements. For example, `!cir.vector<s32i x 4>`. (No scalable vector types yet; those will come later.) * New operation `cir.vec` which creates an object of a vector type with the given operands. * New operation `cir.vec_elem` which extracts an element from a vector. (The array subscript operation doesn't work here because the result is an rvalue, not an lvalue.) * Basic binary arithmetic operations on vector types, though only addition has been tested. There are no unary operators, comparison operators, casts, or shuffle operations yet. Those will all come later.
This is the first part of implementing vector types and vector operations in ClangIR, issue #284. This is enough to compile this test program. I haven't tried to do anything beyond that yet.
This change includes:
Fixed-sized vector types which are parameterized on the element type and the number of elements. For example,
!cir.vector<s32i x 4>
. (No scalable vector types yet; those will come later.)New operation
cir.vec
which creates an object of a vector type with the given operands.New operation
cir.vec_elem
which extracts an element from a vector. (The array subscript operation doesn't work here because the result is an rvalue, not an lvalue.)Basic binary arithmetic operations on vector types, though only addition has been tested.
There are no unary operators, comparison operators, casts, or shuffle operations yet. Those will all come later.