-
Notifications
You must be signed in to change notification settings - Fork 801
[SYCL] Fix check for reqd_sub_group_size attribute mismatches #1905
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
Changes from 3 commits
8a35cf0
608ee3a
6b578a6
3bee3df
540853f
c625a69
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -308,14 +308,6 @@ static void reportConflictingAttrs(Sema &S, FunctionDecl *F, const Attr *A1, | |
| F->setInvalidDecl(); | ||
| } | ||
|
|
||
| // Returns the signed constant integer value represented by given expression. | ||
| static int64_t getIntExprValue(Sema &S, const Expr *E) { | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I decided to replace this function with extension to
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have a feeling, that I've already seen that type of function is Sema, like 'check unsigned int arguments' (can't grep it right now), so I see no value in the function above.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we use this function then?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I prefer to have some cached value instead of evaluating attribute argument each time we need it to perform some correctness check |
||
| llvm::APSInt Val(32); | ||
| bool IsValid = E->isIntegerConstantExpr(Val, S.getASTContext()); | ||
| assert(IsValid && "expression must be constant integer"); | ||
| return Val.getSExtValue(); | ||
| } | ||
|
|
||
| class MarkDeviceFunction : public RecursiveASTVisitor<MarkDeviceFunction> { | ||
| public: | ||
| MarkDeviceFunction(Sema &S) | ||
|
|
@@ -1696,15 +1688,16 @@ void Sema::MarkDevice(void) { | |
| KernelBody ? KernelBody->getAttr<SYCLSimdAttr>() : nullptr; | ||
| if (auto *Existing = | ||
| SYCLKernel->getAttr<IntelReqdSubGroupSizeAttr>()) { | ||
| if (Existing->getSubGroupSize() != Attr->getSubGroupSize()) { | ||
| if (Existing->getSubGroupSizeEvaluated(getASTContext()) != | ||
| Attr->getSubGroupSizeEvaluated(getASTContext())) { | ||
| Diag(SYCLKernel->getLocation(), | ||
| diag::err_conflicting_sycl_kernel_attributes); | ||
| Diag(Existing->getLocation(), diag::note_conflicting_attribute); | ||
| Diag(Attr->getLocation(), diag::note_conflicting_attribute); | ||
| SYCLKernel->setInvalidDecl(); | ||
| } | ||
| } else if (KBSimdAttr && | ||
| (getIntExprValue(*this, Attr->getSubGroupSize()) != 1)) { | ||
| (Attr->getSubGroupSizeEvaluated(getASTContext()) != 1)) { | ||
| reportConflictingAttrs(*this, KernelBody, KBSimdAttr, Attr); | ||
| } else { | ||
| SYCLKernel->addAttr(A); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1161,6 +1161,36 @@ namespace { | |
| void writeHasChildren(raw_ostream &OS) const override { OS << "true"; } | ||
| }; | ||
|
|
||
| class IntegerExprArgument : public ExprArgument { | ||
| private: | ||
| int UndefValue; | ||
|
|
||
| public: | ||
| IntegerExprArgument(const Record &Arg, StringRef Attr) | ||
| : ExprArgument(Arg, Attr), UndefValue(Arg.getValueAsInt("UndefValue")) { | ||
| } | ||
|
|
||
| void writeAccessors(raw_ostream &OS) const override { | ||
| OS << " " << getType() << " get" << getUpperName() << "() const {\n"; | ||
| OS << " return " << getLowerName() << ";\n"; | ||
| OS << " }\n"; | ||
| OS << "private:\n"; | ||
| OS << " int " << getLowerName() << "Value = " << UndefValue << ";\n"; | ||
| OS << "public:\n"; | ||
| OS << " int get" << getUpperName() << "Evaluated(ASTContext &Ctx) {\n"; | ||
| OS << " if (" << getLowerName() << "Value != " << UndefValue << ")\n"; | ||
| OS << " return " << getLowerName() << "Value;\n"; | ||
| OS << " llvm::APSInt Val(32);\n"; | ||
| OS << " bool Succeedded = " << getLowerName() | ||
| << "->isIntegerConstantExpr(Val, Ctx);\n"; | ||
| OS << " assert(Succeedded && \"expression must be constant " | ||
| "integer\");\n"; | ||
| OS << " " << getLowerName() << "Value = Val.getSExtValue();\n"; | ||
| OS << " return " << getLowerName() << "Value;\n"; | ||
| OS << " }"; | ||
| } | ||
| }; | ||
|
|
||
|
||
| class VariadicExprArgument : public VariadicArgument { | ||
| public: | ||
| VariadicExprArgument(const Record &Arg, StringRef Attr) | ||
|
|
@@ -1299,6 +1329,8 @@ createArgument(const Record &Arg, StringRef Attr, | |
| Ptr = std::make_unique<EnumArgument>(Arg, Attr); | ||
| else if (ArgName == "ExprArgument") | ||
| Ptr = std::make_unique<ExprArgument>(Arg, Attr); | ||
| else if (ArgName == "IntegerExprArgument") | ||
| Ptr = std::make_unique<IntegerExprArgument>(Arg, Attr); | ||
| else if (ArgName == "DeclArgument") | ||
| Ptr = std::make_unique<SimpleArgument>( | ||
| Arg, Attr, (Arg.getValueAsDef("Kind")->getName() + "Decl *").str()); | ||
|
|
||
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.
I've started thinking, that 'named' arguments, even if they are more readable, are actually not good. By naming arguments as faceless 'Value' we can unify handlers for many attributes. But I'm doing renaming in a patch for FPGA attributes, no need to bring it here.