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

SPV_KHR_untyped_pointers - implement OpUntypedPrefetchKHR #2752

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

vmaksimo
Copy link
Contributor

When the extension is enabled, we should replace prefetch OpenCL ExtInst with the OpUntypedPrefetchKHR instruction.

Spec:
https://htmlpreview.github.io/?https://github.com/KhronosGroup/SPIRV-Registry/blob/main/extensions/KHR/SPV_KHR_untyped_pointers.html

When the extension is enabled, we should replace `prefetch` OpenCL ExtInst with the `OpUntypedPrefetchKHR` instruction.

Spec:
https://htmlpreview.github.io/?https://github.com/KhronosGroup/SPIRV-Registry/blob/main/extensions/KHR/SPV_KHR_untyped_pointers.html

void validate() const override {
SPIRVInstruction::validate();
assert(getValueType(PtrTy)->isTypePointer());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lets use

 SPIRVErrorLog &SPVErrLog = this->getModule()->getErrorLog();
 SPVErrLog.checkError(....


void setWordCount(SPIRVWord TheWordCount) override {
SPIRVEntry::setWordCount(TheWordCount);
if (TheWordCount > 3)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I might be missing something, but why do we need these checks?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the way to handle optional arguments that is used through the translator's codebase. For the current test case without optional parameters these checks are not used, but need to verify if they are in case we have optional operands.

Type *RetTy = Type::getVoidTy(*Context);

std::string MangledName =
getSPIRVFriendlyIRFunctionName(OpenCLLIB::Prefetch, ArgTypes, RetTy);
Copy link
Contributor

@MrSidims MrSidims Oct 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I started to remember (missed it in our chat). We need to map the instruction to llvm.prefetch intrinsic. So probably the logic should be:

  1. if RW, locality and cache type optional parameters are set, then map the instruction to llvm.prefetch;
  2. else if some of the optional parameters present, then we should emit SPIR-V friendly LLVM IR call (btw, @alan-baker I believe some routine lines should be added to the spec like: "if Cache Type present, then other optional parameters must be set");
  3. if no optional parameters are set - map it to OpenCL prefetch call.

Note, No.2 is discussible, we may want to still emit llvm intrinsic but with some default values set. In the case No.2 RW will always be set, which is good as we won't need to guess a default value, locality can be defaulted to '0'. Not sure though what to use for Cache Type, '1' seems reasonable to me. Would be nice to hear from @alan-baker @bashbaug and @svenvh about that.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could add that restriction in the future if that is the only practical use case. I left it vague because I am not familiar with generating the equivalent LLVM intrinsic.

As for defaults I simply tried to provide the same arguments as the LLVM intrinsics, though I can't imagine how instruction cache fetching could be done via OpenCL C. So for Cache Type I'd expect it's always safe to default to data.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

About p.1, I'm not sure we should use llvm.prefetch intrinsic for now because it does not contain the number of bytes to prefetch field.
The similar concern is for forward translation. Although llvm.prefetch contains RW, Locality and Cache Type fields, it does not have a number of bytes to prefetch, which is a mandatory field in OpUntypedPrefetchKHR instruction.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it does not contain the number of bytes to prefetch field

Indeed. Probably it can go to another PR, but we can add the following logic:

  1. (as before) if no optional parameters are set - map it to OpenCL prefetch call;
  2. if one of the optional parameters (RW, locality or cache type) optional parameters is set and number of bytes = 64, then map it on llvm.prefetch (on x86-64 prefetch would prefetch 64 bytes, other magic number is also possible);
  3. if optional parameter present and number of bytes != 64 - leave it as SPIR-V friendly call.

@@ -5329,6 +5329,12 @@ SPIRVValue *LLVMToSPIRVBase::transDirectCallInst(CallInst *CI,
BM->addExtension(
ExtensionID::SPV_EXT_relaxed_printf_string_address_space);
}
} else if (DemangledName.find("__spirv_ocl_prefetch") != StringRef::npos) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please also add translation from prefetch llvm intrinsic.

Copy link
Contributor

@MrSidims MrSidims left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feel free to address llvm.prefetch later/create a tracker.
I'd also like to hear from @svenvh if he approves the PR

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.

4 participants