Skip to content
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

Merged
merged 5 commits into from
Dec 14, 2023

Conversation

dkolsen-pgi
Copy link
Collaborator

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.  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.
@dkolsen-pgi
Copy link
Collaborator Author

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.
@dkolsen-pgi
Copy link
Collaborator Author

I updated the expected results for the test that failed, and the test now passes.

@bcardosolopes
Copy link
Member

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.

Is this due to some non-determinism we should fix or something else? I lost the context!

@dkolsen-pgi
Copy link
Collaborator Author

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:

    %17 = cir.const(#cir.int<1> : !s32i) : !s32i
    %18 = cir.load %3 : cir.ptr <!cir.vector<!s32i x 4>>, !cir.vector<!s32i x 4>
    %19 = cir.vec_elem %18[%17 : !s32i] <!s32i x 4> -> !s32i

On MacOS the generated CIR was slightly different:

    %17 = cir.load %3 : cir.ptr <!cir.vector<!s32i x 4>>, !cir.vector<!s32i x 4>
    %18 = cir.const(#cir.int<1> : !s32i) : !s32i
    %19 = cir.vec_elem %17[%18 : !s32i] <!s32i x 4> -> !s32i

I realized just now that this non-determinism is the result of this code in ScalarExprEmitter::VisitArraySubscriptExpr:

      return CGF.builder.create<mlir::cir::VecElemOp>(
          CGF.getLoc(E->getSourceRange()), Visit(E->getBase()),
          Visit(E->getIdx()));

The C++ standard does not guarantee the order of the two calls to Visit It seems that the CI compilers on Linux and Windows evaluate function arguments right-to-left while the MacOS compiler evaluates them left-to-right.

I should probably change the code so the calls to Visit are in their own statements, since those function calls have noticeable side effects.

Copy link
Member

@bcardosolopes bcardosolopes left a 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

clang/test/CIR/CodeGen/vectype.cpp Show resolved Hide resolved
clang/test/CIR/CodeGen/vectype.cpp Outdated Show resolved Hide resolved
clang/lib/CIR/Dialect/IR/CIRDialect.cpp Show resolved Hide resolved
clang/include/clang/CIR/Dialect/IR/CIROps.td Outdated Show resolved Hide resolved
clang/include/clang/CIR/Dialect/IR/CIROps.td Show resolved Hide resolved
clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp Show resolved Hide resolved
clang/include/clang/CIR/Dialect/IR/CIROps.td Outdated Show resolved Hide resolved
clang/include/clang/CIR/Dialect/IR/CIROps.td Show resolved Hide resolved
clang/test/CIR/CodeGen/vectype.cpp Outdated Show resolved Hide resolved
clang/test/CIR/IR/invalid.cir Show resolved Hide resolved
@bcardosolopes
Copy link
Member

Thanks for the detailed explanation, very subtle!

I should probably change the code so the calls to Visit are in their own statements, since those function calls have noticeable side effects.

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.
@dkolsen-pgi
Copy link
Collaborator Author

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.

Copy link
Member

@bcardosolopes bcardosolopes left a 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
Copy link
Member

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");
Copy link
Member

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.

@bcardosolopes
Copy link
Member

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!

@bcardosolopes bcardosolopes merged commit 54a37ba into llvm:main Dec 14, 2023
4 checks passed
lanza pushed a commit that referenced this pull request Dec 20, 2023
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.
lanza pushed a commit that referenced this pull request Jan 29, 2024
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.
lanza pushed a commit that referenced this pull request Mar 23, 2024
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.
eZWALT pushed a commit to eZWALT/clangir that referenced this pull request Mar 24, 2024
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.
eZWALT pushed a commit to eZWALT/clangir that referenced this pull request Mar 24, 2024
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.
lanza pushed a commit that referenced this pull request Apr 29, 2024
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.
lanza pushed a commit that referenced this pull request Apr 29, 2024
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.
eZWALT pushed a commit to eZWALT/clangir that referenced this pull request Apr 29, 2024
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.
lanza pushed a commit that referenced this pull request Apr 29, 2024
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.
bruteforceboy pushed a commit to bruteforceboy/clangir that referenced this pull request Oct 2, 2024
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.
Hugobros3 pushed a commit to shady-gang/clangir that referenced this pull request Oct 2, 2024
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.
keryell pushed a commit to keryell/clangir that referenced this pull request Oct 19, 2024
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.
lanza pushed a commit that referenced this pull request Nov 5, 2024
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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants