Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 16 additions & 2 deletions clang/lib/Basic/Targets/SPIR.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ static const unsigned SPIRDefIsPrivMap[] = {
0, // cuda_device
0, // cuda_constant
0, // cuda_shared
// SYCL address space values for this map are dummy
0, // sycl_global
// Most SYCL address space values for this map are dummy
Copy link
Contributor

Choose a reason for hiding this comment

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

Anyone know why this is the case?

Copy link
Member Author

Choose a reason for hiding this comment

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

Probably because for SYCL it doesn't use that map, it uses this one because of this logic.

Copy link
Contributor

Choose a reason for hiding this comment

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

This is a hack for OpenCL, and is not meant to work otherwise, it should only be used for OCL (looks like an unfortunate import from some brainrot we put in AMDGPU). We've made an effort to fix this recently, so perhaps we could look at moving SPIR-V away from it as well, see #112442 and its children.

Copy link
Member Author

@sarnex sarnex Apr 8, 2025

Choose a reason for hiding this comment

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

@AlexVlx Sorry do you mean the map with default AS as 0 should be OCL only and the one with default AS as 4 should be used otherwise even if temporary? If so I can update this PR to do that instead and deal with the fallout sooner rather than later.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, not only should it be OCL only, but it probably should only be OCL with no generic AS support only (please check out the PR I linked where we switched that over for AMDGPU). PrivateAsDefault was/is a bad hack. Note that you might want to fork the AS map switch into a different PR, as the fallout might end up a bit of a slog. E.g., this is still stuck in limbo #113930, and it will bite.

Copy link
Member Author

@sarnex sarnex Apr 8, 2025

Choose a reason for hiding this comment

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

Got it, so are you okay with this PR if I remove the part changing the default AS 0 map (and just have the constant global addrspace change)?

Copy link
Contributor

Choose a reason for hiding this comment

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

Oh, yes, apologies for the segue, this LGTM in general, thanks.

Copy link
Member Author

Choose a reason for hiding this comment

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

thanks for the review, should have a PR for the map fix shortly

1, // sycl_global
0, // sycl_global_device
0, // sycl_global_host
0, // sycl_local
Expand Down Expand Up @@ -374,6 +374,20 @@ class LLVM_LIBRARY_VISIBILITY SPIRV64TargetInfo : public BaseSPIRVTargetInfo {
const llvm::omp::GV &getGridValue() const override {
return llvm::omp::SPIRVGridValues;
}

std::optional<LangAS> getConstantAddressSpace() const override {
return ConstantAS;
}
void adjust(DiagnosticsEngine &Diags, LangOptions &Opts) override {
BaseSPIRVTargetInfo::adjust(Diags, Opts);
// opencl_constant will map to UniformConstant in SPIR-V
if (Opts.OpenCL)
ConstantAS = LangAS::opencl_constant;
}

private:
// opencl_global will map to CrossWorkgroup in SPIR-V
LangAS ConstantAS = LangAS::opencl_global;
};

class LLVM_LIBRARY_VISIBILITY SPIRV64AMDGCNTargetInfo final
Expand Down
4 changes: 2 additions & 2 deletions clang/test/CodeGenHLSL/GlobalDestructors.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,8 @@ void main(unsigned GI : SV_GroupIndex) {
// NOINLINE-SPIRV: define internal spir_func void @_GLOBAL__D_a() [[IntAttr:\#[0-9]+]]
// NOINLINE-SPIRV-NEXT: entry:
// NOINLINE-SPIRV-NEXT: %0 = call token @llvm.experimental.convergence.entry()
// NOINLINE-SPIRV-NEXT: call spir_func void @_ZN4TailD1Ev(ptr @_ZZ3WagvE1T) [ "convergencectrl"(token %0) ]
// NOINLINE-SPIRV-NEXT: call spir_func void @_ZN6PupperD1Ev(ptr @GlobalPup) [ "convergencectrl"(token %0) ]
// NOINLINE-SPIRV-NEXT: call spir_func void @_ZN4TailD1Ev(ptr addrspacecast (ptr addrspace(1) @_ZZ3WagvE1T to ptr)) [ "convergencectrl"(token %0) ]
// NOINLINE-SPIRV-NEXT: call spir_func void @_ZN6PupperD1Ev(ptr addrspacecast (ptr addrspace(1) @GlobalPup to ptr)) [ "convergencectrl"(token %0) ]
// NOINLINE-SPIRV-NEXT: ret void

// NOINLINE: attributes [[IntAttr]] = {{.*}} alwaysinline
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@ RasterizerOrderedStructuredBuffer<float> Buf5 : register(u1, space2);
// CHECK-SPIRV: %"class.hlsl::RWStructuredBuffer" = type { target("spirv.VulkanBuffer", [0 x float], 12, 1) }


// CHECK: @_ZL3Buf = internal global %"class.hlsl::StructuredBuffer" poison
// CHECK: @_ZL4Buf2 = internal global %"class.hlsl::RWStructuredBuffer" poison
// CHECK-SPIRV: @_ZL3Buf = internal addrspace(1) global %"class.hlsl::StructuredBuffer" poison
// CHECK-SPIRV: @_ZL4Buf2 = internal addrspace(1) global %"class.hlsl::RWStructuredBuffer" poison
// CHECK-DXIL: @_ZL3Buf = internal{{.*}}global %"class.hlsl::StructuredBuffer" poison
// CHECK-DXIL: @_ZL4Buf2 = internal{{.*}}global %"class.hlsl::RWStructuredBuffer" poison
// CHECK-DXIL: @_ZL4Buf3 = internal global %"class.hlsl::AppendStructuredBuffer" poison, align 4
// CHECK-DXIL: @_ZL4Buf4 = internal global %"class.hlsl::ConsumeStructuredBuffer" poison, align 4
// CHECK-DXIL: @_ZL4Buf5 = internal global %"class.hlsl::RasterizerOrderedStructuredBuffer" poison, align 4
Expand All @@ -32,13 +34,13 @@ RasterizerOrderedStructuredBuffer<float> Buf5 : register(u1, space2);
// CHECK-DXIL: [[H:%.*]] = call target("dx.RawBuffer", float, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_f32_0_0t(i32 0, i32 10, i32 1, i32 0, i1 false)
// CHECK-DXIL: store target("dx.RawBuffer", float, 0, 0) [[H]], ptr @_ZL3Buf, align 4
// CHECK-SPIRV: [[H:%.*]] = call target("spirv.VulkanBuffer", [0 x float], 12, 0) @llvm.spv.resource.handlefrombinding.tspirv.VulkanBuffer_a0f32_12_0t(i32 0, i32 10, i32 1, i32 0, i1 false)
// CHECK-SPIRV: store target("spirv.VulkanBuffer", [0 x float], 12, 0) [[H]], ptr @_ZL3Buf, align 8
// CHECK-SPIRV: store target("spirv.VulkanBuffer", [0 x float], 12, 0) [[H]], ptr addrspace(1) @_ZL3Buf, align 8

// CHECK: define internal void @_init_resource__ZL4Buf2()
// CHECK-DXIL: [[H:%.*]] = call target("dx.RawBuffer", float, 1, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_f32_1_0t(i32 1, i32 5, i32 1, i32 0, i1 false)
// CHECK-DXIL: store target("dx.RawBuffer", float, 1, 0) [[H]], ptr @_ZL4Buf2, align 4
// CHECK-SPIRV: [[H:%.*]] = call target("spirv.VulkanBuffer", [0 x float], 12, 1) @llvm.spv.resource.handlefrombinding.tspirv.VulkanBuffer_a0f32_12_1t(i32 1, i32 5, i32 1, i32 0, i1 false)
// CHECK-SPIRV: store target("spirv.VulkanBuffer", [0 x float], 12, 1) [[H]], ptr @_ZL4Buf2, align 8
// CHECK-SPIRV: store target("spirv.VulkanBuffer", [0 x float], 12, 1) [[H]], ptr addrspace(1) @_ZL4Buf2, align 8

// CHECK-DXIL: define internal void @_init_resource__ZL4Buf3()
// CHECK-DXIL: [[H:%.*]] = call target("dx.RawBuffer", float, 1, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_f32_1_0t(i32 0, i32 3, i32 1, i32 0, i1 false)
Expand Down
20 changes: 20 additions & 0 deletions clang/test/OpenMP/spirv_target_addrspace.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-unknown-unknown -fopenmp-targets=spirv64 -emit-llvm-bc %s -o %t-host.bc
// RUN: %clang_cc1 -O0 -fopenmp -fopenmp-targets=spirv64 -fopenmp-is-target-device -triple spirv64 -fopenmp-host-ir-file-path %t-host.bc -emit-llvm %s -o - | FileCheck %s

extern int printf(char[]);

#pragma omp declare target
// CHECK: @global = addrspace(1) global i32 0, align 4
// CHECK: @.str = private unnamed_addr addrspace(1) constant [4 x i8] c"foo\00", align 1
int global = 0;
#pragma omp end declare target
int main() {
// CHECK: = call i32 @__kmpc_target_init(ptr addrspacecast (ptr addrspace(1) @__omp_offloading_{{.*}}_kernel_environment to ptr), ptr %{{.*}})
#pragma omp target
{
for(int i = 0; i < 5; i++)
global++;
printf("foo");
}
return global;
}
6 changes: 6 additions & 0 deletions llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6295,6 +6295,12 @@ OpenMPIRBuilder::InsertPointTy OpenMPIRBuilder::createTargetInit(
: ConstantExpr::getAddrSpaceCast(KernelEnvironmentGV,
KernelEnvironmentPtr);
Value *KernelLaunchEnvironment = DebugKernelWrapper->getArg(0);
Type *KernelLaunchEnvParamTy = Fn->getFunctionType()->getParamType(1);
KernelLaunchEnvironment =
KernelLaunchEnvironment->getType() == KernelLaunchEnvParamTy
? KernelLaunchEnvironment
: Builder.CreateAddrSpaceCast(KernelLaunchEnvironment,
KernelLaunchEnvParamTy);
CallInst *ThreadKind =
Builder.CreateCall(Fn, {KernelEnvironment, KernelLaunchEnvironment});

Expand Down