diff --git a/clang/lib/CodeGen/Targets/SPIR.cpp b/clang/lib/CodeGen/Targets/SPIR.cpp index abd049aca0ed7..161a944b16bda 100644 --- a/clang/lib/CodeGen/Targets/SPIR.cpp +++ b/clang/lib/CodeGen/Targets/SPIR.cpp @@ -260,8 +260,16 @@ CommonSPIRTargetCodeGenInfo::getNullPointer(const CodeGen::CodeGenModule &CGM, LangAS AS = QT->getUnqualifiedDesugaredType()->isNullPtrType() ? LangAS::Default : QT->getPointeeType().getAddressSpace(); + unsigned ASAsInt = static_cast(AS); + unsigned FirstTargetASAsInt = + static_cast(LangAS::FirstTargetAddressSpace); + unsigned CodeSectionINTELAS = FirstTargetASAsInt + 9; + // As per SPV_INTEL_function_pointers, it is illegal to addrspacecast + // function pointers to/from the generic AS. + bool IsFunctionPtrAS = + CGM.getTriple().isSPIRV() && ASAsInt == CodeSectionINTELAS; if (AS == LangAS::Default || AS == LangAS::opencl_generic || - AS == LangAS::opencl_constant) + AS == LangAS::opencl_constant || IsFunctionPtrAS) return llvm::ConstantPointerNull::get(PT); auto &Ctx = CGM.getContext(); diff --git a/clang/test/CodeGenSPIRV/spirv-intel.c b/clang/test/CodeGenSPIRV/spirv-intel.c index 997cd6f10b90c..f00fc97adaec7 100644 --- a/clang/test/CodeGenSPIRV/spirv-intel.c +++ b/clang/test/CodeGenSPIRV/spirv-intel.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -triple spirv64-intel %s -emit-llvm -o - | FileCheck -check-prefix=CHECK-WITH-64 %s -// RUN: %clang_cc1 -triple spirv32-intel %s -emit-llvm -o - | FileCheck -check-prefix=CHECK-WITH-32 %s +// RUN: %clang_cc1 -triple spirv64-intel %s -emit-llvm -o - | FileCheck -check-prefixes=CHECK-WITH,CHECK-WITH-64 %s +// RUN: %clang_cc1 -triple spirv32-intel %s -emit-llvm -o - | FileCheck -check-prefixes=CHECK-WITH,CHECK-WITH-32 %s // RUN: %clang_cc1 -triple spir-intel %s -emit-llvm -o - | FileCheck -check-prefix=CHECK-WITHOUT %s // RUN: %clang_cc1 -triple spir64-intel %s -emit-llvm -o - | FileCheck -check-prefix=CHECK-WITHOUT %s @@ -9,3 +9,11 @@ // CHECK-WITHOUT: spir_func void @foo(ptr noundef %param) #0 { void foo(int *param) { } + +typedef __attribute__((address_space(9))) void * FnPtrTy; + +// CHECK-WITH: %{{.*}} = icmp eq ptr addrspace(9) %{{.*}}, null +int bar() { + FnPtrTy FnPtr = (FnPtrTy)foo; + return FnPtr == 0; +}