================
@@ -70,43 +70,89 @@ bool Qualifiers::isStrictSupersetOf(Qualifiers Other) const
{
(hasObjCLifetime() && !Other.hasObjCLifetime()));
}
+// When targeting the OpenCL execution environment, corresponding SYCL and
+// OpenCL address spaces designate the same underlying address space and are
+// mutually convertible.
+static bool isConvertibleOpenCLSYCLAddressSpace(LangAS A, LangAS B) {
+ return (A == LangAS::sycl_global && B == LangAS::opencl_global) ||
+ (A == LangAS::opencl_global && B == LangAS::sycl_global) ||
+ (A == LangAS::sycl_global_device &&
+ B == LangAS::opencl_global_device) ||
+ (A == LangAS::opencl_global_device &&
+ B == LangAS::sycl_global_device) ||
+ (A == LangAS::sycl_global_host && B == LangAS::opencl_global_host) ||
+ (A == LangAS::opencl_global_host && B == LangAS::sycl_global_host) ||
+ (A == LangAS::sycl_local && B == LangAS::opencl_local) ||
+ (A == LangAS::opencl_local && B == LangAS::sycl_local) ||
+ (A == LangAS::sycl_private && B == LangAS::opencl_private) ||
+ (A == LangAS::opencl_private && B == LangAS::sycl_private) ||
+ (A == LangAS::sycl_generic && B == LangAS::opencl_generic) ||
+ (A == LangAS::opencl_generic && B == LangAS::sycl_generic) ||
+ (A == LangAS::sycl_constant && B == LangAS::opencl_constant) ||
+ (A == LangAS::opencl_constant && B == LangAS::sycl_constant);
+}
+
bool Qualifiers::isTargetAddressSpaceSupersetOf(LangAS A, LangAS B,
const ASTContext &Ctx) {
- // In OpenCLC v2.0 s6.5.5: every address space except for __constant can be
+ const bool IsOpenCLExecEnv =
+ Ctx.getTargetInfo().getTriple().getOS() == llvm::Triple::OpenCL;
+
+ // In OpenCL C v2.0 s6.5.5: every address space except for __constant can be
// used as __generic.
- return (A == LangAS::opencl_generic && B != LangAS::opencl_constant) ||
- // We also define global_device and global_host address spaces,
- // to distinguish global pointers allocated on host from pointers
- // allocated on device, which are a subset of __global.
- (A == LangAS::opencl_global && (B == LangAS::opencl_global_device ||
- B == LangAS::opencl_global_host)) ||
- (A == LangAS::sycl_global &&
- (B == LangAS::sycl_global_device || B == LangAS::sycl_global_host))
||
- // Consider pointer size address spaces to be equivalent to default.
- ((isPtrSizeAddressSpace(A) || A == LangAS::Default) &&
- (isPtrSizeAddressSpace(B) || B == LangAS::Default)) ||
- // Default is a superset of SYCL address spaces.
- (A == LangAS::Default &&
- (B == LangAS::sycl_private || B == LangAS::sycl_local ||
- B == LangAS::sycl_global || B == LangAS::sycl_global_device ||
- B == LangAS::sycl_global_host)) ||
- // In HIP device compilation, any cuda address space is allowed
- // to implicitly cast into the default address space.
- (A == LangAS::Default &&
- (B == LangAS::cuda_constant || B == LangAS::cuda_device ||
- B == LangAS::cuda_shared)) ||
- // In HLSL, the this pointer for member functions points to the
default
- // address space. This causes a problem if the structure is in
- // a different address space. We want to allow casting from these
- // address spaces to default to work around this problem.
- (A == LangAS::Default && B == LangAS::hlsl_private) ||
- (A == LangAS::Default && B == LangAS::hlsl_device) ||
- (A == LangAS::Default && B == LangAS::hlsl_input) ||
- (A == LangAS::Default && B == LangAS::hlsl_output) ||
- (A == LangAS::Default && B == LangAS::hlsl_push_constant) ||
- // Conversions from target specific address spaces may be legal
- // depending on the target information.
- Ctx.getTargetInfo().isAddressSpaceSupersetOf(A, B);
+ if ((Ctx.getLangOpts().OpenCL || IsOpenCLExecEnv) &&
+ A == LangAS::opencl_generic && B != LangAS::opencl_constant)
+ return true;
+
+ // __global is a superset of the global_device and global_host address
+ // spaces, which distinguish global pointers allocated on the host from those
+ // allocated on the device.
+ if (A == LangAS::opencl_global &&
+ (B == LangAS::opencl_global_device || B == LangAS::opencl_global_host))
+ return true;
+ if (A == LangAS::sycl_global &&
+ (B == LangAS::sycl_global_device || B == LangAS::sycl_global_host))
+ return true;
+
+ // Pointer size address spaces are equivalent to the default address space.
+ if ((isPtrSizeAddressSpace(A) || A == LangAS::Default) &&
+ (isPtrSizeAddressSpace(B) || B == LangAS::Default))
+ return true;
+
+ // Default and sycl_generic are supersets of the SYCL address spaces.
+ if ((A == LangAS::Default || A == LangAS::sycl_generic) &&
+ (B == LangAS::sycl_private || B == LangAS::sycl_local ||
+ B == LangAS::sycl_global || B == LangAS::sycl_global_device ||
+ B == LangAS::sycl_global_host))
----------------
tahonermann wrote:
This can be written similarly to the checks for OpenCL above.
```suggestion
if ((A == LangAS::Default || A == LangAS::sycl_generic) && B !=
LangAS::Constant)
```
If you use the `getMemoryRegion()` suggestion from one of my other comments
with `LangAS::Default` mapped to `Generic`, then I think this can be distilled
to the following (perhaps with a SYCL check).
```suggestion
if (getMemoryRegion(A) == MemoryRegion::Generic && getMemoryRegion(B) !=
LangAS::Constant)
```
Your rewrite is a major improvement over the previous code! Thank you! :)
https://github.com/llvm/llvm-project/pull/200849
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits