Skip to content

Commit 6305f8a

Browse files
committedAug 18, 2016
[OpenCL] AMDGCN: Fix size_t type
Pointers of certain GPUs in AMDGCN target in private address space is 32 bit but pointers in other address spaces are 64 bit. size_t type should be defined as 64 bit for these GPUs so that it could hold pointers in all address spaces. Also fixed issues in pointer arithmetic codegen by using pointer specific intptr type. Differential Revision: https://reviews.llvm.org/D23361 llvm-svn: 279121
1 parent 9e60a2a commit 6305f8a

File tree

7 files changed

+140
-9
lines changed

7 files changed

+140
-9
lines changed
 

‎clang/include/clang/Basic/TargetInfo.h

+5
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,11 @@ class TargetInfo : public RefCountedBase<TargetInfo> {
294294
return AddrSpace == 0 ? PointerAlign : getPointerAlignV(AddrSpace);
295295
}
296296

297+
/// \brief Return the maximum width of pointers on this target.
298+
virtual uint64_t getMaxPointerWidth() const {
299+
return PointerWidth;
300+
}
301+
297302
/// \brief Return the size of '_Bool' and C++ 'bool' for this target, in bits.
298303
unsigned getBoolWidth() const { return BoolWidth; }
299304

‎clang/lib/Basic/TargetInfo.cpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -306,8 +306,9 @@ void TargetInfo::adjust(const LangOptions &Opts) {
306306
}
307307
LongDoubleWidth = LongDoubleAlign = 128;
308308

309-
assert(PointerWidth == 32 || PointerWidth == 64);
310-
bool Is32BitArch = PointerWidth == 32;
309+
unsigned MaxPointerWidth = getMaxPointerWidth();
310+
assert(MaxPointerWidth == 32 || MaxPointerWidth == 64);
311+
bool Is32BitArch = MaxPointerWidth == 32;
311312
SizeType = Is32BitArch ? UnsignedInt : UnsignedLong;
312313
PtrDiffType = Is32BitArch ? SignedInt : SignedLong;
313314
IntPtrType = Is32BitArch ? SignedInt : SignedLong;

‎clang/lib/Basic/Targets.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -2004,6 +2004,10 @@ class AMDGPUTargetInfo final : public TargetInfo {
20042004
}
20052005
}
20062006

2007+
uint64_t getMaxPointerWidth() const override {
2008+
return getTriple().getArch() == llvm::Triple::amdgcn ? 64 : 32;
2009+
}
2010+
20072011
const char * getClobbers() const override {
20082012
return "";
20092013
}

‎clang/lib/CodeGen/CGExprScalar.cpp

+9-6
Original file line numberDiff line numberDiff line change
@@ -787,15 +787,15 @@ Value *ScalarExprEmitter::EmitScalarConversion(Value *Src, QualType SrcType,
787787
// Handle pointer conversions next: pointers can only be converted to/from
788788
// other pointers and integers. Check for pointer types in terms of LLVM, as
789789
// some native types (like Obj-C id) may map to a pointer type.
790-
if (isa<llvm::PointerType>(DstTy)) {
790+
if (auto DstPT = dyn_cast<llvm::PointerType>(DstTy)) {
791791
// The source value may be an integer, or a pointer.
792792
if (isa<llvm::PointerType>(SrcTy))
793793
return Builder.CreateBitCast(Src, DstTy, "conv");
794794

795795
assert(SrcType->isIntegerType() && "Not ptr->ptr or int->ptr conversion?");
796796
// First, convert to the correct width so that we control the kind of
797797
// extension.
798-
llvm::Type *MiddleTy = CGF.IntPtrTy;
798+
llvm::Type *MiddleTy = CGF.CGM.getDataLayout().getIntPtrType(DstPT);
799799
bool InputSigned = SrcType->isSignedIntegerOrEnumerationType();
800800
llvm::Value* IntResult =
801801
Builder.CreateIntCast(Src, MiddleTy, InputSigned, "conv");
@@ -1510,12 +1510,13 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) {
15101510

15111511
// First, convert to the correct width so that we control the kind of
15121512
// extension.
1513-
llvm::Type *MiddleTy = CGF.IntPtrTy;
1513+
auto DestLLVMTy = ConvertType(DestTy);
1514+
llvm::Type *MiddleTy = CGF.CGM.getDataLayout().getIntPtrType(DestLLVMTy);
15141515
bool InputSigned = E->getType()->isSignedIntegerOrEnumerationType();
15151516
llvm::Value* IntResult =
15161517
Builder.CreateIntCast(Src, MiddleTy, InputSigned, "conv");
15171518

1518-
return Builder.CreateIntToPtr(IntResult, ConvertType(DestTy));
1519+
return Builder.CreateIntToPtr(IntResult, DestLLVMTy);
15191520
}
15201521
case CK_PointerToIntegral:
15211522
assert(!DestTy->isBooleanType() && "bool should use PointerToBool");
@@ -2426,6 +2427,7 @@ static Value *emitPointerArithmetic(CodeGenFunction &CGF,
24262427

24272428
Value *pointer = op.LHS;
24282429
Expr *pointerOperand = expr->getLHS();
2430+
auto PtrTy = cast<llvm::PointerType>(pointer->getType());
24292431
Value *index = op.RHS;
24302432
Expr *indexOperand = expr->getRHS();
24312433

@@ -2436,11 +2438,12 @@ static Value *emitPointerArithmetic(CodeGenFunction &CGF,
24362438
}
24372439

24382440
unsigned width = cast<llvm::IntegerType>(index->getType())->getBitWidth();
2439-
if (width != CGF.PointerWidthInBits) {
2441+
auto &DL = CGF.CGM.getDataLayout();
2442+
if (width != DL.getTypeSizeInBits(PtrTy)) {
24402443
// Zero-extend or sign-extend the pointer value according to
24412444
// whether the index is signed or not.
24422445
bool isSigned = indexOperand->getType()->isSignedIntegerOrEnumerationType();
2443-
index = CGF.Builder.CreateIntCast(index, CGF.PtrDiffTy, isSigned,
2446+
index = CGF.Builder.CreateIntCast(index, DL.getIntPtrType(PtrTy), isSigned,
24442447
"idx.ext");
24452448
}
24462449

‎clang/lib/CodeGen/CodeGenModule.cpp

+4-1
Original file line numberDiff line numberDiff line change
@@ -101,10 +101,13 @@ CodeGenModule::CodeGenModule(ASTContext &C, const HeaderSearchOptions &HSO,
101101
PointerWidthInBits = C.getTargetInfo().getPointerWidth(0);
102102
PointerAlignInBytes =
103103
C.toCharUnitsFromBits(C.getTargetInfo().getPointerAlign(0)).getQuantity();
104+
SizeSizeInBytes =
105+
C.toCharUnitsFromBits(C.getTargetInfo().getMaxPointerWidth()).getQuantity();
104106
IntAlignInBytes =
105107
C.toCharUnitsFromBits(C.getTargetInfo().getIntAlign()).getQuantity();
106108
IntTy = llvm::IntegerType::get(LLVMContext, C.getTargetInfo().getIntWidth());
107-
IntPtrTy = llvm::IntegerType::get(LLVMContext, PointerWidthInBits);
109+
IntPtrTy = llvm::IntegerType::get(LLVMContext,
110+
C.getTargetInfo().getMaxPointerWidth());
108111
Int8PtrTy = Int8Ty->getPointerTo(0);
109112
Int8PtrPtrTy = Int8PtrTy->getPointerTo(0);
110113

‎clang/lib/CodeGen/CodeGenTypeCache.h

+5
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,14 @@ struct CodeGenTypeCache {
8080
union {
8181
unsigned char PointerAlignInBytes;
8282
unsigned char PointerSizeInBytes;
83+
};
84+
85+
/// The size and alignment of size_t.
86+
union {
8387
unsigned char SizeSizeInBytes; // sizeof(size_t)
8488
unsigned char SizeAlignInBytes;
8589
};
90+
8691
CharUnits getSizeSize() const {
8792
return CharUnits::fromQuantity(SizeSizeInBytes);
8893
}

‎clang/test/CodeGenOpenCL/size_t.cl

+110
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
// RUN: %clang_cc1 %s -cl-std=CL2.0 -finclude-default-header -emit-llvm -O0 -triple spir-unknown-unknown -o - | FileCheck --check-prefix=SZ32 %s
2+
// RUN: %clang_cc1 %s -cl-std=CL2.0 -finclude-default-header -emit-llvm -O0 -triple spir64-unknown-unknown -o - | FileCheck --check-prefix=SZ64 --check-prefix=SZ64ONLY %s
3+
// RUN: %clang_cc1 %s -cl-std=CL2.0 -finclude-default-header -emit-llvm -O0 -triple amdgcn-- -o - | FileCheck --check-prefix=SZ64 --check-prefix=AMDONLY %s
4+
5+
//SZ32: define{{.*}} i32 @test_ptrtoint_private(i8* %x)
6+
//SZ32: ptrtoint i8* %{{.*}} to i32
7+
//SZ64: define{{.*}} i64 @test_ptrtoint_private(i8* %x)
8+
//SZ64: ptrtoint i8* %{{.*}} to i64
9+
size_t test_ptrtoint_private(private char* x) {
10+
return (size_t)x;
11+
}
12+
13+
//SZ32: define{{.*}} i32 @test_ptrtoint_global(i8 addrspace(1)* %x)
14+
//SZ32: ptrtoint i8 addrspace(1)* %{{.*}} to i32
15+
//SZ64: define{{.*}} i64 @test_ptrtoint_global(i8 addrspace(1)* %x)
16+
//SZ64: ptrtoint i8 addrspace(1)* %{{.*}} to i64
17+
intptr_t test_ptrtoint_global(global char* x) {
18+
return (intptr_t)x;
19+
}
20+
21+
//SZ32: define{{.*}} i32 @test_ptrtoint_constant(i8 addrspace(2)* %x)
22+
//SZ32: ptrtoint i8 addrspace(2)* %{{.*}} to i32
23+
//SZ64: define{{.*}} i64 @test_ptrtoint_constant(i8 addrspace(2)* %x)
24+
//SZ64: ptrtoint i8 addrspace(2)* %{{.*}} to i64
25+
uintptr_t test_ptrtoint_constant(constant char* x) {
26+
return (uintptr_t)x;
27+
}
28+
29+
//SZ32: define{{.*}} i32 @test_ptrtoint_local(i8 addrspace(3)* %x)
30+
//SZ32: ptrtoint i8 addrspace(3)* %{{.*}} to i32
31+
//SZ64: define{{.*}} i64 @test_ptrtoint_local(i8 addrspace(3)* %x)
32+
//SZ64: ptrtoint i8 addrspace(3)* %{{.*}} to i64
33+
size_t test_ptrtoint_local(local char* x) {
34+
return (size_t)x;
35+
}
36+
37+
//SZ32: define{{.*}} i32 @test_ptrtoint_generic(i8 addrspace(4)* %x)
38+
//SZ32: ptrtoint i8 addrspace(4)* %{{.*}} to i32
39+
//SZ64: define{{.*}} i64 @test_ptrtoint_generic(i8 addrspace(4)* %x)
40+
//SZ64: ptrtoint i8 addrspace(4)* %{{.*}} to i64
41+
size_t test_ptrtoint_generic(generic char* x) {
42+
return (size_t)x;
43+
}
44+
45+
//SZ32: define{{.*}} i8* @test_inttoptr_private(i32 %x)
46+
//SZ32: inttoptr i32 %{{.*}} to i8*
47+
//SZ64: define{{.*}} i8* @test_inttoptr_private(i64 %x)
48+
//AMDONLY: trunc i64 %{{.*}} to i32
49+
//AMDONLY: inttoptr i32 %{{.*}} to i8*
50+
//SZ64ONLY: inttoptr i64 %{{.*}} to i8*
51+
private char* test_inttoptr_private(size_t x) {
52+
return (private char*)x;
53+
}
54+
55+
//SZ32: define{{.*}} i8 addrspace(1)* @test_inttoptr_global(i32 %x)
56+
//SZ32: inttoptr i32 %{{.*}} to i8 addrspace(1)*
57+
//SZ64: define{{.*}} i8 addrspace(1)* @test_inttoptr_global(i64 %x)
58+
//SZ64: inttoptr i64 %{{.*}} to i8 addrspace(1)*
59+
global char* test_inttoptr_global(size_t x) {
60+
return (global char*)x;
61+
}
62+
63+
//SZ32: define{{.*}} i8 addrspace(3)* @test_add_local(i8 addrspace(3)* %x, i32 %y)
64+
//SZ32: getelementptr inbounds i8, i8 addrspace(3)* %{{.*}}, i32
65+
//SZ64: define{{.*}} i8 addrspace(3)* @test_add_local(i8 addrspace(3)* %x, i64 %y)
66+
//AMDONLY: trunc i64 %{{.*}} to i32
67+
//AMDONLY: getelementptr inbounds i8, i8 addrspace(3)* %{{.*}}, i32
68+
//SZ64ONLY: getelementptr inbounds i8, i8 addrspace(3)* %{{.*}}, i64
69+
local char* test_add_local(local char* x, ptrdiff_t y) {
70+
return x + y;
71+
}
72+
73+
//SZ32: define{{.*}} i8 addrspace(1)* @test_add_global(i8 addrspace(1)* %x, i32 %y)
74+
//SZ32: getelementptr inbounds i8, i8 addrspace(1)* %{{.*}}, i32
75+
//SZ64: define{{.*}} i8 addrspace(1)* @test_add_global(i8 addrspace(1)* %x, i64 %y)
76+
//SZ64: getelementptr inbounds i8, i8 addrspace(1)* %{{.*}}, i64
77+
global char* test_add_global(global char* x, ptrdiff_t y) {
78+
return x + y;
79+
}
80+
81+
//SZ32: define{{.*}} i32 @test_sub_local(i8 addrspace(3)* %x, i8 addrspace(3)* %y)
82+
//SZ32: ptrtoint i8 addrspace(3)* %{{.*}} to i32
83+
//SZ32: ptrtoint i8 addrspace(3)* %{{.*}} to i32
84+
//SZ64: define{{.*}} i64 @test_sub_local(i8 addrspace(3)* %x, i8 addrspace(3)* %y)
85+
//SZ64: ptrtoint i8 addrspace(3)* %{{.*}} to i64
86+
//SZ64: ptrtoint i8 addrspace(3)* %{{.*}} to i64
87+
ptrdiff_t test_sub_local(local char* x, local char *y) {
88+
return x - y;
89+
}
90+
91+
//SZ32: define{{.*}} i32 @test_sub_private(i8* %x, i8* %y)
92+
//SZ32: ptrtoint i8* %{{.*}} to i32
93+
//SZ32: ptrtoint i8* %{{.*}} to i32
94+
//SZ64: define{{.*}} i64 @test_sub_private(i8* %x, i8* %y)
95+
//SZ64: ptrtoint i8* %{{.*}} to i64
96+
//SZ64: ptrtoint i8* %{{.*}} to i64
97+
ptrdiff_t test_sub_private(private char* x, private char *y) {
98+
return x - y;
99+
}
100+
101+
//SZ32: define{{.*}} i32 @test_sub_mix(i8* %x, i8 addrspace(4)* %y)
102+
//SZ32: ptrtoint i8* %{{.*}} to i32
103+
//SZ32: ptrtoint i8 addrspace(4)* %{{.*}} to i32
104+
//SZ64: define{{.*}} i64 @test_sub_mix(i8* %x, i8 addrspace(4)* %y)
105+
//SZ64: ptrtoint i8* %{{.*}} to i64
106+
//SZ64: ptrtoint i8 addrspace(4)* %{{.*}} to i64
107+
ptrdiff_t test_sub_mix(private char* x, generic char *y) {
108+
return x - y;
109+
}
110+

0 commit comments

Comments
 (0)
Please sign in to comment.