[clang] 4eaf584 - [clang] Fix function pointer address space
Elizabeth Andrews via cfe-commits
cfe-commits at lists.llvm.org
Thu Jan 13 08:12:28 PST 2022
Author: Elizabeth Andrews
Date: 2022-01-13T08:06:19-08:00
New Revision: 4eaf5846d0e738264d9328b4a919bc352ea83b7a
URL: https://github.com/llvm/llvm-project/commit/4eaf5846d0e738264d9328b4a919bc352ea83b7a
DIFF: https://github.com/llvm/llvm-project/commit/4eaf5846d0e738264d9328b4a919bc352ea83b7a.diff
LOG: [clang] Fix function pointer address space
Functions pointers should be created with program address space. This
patch introduces program address space in TargetInfo. Targets with
non-default (default is 0) address space for functions should explicitly
set this value. This patch fixes a crash on lvalue reference to function
pointer (in device code) when using oneAPI DPC++ compiler.
Differential Revision: https://reviews.llvm.org/D111566
Added:
clang/test/CodeGen/avr/functionptr-addrspace.c
clang/test/CodeGenSYCL/functionptr-addrspace.cpp
Modified:
clang/include/clang/AST/ASTContext.h
clang/include/clang/Basic/TargetInfo.h
clang/lib/AST/ASTContext.cpp
clang/lib/Basic/TargetInfo.cpp
clang/lib/Basic/Targets/AVR.h
clang/lib/CodeGen/CodeGenTypes.cpp
Removed:
################################################################################
diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h
index 7a9e3a643d6f4..c5946b662cb29 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -2727,13 +2727,9 @@ class ASTContext : public RefCountedBase<ASTContext> {
QualType getFloatingTypeOfSizeWithinDomain(QualType typeSize,
QualType typeDomain) const;
- unsigned getTargetAddressSpace(QualType T) const {
- return getTargetAddressSpace(T.getQualifiers());
- }
+ unsigned getTargetAddressSpace(QualType T) const;
- unsigned getTargetAddressSpace(Qualifiers Q) const {
- return getTargetAddressSpace(Q.getAddressSpace());
- }
+ unsigned getTargetAddressSpace(Qualifiers Q) const;
unsigned getTargetAddressSpace(LangAS AS) const;
diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h
index 46eb190333aa2..686a365b8c12d 100644
--- a/clang/include/clang/Basic/TargetInfo.h
+++ b/clang/include/clang/Basic/TargetInfo.h
@@ -212,6 +212,7 @@ class TargetInfo : public virtual TransferrableTargetInfo,
unsigned char RegParmMax, SSERegParmMax;
TargetCXXABI TheCXXABI;
const LangASMap *AddrSpaceMap;
+ unsigned ProgramAddrSpace;
mutable StringRef PlatformName;
mutable VersionTuple PlatformMinVersion;
@@ -767,6 +768,9 @@ class TargetInfo : public virtual TransferrableTargetInfo,
return getTypeWidth(IntMaxType);
}
+ /// Return the address space for functions for the given target.
+ unsigned getProgramAddressSpace() const { return ProgramAddrSpace; }
+
// Return the size of unwind_word for this target.
virtual unsigned getUnwindWordWidth() const { return getPointerWidth(0); }
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 6f3c0dc14867a..9d63724c919a0 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -11575,6 +11575,15 @@ uint64_t ASTContext::getTargetNullPointerValue(QualType QT) const {
return getTargetInfo().getNullPointerValue(AS);
}
+unsigned ASTContext::getTargetAddressSpace(QualType T) const {
+ return T->isFunctionType() ? getTargetInfo().getProgramAddressSpace()
+ : getTargetAddressSpace(T.getQualifiers());
+}
+
+unsigned ASTContext::getTargetAddressSpace(Qualifiers Q) const {
+ return getTargetAddressSpace(Q.getAddressSpace());
+}
+
unsigned ASTContext::getTargetAddressSpace(LangAS AS) const {
if (isTargetAddressSpace(AS))
return toTargetAddressSpace(AS);
diff --git a/clang/lib/Basic/TargetInfo.cpp b/clang/lib/Basic/TargetInfo.cpp
index ddb20008bc9da..4fd31647bab24 100644
--- a/clang/lib/Basic/TargetInfo.cpp
+++ b/clang/lib/Basic/TargetInfo.cpp
@@ -150,6 +150,7 @@ TargetInfo::TargetInfo(const llvm::Triple &T) : Triple(T) {
PlatformMinVersion = VersionTuple();
MaxOpenCLWorkGroupSize = 1024;
+ ProgramAddrSpace = 0;
}
// Out of line virtual dtor for TargetInfo.
diff --git a/clang/lib/Basic/Targets/AVR.h b/clang/lib/Basic/Targets/AVR.h
index 89a80ca6a39a3..a281e2c2cd744 100644
--- a/clang/lib/Basic/Targets/AVR.h
+++ b/clang/lib/Basic/Targets/AVR.h
@@ -55,6 +55,7 @@ class LLVM_LIBRARY_VISIBILITY AVRTargetInfo : public TargetInfo {
Int16Type = SignedInt;
Char32Type = UnsignedLong;
SigAtomicType = SignedChar;
+ ProgramAddrSpace = 1;
resetDataLayout("e-P1-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8-a:8");
}
diff --git a/clang/lib/CodeGen/CodeGenTypes.cpp b/clang/lib/CodeGen/CodeGenTypes.cpp
index 77721510dfd0f..4839e22c4b144 100644
--- a/clang/lib/CodeGen/CodeGenTypes.cpp
+++ b/clang/lib/CodeGen/CodeGenTypes.cpp
@@ -643,11 +643,7 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) {
llvm::Type *PointeeType = ConvertTypeForMem(ETy);
if (PointeeType->isVoidTy())
PointeeType = llvm::Type::getInt8Ty(getLLVMContext());
-
- unsigned AS = PointeeType->isFunctionTy()
- ? getDataLayout().getProgramAddressSpace()
- : Context.getTargetAddressSpace(ETy);
-
+ unsigned AS = Context.getTargetAddressSpace(ETy);
ResultType = llvm::PointerType::get(PointeeType, AS);
break;
}
@@ -748,7 +744,13 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) {
llvm::Type *PointeeType = CGM.getLangOpts().OpenCL
? CGM.getGenericBlockLiteralType()
: ConvertTypeForMem(FTy);
- unsigned AS = Context.getTargetAddressSpace(FTy);
+ // Block pointers lower to function type. For function type,
+ // getTargetAddressSpace() returns default address space for
+ // function pointer i.e. program address space. Therefore, for block
+ // pointers, it is important to pass qualifiers when calling
+ // getTargetAddressSpace(), to ensure that we get the address space
+ // for data pointers and not function pointers.
+ unsigned AS = Context.getTargetAddressSpace(FTy.getQualifiers());
ResultType = llvm::PointerType::get(PointeeType, AS);
break;
}
diff --git a/clang/test/CodeGen/avr/functionptr-addrspace.c b/clang/test/CodeGen/avr/functionptr-addrspace.c
new file mode 100644
index 0000000000000..90ec121319074
--- /dev/null
+++ b/clang/test/CodeGen/avr/functionptr-addrspace.c
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -triple avr -emit-llvm %s -o - | FileCheck %s
+
+int main() {
+ int (*p)();
+ return 0;
+}
+
+// CHECK: %p = alloca i16 (...) addrspace(1)*
diff --git a/clang/test/CodeGenSYCL/functionptr-addrspace.cpp b/clang/test/CodeGenSYCL/functionptr-addrspace.cpp
new file mode 100644
index 0000000000000..26b7c3340ac37
--- /dev/null
+++ b/clang/test/CodeGenSYCL/functionptr-addrspace.cpp
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -fsycl-is-device -emit-llvm -triple spir64 -verify -emit-llvm %s -o - | FileCheck %s
+
+// expected-no-diagnostics
+
+template <typename Name, typename Func>
+__attribute__((sycl_kernel)) void kernel_single_task(const Func &kernelFunc) {
+ kernelFunc();
+}
+
+// CHECK: define dso_local spir_func{{.*}}invoke_function{{.*}}(i32 ()* %fptr, i32 addrspace(4)* %ptr)
+void invoke_function(int (*fptr)(), int *ptr) {}
+
+int f() { return 0; }
+
+int main() {
+ kernel_single_task<class fake_kernel>([=]() {
+ int (*p)() = f;
+ int (&r)() = *p;
+ int a = 10;
+ invoke_function(p, &a);
+ invoke_function(r, &a);
+ invoke_function(f, &a);
+ });
+ return 0;
+}
More information about the cfe-commits
mailing list