akhuang created this revision.
akhuang added reviewers: rnk, rsmith.
Herald added subscribers: llvm-commits, cfe-commits, erik.pilkington,
hiraditya, nhaehnle, jvesely, jholewinski.
Herald added projects: clang, LLVM.
Previously, these qualifiers were being parsed but otherwise ignored.
This change makes it so that an address space is added to specify whether the
pointer is
32-bit or 64-bit and whether it is sign extended or zero extended.
In the backend, the address space casts are lowered to the corresponding
sign/zero extension or truncation.
The data layout for the address spaces was changed in
https://reviews.llvm.org/D64931
Related to https://bugs.llvm.org/show_bug.cgi?id=42359
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D66827
Files:
clang/include/clang/AST/Type.h
clang/include/clang/Basic/AddressSpaces.h
clang/lib/AST/ASTContext.cpp
clang/lib/AST/ItaniumMangle.cpp
clang/lib/AST/MicrosoftMangle.cpp
clang/lib/AST/TypePrinter.cpp
clang/lib/Basic/Targets/AMDGPU.cpp
clang/lib/Basic/Targets/NVPTX.h
clang/lib/Basic/Targets/SPIR.h
clang/lib/Basic/Targets/TCE.h
clang/lib/Basic/Targets/X86.h
clang/lib/Sema/SemaOverload.cpp
clang/lib/Sema/SemaType.cpp
llvm/lib/Target/X86/X86.h
llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
llvm/lib/Target/X86/X86ISelLowering.cpp
llvm/test/CodeGen/X86/mixed-ptr-sizes.ll
Index: llvm/test/CodeGen/X86/mixed-ptr-sizes.ll
===================================================================
--- /dev/null
+++ llvm/test/CodeGen/X86/mixed-ptr-sizes.ll
@@ -0,0 +1,108 @@
+; RUN: llc < %s | FileCheck --check-prefixes=CHECK %s
+
+; Source to regenerate:
+; struct Foo {
+; int * __ptr32 p32;
+; int * __ptr64 p64;
+; }
+; void use_foo(Foo *f);
+; void test_sign_ext(Foo *f, int * __ptr32 __sptr i) {
+; f->p64 = i;
+; use_foo(f);
+; }
+; void test_zero_ext(Foo *f, int * __ptr32 __uptr i) {
+; f->p64 = i;
+; use_foo(f);
+; }
+; void test_trunc(foo *f, int * __ptr64 i) {
+; f->p32 = i;
+; use_foo(f);
+; }
+; void test_noop1(foo *f, int * __ptr32 i) {
+; f->p32 = i;
+; use_foo(f);
+; }
+; void test_noop2(foo *f, int * __ptr64 i) {
+; f->p64 = i;
+; use_foo(f);
+; }
+;
+; $ clang -cc1 -triple x86_64-windows-msvc -fms-extensions -O2 -S t.cpp
+
+; ModuleID = 't.cpp'
+source_filename = "t.cpp"
+target datalayout = "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-windows-msvc"
+
+%struct.Foo = type { i32 addrspace(270)*, i32* }
+declare dso_local void @"?use_foo@@YAXPEAUFoo@@@Z"(%struct.Foo*) local_unnamed_addr #1
+
+; Function Attrs: nounwind
+define dso_local void @"?test_sign_ext@@YAXPEAUFoo@@PEAU?$_ASPtr32_sptr@$$CAH@__clang@@@Z"(%struct.Foo* %f, i32 addrspace(270)* %i) local_unnamed_addr #0 {
+; CHECK-LABEL: {{.*}}test_sign_ext{{.*}}
+; CHECK: movslq %edx, %rax
+entry:
+ %0 = addrspacecast i32 addrspace(270)* %i to i32*
+ %p64 = getelementptr inbounds %struct.Foo, %struct.Foo* %f, i64 0, i32 1
+ store i32* %0, i32** %p64, align 8, !tbaa !2
+ tail call void @"?use_foo@@YAXPEAUFoo@@@Z"(%struct.Foo* %f) #2
+ ret void
+}
+
+; Function Attrs: nounwind
+define dso_local void @"?test_zero_ext@@YAXPEAUFoo@@PEAU?$_ASPtr32_uptr@$$CAH@__clang@@@Z"(%struct.Foo* %f, i32 addrspace(271)* %i) local_unnamed_addr #0 {
+; CHECK-LABEL: {{.*}}test_zero_ext{{.*}}
+; CHECK: movl %edx, %eax
+entry:
+ %0 = addrspacecast i32 addrspace(271)* %i to i32*
+ %p64 = getelementptr inbounds %struct.Foo, %struct.Foo* %f, i64 0, i32 1
+ store i32* %0, i32** %p64, align 8, !tbaa !2
+ tail call void @"?use_foo@@YAXPEAUFoo@@@Z"(%struct.Foo* %f) #2
+ ret void
+}
+
+; Function Attrs: nounwind
+define dso_local void @"?test_trunc@@YAXPEAUFoo@@PEAH@Z"(%struct.Foo* %f, i32* %i) local_unnamed_addr #0 {
+; CHECK-LABEL: {{.*}}test_trunc{{.*}}
+; CHECK: movl %edx, (%rcx)
+entry:
+ %0 = addrspacecast i32* %i to i32 addrspace(270)*
+ %p32 = getelementptr inbounds %struct.Foo, %struct.Foo* %f, i64 0, i32 0
+ store i32 addrspace(270)* %0, i32 addrspace(270)** %p32, align 8, !tbaa !7
+ tail call void @"?use_foo@@YAXPEAUFoo@@@Z"(%struct.Foo* %f) #2
+ ret void
+}
+
+; Function Attrs: nounwind
+define dso_local void @"?test_noop1@@YAXPEAUFoo@@PEAU?$_ASPtr32_sptr@$$CAH@__clang@@@Z"(%struct.Foo* %f, i32 addrspace(270)* %i) local_unnamed_addr #0 {
+; CHECK-LABEL: {{.*}}test_noop1{{.*}}
+; CHECK: movl %edx, (%rcx)
+entry:
+ %p32 = getelementptr inbounds %struct.Foo, %struct.Foo* %f, i64 0, i32 0
+ store i32 addrspace(270)* %i, i32 addrspace(270)** %p32, align 8, !tbaa !7
+ tail call void @"?use_foo@@YAXPEAUFoo@@@Z"(%struct.Foo* %f) #2
+ ret void
+}
+
+; Function Attrs: nounwind
+define dso_local void @"?test_noop2@@YAXPEAUFoo@@PEAH@Z"(%struct.Foo* %f, i32* %i) local_unnamed_addr #0 {
+; CHECK-LABEL: {{.*}}test_noop2{{.*}}
+; CHECK: movq %rdx, 8(%rcx)
+entry:
+ %p64 = getelementptr inbounds %struct.Foo, %struct.Foo* %f, i64 0, i32 1
+ store i32* %i, i32** %p64, align 8, !tbaa !2
+ tail call void @"?use_foo@@YAXPEAUFoo@@@Z"(%struct.Foo* %f) #2
+ ret void
+}
+
+!llvm.module.flags = !{!0}
+!llvm.ident = !{!1}
+
+!0 = !{i32 1, !"wchar_size", i32 2}
+!1 = !{!"clang version 10.0.0 (https://github.com/llvm/llvm-project.git e7b4a1629519fc9910b49e59ea4b13040631b2b5)"}
+!2 = !{!3, !4, i64 8}
+!3 = !{!"?AUFoo@@", !4, i64 0, !4, i64 8}
+!4 = !{!"any pointer", !5, i64 0}
+!5 = !{!"omnipotent char", !6, i64 0}
+!6 = !{!"Simple C++ TBAA"}
+!7 = !{!3, !4, i64 0}
Index: llvm/lib/Target/X86/X86ISelLowering.cpp
===================================================================
--- llvm/lib/Target/X86/X86ISelLowering.cpp
+++ llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -277,6 +277,10 @@
setOperationAction(ISD::FP_TO_UINT , MVT::i8 , Promote);
setOperationAction(ISD::FP_TO_UINT , MVT::i16 , Promote);
+ // Handle address space casts between mixed sized pointers.
+ setOperationAction(ISD::ADDRSPACECAST, MVT::i32, Custom);
+ setOperationAction(ISD::ADDRSPACECAST, MVT::i64, Custom);
+
if (Subtarget.is64Bit()) {
if (!Subtarget.useSoftFloat() && Subtarget.hasAVX512()) {
// FP_TO_UINT-i32/i64 is legal for f32/f64, but custom for f80.
@@ -2353,10 +2357,21 @@
return TargetLowering::getSafeStackPointerLocation(IRB);
}
+static bool isPtrSizeOrDefaultAddrSpace(unsigned AS) {
+ return (AS == 0 || AS == X86AS::PTR32_SPTR || AS == X86AS::PTR32_UPTR ||
+ AS == X86AS::PTR64);
+}
+
bool X86TargetLowering::isNoopAddrSpaceCast(unsigned SrcAS,
unsigned DestAS) const {
assert(SrcAS != DestAS && "Expected different address spaces!");
+ const TargetMachine &TM = getTargetMachine();
+ if ((isPtrSizeOrDefaultAddrSpace(SrcAS) &&
+ isPtrSizeOrDefaultAddrSpace(DestAS)) &&
+ TM.getPointerSize(SrcAS) != TM.getPointerSize(DestAS))
+ return false;
+
return SrcAS < 256 && DestAS < 256;
}
@@ -27397,6 +27412,33 @@
return DAG.getMergeValues({Extract, NewGather.getValue(2)}, dl);
}
+static SDValue LowerADDRSPACECAST(SDValue Op, SelectionDAG &DAG) {
+ SDLoc dl(Op);
+ SDValue Src = Op.getOperand(0);
+ MVT DstVT = Op.getSimpleValueType();
+
+ AddrSpaceCastSDNode *N = cast<AddrSpaceCastSDNode>(Op.getNode());
+ unsigned SrcAS = N->getSrcAddressSpace();
+ unsigned DstAS = N->getDestAddressSpace();
+
+ assert(SrcAS != DstAS &&
+ "addrspacecast must be between different address spaces");
+
+ if (isPtrSizeOrDefaultAddrSpace(SrcAS) &&
+ isPtrSizeOrDefaultAddrSpace(DstAS)) {
+ if (SrcAS == X86AS::PTR32_UPTR && DstVT == MVT::i64) {
+ Op = DAG.getNode(ISD::ZERO_EXTEND, dl, DstVT, Src);
+ } else if (DstVT == MVT::i64) {
+ Op = DAG.getNode(ISD::SIGN_EXTEND, dl, DstVT, Src);
+ } else if (DstVT == MVT::i32) {
+ Op = DAG.getNode(ISD::TRUNCATE, dl, DstVT, Src);
+ }
+ } else {
+ report_fatal_error("Bad address space in addrspacecast");
+ }
+ return Op;
+}
+
SDValue X86TargetLowering::LowerGC_TRANSITION_START(SDValue Op,
SelectionDAG &DAG) const {
// TODO: Eventually, the lowering of these nodes should be informed by or
@@ -27559,6 +27601,8 @@
case ISD::GC_TRANSITION_START:
return LowerGC_TRANSITION_START(Op, DAG);
case ISD::GC_TRANSITION_END: return LowerGC_TRANSITION_END(Op, DAG);
+ case ISD::ADDRSPACECAST:
+ return LowerADDRSPACECAST(Op, DAG);
}
}
@@ -28481,6 +28525,32 @@
Results.push_back(Res.getValue(1));
return;
}
+ case ISD::ADDRSPACECAST: {
+ SDValue Src = N->getOperand(0);
+ EVT DstVT = N->getValueType(0);
+ AddrSpaceCastSDNode *CastN = cast<AddrSpaceCastSDNode>(N);
+ unsigned SrcAS = CastN->getSrcAddressSpace();
+ unsigned DstAS = CastN->getDestAddressSpace();
+
+ assert(SrcAS != DstAS &&
+ "addrspacecast must be between different address spaces");
+
+ SDValue Res;
+ if (isPtrSizeOrDefaultAddrSpace(SrcAS) &&
+ isPtrSizeOrDefaultAddrSpace(DstAS)) {
+ if (SrcAS == X86AS::PTR32_UPTR && DstVT == MVT::i64)
+ Res = DAG.getNode(ISD::ZERO_EXTEND, dl, DstVT, Src);
+ else if (DstVT == MVT::i64)
+ Res = DAG.getNode(ISD::SIGN_EXTEND, dl, DstVT, Src);
+ else
+ Res = DAG.getNode(ISD::TRUNCATE, dl, DstVT, Src);
+ } else {
+ report_fatal_error("Unrecognized addrspacecast type legalization");
+ }
+
+ Results.push_back(Res);
+ return;
+ }
}
}
Index: llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
===================================================================
--- llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
+++ llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
@@ -2218,12 +2218,11 @@
AM.Scale = cast<ConstantSDNode>(Mgs->getScale())->getZExtValue();
unsigned AddrSpace = cast<MemSDNode>(Parent)->getPointerInfo().getAddrSpace();
- // AddrSpace 256 -> GS, 257 -> FS, 258 -> SS.
- if (AddrSpace == 256)
+ if (AddrSpace == X86AS::GS)
AM.Segment = CurDAG->getRegister(X86::GS, MVT::i16);
- if (AddrSpace == 257)
+ if (AddrSpace == X86AS::FS)
AM.Segment = CurDAG->getRegister(X86::FS, MVT::i16);
- if (AddrSpace == 258)
+ if (AddrSpace == X86AS::SS)
AM.Segment = CurDAG->getRegister(X86::SS, MVT::i16);
SDLoc DL(N);
Index: llvm/lib/Target/X86/X86.h
===================================================================
--- llvm/lib/Target/X86/X86.h
+++ llvm/lib/Target/X86/X86.h
@@ -146,4 +146,15 @@
void initializeX86SpeculativeLoadHardeningPassPass(PassRegistry &);
} // End llvm namespace
+namespace X86AS {
+enum : unsigned {
+ GS = 256,
+ FS = 257,
+ SS = 258,
+ PTR32_SPTR = 270,
+ PTR32_UPTR = 271,
+ PTR64 = 272
+};
+}
+
#endif
Index: clang/lib/Sema/SemaType.cpp
===================================================================
--- clang/lib/Sema/SemaType.cpp
+++ clang/lib/Sema/SemaType.cpp
@@ -6462,6 +6462,8 @@
attr::Kind NewAttrKind = A->getKind();
QualType Desugared = Type;
const AttributedType *AT = dyn_cast<AttributedType>(Type);
+ llvm::SmallSet<attr::Kind, 2> Attrs;
+ Attrs.insert(NewAttrKind);
while (AT) {
attr::Kind CurAttrKind = AT->getAttrKind();
@@ -6489,6 +6491,7 @@
Desugared = AT->getEquivalentType();
AT = dyn_cast<AttributedType>(Desugared);
+ Attrs.insert(CurAttrKind);
}
// Pointer type qualifiers can only operate on pointer types, but not
@@ -6506,7 +6509,26 @@
return true;
}
- Type = State.getAttributedType(A, Type, Type);
+ // Add address space qualifier.
+ LangAS ASIdx = LangAS::Default;
+ uint64_t PtrWidth = S.Context.getTargetInfo().getPointerWidth(0);
+ if (PtrWidth == 32) {
+ if (Attrs.count(attr::Ptr64))
+ ASIdx = LangAS::ptr64;
+ else if (Attrs.count(attr::UPtr))
+ ASIdx = LangAS::ptr32_uptr;
+ } else if (PtrWidth == 64 && Attrs.count(attr::Ptr32)) {
+ if (Attrs.count(attr::UPtr))
+ ASIdx = LangAS::ptr32_uptr;
+ else
+ ASIdx = LangAS::ptr32_sptr;
+ }
+
+ QualType Pointee = Type->getPointeeType();
+ if (ASIdx != LangAS::Default)
+ Pointee = S.Context.getAddrSpaceQualType(
+ S.Context.removeAddrSpaceQualType(Pointee), ASIdx);
+ Type = State.getAttributedType(A, Type, S.Context.getPointerType(Pointee));
return false;
}
Index: clang/lib/Sema/SemaOverload.cpp
===================================================================
--- clang/lib/Sema/SemaOverload.cpp
+++ clang/lib/Sema/SemaOverload.cpp
@@ -2871,6 +2871,14 @@
O && (O != E); ++O, ++N) {
if (!Context.hasSameType(O->getUnqualifiedType(),
N->getUnqualifiedType())) {
+ const PointerType *OldTypePtr =
+ dyn_cast<PointerType>(O->getUnqualifiedType());
+ const PointerType *NewTypePtr =
+ dyn_cast<PointerType>(N->getUnqualifiedType());
+ if (OldTypePtr && NewTypePtr)
+ if (OldTypePtr->isAddressSpacePtrSize(*NewTypePtr))
+ continue;
+
if (ArgPos)
*ArgPos = O - OldType->param_type_begin();
return false;
Index: clang/lib/Basic/Targets/X86.h
===================================================================
--- clang/lib/Basic/Targets/X86.h
+++ clang/lib/Basic/Targets/X86.h
@@ -22,6 +22,21 @@
namespace clang {
namespace targets {
+static const unsigned X86AddrSpaceMap[] = {
+ 0, // Default
+ 0, // opencl_global
+ 0, // opencl_local
+ 0, // opencl_constant
+ 0, // opencl_private
+ 0, // opencl_generic
+ 0, // cuda_device
+ 0, // cuda_constant
+ 0, // cuda_shared
+ 270, // ptr32_sptr
+ 271, // ptr32_uptr
+ 272 // ptr64
+};
+
// X86 target abstract base class; x86-32 and x86-64 are very close, so
// most of the implementation can be shared.
class LLVM_LIBRARY_VISIBILITY X86TargetInfo : public TargetInfo {
@@ -45,6 +60,7 @@
AMD3DNowAthlon
} MMX3DNowLevel = NoMMX3DNow;
enum XOPEnum { NoXOP, SSE4A, FMA4, XOP } XOPLevel = NoXOP;
+ enum AddrSpace { ptr32_sptr = 270, ptr32_uptr = 271, ptr64 = 272 };
bool HasAES = false;
bool HasVAES = false;
@@ -131,6 +147,7 @@
X86TargetInfo(const llvm::Triple &Triple, const TargetOptions &)
: TargetInfo(Triple) {
LongDoubleFormat = &llvm::APFloat::x87DoubleExtended();
+ AddrSpaceMap = &X86AddrSpaceMap;
}
const char *getLongDoubleMangling() const override {
@@ -329,6 +346,18 @@
void setSupportedOpenCLOpts() override {
getSupportedOpenCLOpts().supportAll();
}
+
+ uint64_t getPointerWidthV(unsigned AddrSpace) const override {
+ if (AddrSpace == ptr32_sptr || AddrSpace == ptr32_uptr)
+ return 32;
+ if (AddrSpace == ptr64)
+ return 64;
+ return PointerWidth;
+ }
+
+ uint64_t getPointerAlignV(unsigned AddrSpace) const override {
+ return getPointerWidthV(AddrSpace);
+ }
};
// X86-32 generic target
Index: clang/lib/Basic/Targets/TCE.h
===================================================================
--- clang/lib/Basic/Targets/TCE.h
+++ clang/lib/Basic/Targets/TCE.h
@@ -39,7 +39,10 @@
0, // opencl_generic
0, // cuda_device
0, // cuda_constant
- 0 // cuda_shared
+ 0, // cuda_shared
+ 0, // ptr32_sptr
+ 0, // ptr32_uptr
+ 0, // ptr64
};
class LLVM_LIBRARY_VISIBILITY TCETargetInfo : public TargetInfo {
Index: clang/lib/Basic/Targets/SPIR.h
===================================================================
--- clang/lib/Basic/Targets/SPIR.h
+++ clang/lib/Basic/Targets/SPIR.h
@@ -30,7 +30,10 @@
4, // opencl_generic
0, // cuda_device
0, // cuda_constant
- 0 // cuda_shared
+ 0, // cuda_shared
+ 0, // ptr32_sptr
+ 0, // ptr32_uptr
+ 0 // ptr64
};
class LLVM_LIBRARY_VISIBILITY SPIRTargetInfo : public TargetInfo {
Index: clang/lib/Basic/Targets/NVPTX.h
===================================================================
--- clang/lib/Basic/Targets/NVPTX.h
+++ clang/lib/Basic/Targets/NVPTX.h
@@ -33,6 +33,9 @@
1, // cuda_device
4, // cuda_constant
3, // cuda_shared
+ 0, // ptr32_sptr
+ 0, // ptr32_uptr
+ 0 // ptr64
};
/// The DWARF address class. Taken from
Index: clang/lib/Basic/Targets/AMDGPU.cpp
===================================================================
--- clang/lib/Basic/Targets/AMDGPU.cpp
+++ clang/lib/Basic/Targets/AMDGPU.cpp
@@ -46,7 +46,10 @@
Generic, // opencl_generic
Global, // cuda_device
Constant, // cuda_constant
- Local // cuda_shared
+ Local, // cuda_shared
+ Generic, // ptr32_sptr
+ Generic, // ptr32_uptr
+ Generic // ptr64
};
const LangASMap AMDGPUTargetInfo::AMDGPUDefIsPrivMap = {
@@ -58,7 +61,11 @@
Generic, // opencl_generic
Global, // cuda_device
Constant, // cuda_constant
- Local // cuda_shared
+ Local, // cuda_shared
+ Generic, // ptr32_sptr
+ Generic, // ptr32_uptr
+ Generic // ptr64
+
};
} // namespace targets
} // namespace clang
Index: clang/lib/AST/TypePrinter.cpp
===================================================================
--- clang/lib/AST/TypePrinter.cpp
+++ clang/lib/AST/TypePrinter.cpp
@@ -1819,6 +1819,15 @@
case LangAS::cuda_shared:
OS << "__shared__";
break;
+ case LangAS::ptr32_sptr:
+ OS << "__ptr32_sptr";
+ break;
+ case LangAS::ptr32_uptr:
+ OS << "__ptr32_uptr";
+ break;
+ case LangAS::ptr64:
+ OS << "__ptr64";
+ break;
default:
OS << "__attribute__((address_space(";
OS << toTargetAddressSpace(addrspace);
Index: clang/lib/AST/MicrosoftMangle.cpp
===================================================================
--- clang/lib/AST/MicrosoftMangle.cpp
+++ clang/lib/AST/MicrosoftMangle.cpp
@@ -1870,6 +1870,15 @@
case LangAS::cuda_shared:
Extra.mangleSourceName("_ASCUshared");
break;
+ case LangAS::ptr32_sptr:
+ Extra.mangleSourceName("_ASPtr32_sptr");
+ break;
+ case LangAS::ptr32_uptr:
+ Extra.mangleSourceName("_ASPtr32_uptr");
+ break;
+ case LangAS::ptr64:
+ Extra.mangleSourceName("_ASPtr64");
+ break;
}
}
Index: clang/lib/AST/ItaniumMangle.cpp
===================================================================
--- clang/lib/AST/ItaniumMangle.cpp
+++ clang/lib/AST/ItaniumMangle.cpp
@@ -2266,6 +2266,10 @@
case LangAS::cuda_device: ASString = "CUdevice"; break;
case LangAS::cuda_constant: ASString = "CUconstant"; break;
case LangAS::cuda_shared: ASString = "CUshared"; break;
+ // <ptrsize-addrspace> ::= [ "ptr32_sptr" | "ptr32_uptr" | "ptr64" ]
+ case LangAS::ptr32_sptr: ASString = "ptr32_sptr"; break;
+ case LangAS::ptr32_uptr: ASString = "ptr32_uptr"; break;
+ case LangAS::ptr64: ASString = "ptr64"; break;
}
}
if (!ASString.empty())
Index: clang/lib/AST/ASTContext.cpp
===================================================================
--- clang/lib/AST/ASTContext.cpp
+++ clang/lib/AST/ASTContext.cpp
@@ -789,15 +789,18 @@
// The fake address space map must have a distinct entry for each
// language-specific address space.
static const unsigned FakeAddrSpaceMap[] = {
- 0, // Default
- 1, // opencl_global
- 3, // opencl_local
- 2, // opencl_constant
- 0, // opencl_private
- 4, // opencl_generic
- 5, // cuda_device
- 6, // cuda_constant
- 7 // cuda_shared
+ 0, // Default
+ 1, // opencl_global
+ 3, // opencl_local
+ 2, // opencl_constant
+ 0, // opencl_private
+ 4, // opencl_generic
+ 5, // cuda_device
+ 6, // cuda_constant
+ 7, // cuda_shared
+ 8, // ptr32_sptr
+ 9, // ptr32_uptr
+ 10 // ptr64
};
return &FakeAddrSpaceMap;
} else {
Index: clang/include/clang/Basic/AddressSpaces.h
===================================================================
--- clang/include/clang/Basic/AddressSpaces.h
+++ clang/include/clang/Basic/AddressSpaces.h
@@ -42,6 +42,11 @@
cuda_constant,
cuda_shared,
+ // Pointer size and extension address spaces.
+ ptr32_sptr,
+ ptr32_uptr,
+ ptr64,
+
// This denotes the count of language-specific address spaces and also
// the offset added to the target-specific address spaces, which are usually
// specified by address space attributes __attribute__(address_space(n))).
@@ -68,6 +73,11 @@
(unsigned)LangAS::FirstTargetAddressSpace);
}
+inline bool isPtrSizeOrDefaultAddressSpace(LangAS AS) {
+ return (AS == LangAS::Default || AS == LangAS::ptr32_sptr ||
+ AS == LangAS::ptr32_uptr || AS == LangAS::ptr64);
+}
+
} // namespace clang
#endif // LLVM_CLANG_BASIC_ADDRESSSPACES_H
Index: clang/include/clang/AST/Type.h
===================================================================
--- clang/include/clang/AST/Type.h
+++ clang/include/clang/AST/Type.h
@@ -472,7 +472,10 @@
return A == B ||
// Otherwise in OpenCLC v2.0 s6.5.5: every address space except
// for __constant can be used as __generic.
- (A == LangAS::opencl_generic && B != LangAS::opencl_constant);
+ (A == LangAS::opencl_generic && B != LangAS::opencl_constant) ||
+ // Consider mixed sized pointers to be equivalent.
+ (isPtrSizeOrDefaultAddressSpace(A) &&
+ isPtrSizeOrDefaultAddressSpace(B));
}
/// Returns true if the address space in these qualifiers is equal to or
@@ -2588,6 +2591,13 @@
otherQuals.isAddressSpaceSupersetOf(thisQuals);
}
+ bool isAddressSpacePtrSize(const PointerType &other) const {
+ Qualifiers thisQuals = PointeeType.getQualifiers();
+ Qualifiers otherQuals = other.getPointeeType().getQualifiers();
+ return (isPtrSizeOrDefaultAddressSpace(thisQuals.getAddressSpace()) &&
+ isPtrSizeOrDefaultAddressSpace(otherQuals.getAddressSpace()));
+ }
+
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits