-
Notifications
You must be signed in to change notification settings - Fork 768
Reenable "[ESIMD] Remove one of the uses on __SYCL_EXPLICIT_SIMD__ (#3242) #3311
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
Conversation
…__ (intel#3242)" This patch is a part of the efforts for allowing ESIMD and regular SYCL kernels to coexist in the same translation unit and in the same program. Previously, in ESIMD device code we had calls to SPIRV intrinsics that didn't have definitions. With the change in spirv_vars.hpp, SYCL optimization passes convert calls to SPIRV intrinsics into loads from globals (SPIRV builtins). Thus, there is a need to change the implementation of LowerESIMD pass to lower such new constructs. Example: // @__spirv_BuiltInGlobalInvocationId = external dso_local local_unnamed_addr addrspace(1) constant <3 x i64>, align 32 // ... // %0 = load <3 x i64>, <3 x i64> addrspace(4)* addrspacecast // (<3 x i64> addrspace(1)* @__spirv_BuiltInLocalInvocationId // to <3 x i64> addrspace(4)*), align 32 // %1 = extractelement <3 x i64> %0, i64 0 // // => // // %.esimd = call <3 x i32> @llvm.genx.local.id.v3i32() // %local_id.x = extractelement <3 x i32> %.esimd, i32 0 // %local_id.x.cast.ty = zext i32 %local_id.x to i64 Current tests in sycl/test/esimd/spirv_intrins_trans.cpp check that there is no regression in how we lower SPRIV intrinsics into GenX counterparts. But also, I added some more tests.
// this is ESIMD intrinsic - record for later translation | ||
ESIMDIntrCalls.push_back(CI); | ||
// Translate loads from SPIRV builtin globals into GenX intrinsics | ||
auto *LI = dyn_cast<LoadInst>(&I); |
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 think the following would be more efficient from compile-time and code simplicity perspective and slightly more reliable:
- iterating through M.global_begin()/M.global_end() and finding SPIRV globals among them
- iterating through each global's uses and applying the esimd translation t-form.
This can be considered a Nit. But please add a TODO if you decide not to implement.
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.
That's a good point. I agree to reimplement it, but I would prefer to do it in a separate patch if you don't mind. We talked about splitting the LowerESIMD pass into two: ModulePass and FunctionPass. I think it would be appropriate to do those two changes together.
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.
OK, sounds good
llvm/lib/SYCLLowerIR/LowerESIMD.cpp
Outdated
if (isa<GlobalVariable>(SpirvGlobal) && | ||
SpirvGlobal->getName().startswith(SPIRV_INTRIN_PREF)) { |
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.
if (isa<GlobalVariable>(SpirvGlobal) && | |
SpirvGlobal->getName().startswith(SPIRV_INTRIN_PREF)) { | |
if (!isa<GlobalVariable>(SpirvGlobal) || | |
!SpirvGlobal->getName().startswith(SPIRV_INTRIN_PREF)) | |
continue; |
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.
Ok. Will do.
llvm/lib/SYCLLowerIR/LowerESIMD.cpp
Outdated
Value *TranslatedVal = translateSpirvIntrinsic( | ||
EEI, SpirvGlobal->getName().drop_front(PrefLen)); | ||
|
||
if (TranslatedVal) { |
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.
should this be rather an assert(TranslatedVal)? Failure to translate a load from a SPIR-V intrinsic var seems like an error.
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.
Yes. Will change.
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.
Approving changes in spirv_vars.hpp
@@ -859,7 +859,7 @@ static Value *translateSpirvIntrinsic(ExtractElementInst *EEI, | |||
else if (IndexC->equalsInt(2)) | |||
Suff = 'z'; | |||
else | |||
return nullptr; | |||
assert(false && "Extract element index should be either 0, 1, or 2"); |
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.
Nit: llvm_unrecheable seems a better fit for the purpose
This patch is a part of the efforts for allowing ESIMD and
regular SYCL kernels to coexist in the same translation unit and
in the same program.
Previously, in ESIMD device code we had calls to SPIRV intrinsics
that didn't have definitions. With the change in spirv_vars.hpp,
SYCL optimization passes convert calls to SPIRV intrinsics into
loads from globals (SPIRV builtins). Thus, there is a need to change
the implementation of LowerESIMD pass to lower such new constructs.
Example:
Current tests in sycl/test/esimd/spirv_intrins_trans.cpp check that
there is no regression in how we lower SPRIV intrinsics into GenX
counterparts. But also, I added some more tests.