From: Yaxun Liu Date: Fri, 19 Aug 2016 05:17:25 +0000 (+0000) Subject: Re-commit [OpenCL] AMDGCN: Fix size_t type X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d0b5dcb55c8748f6efbae514858aba234483bd3b;p=clang Re-commit [OpenCL] AMDGCN: Fix size_t type There was a premature cast to pointer type in emitPointerArithmetic which caused assertion in tests with assertion enabled. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@279206 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/TargetInfo.h b/include/clang/Basic/TargetInfo.h index a9378f83af..de94cdacd2 100644 --- a/include/clang/Basic/TargetInfo.h +++ b/include/clang/Basic/TargetInfo.h @@ -294,6 +294,11 @@ public: return AddrSpace == 0 ? PointerAlign : getPointerAlignV(AddrSpace); } + /// \brief Return the maximum width of pointers on this target. + virtual uint64_t getMaxPointerWidth() const { + return PointerWidth; + } + /// \brief Return the size of '_Bool' and C++ 'bool' for this target, in bits. unsigned getBoolWidth() const { return BoolWidth; } diff --git a/lib/Basic/TargetInfo.cpp b/lib/Basic/TargetInfo.cpp index dec8b7cda4..592b877fad 100644 --- a/lib/Basic/TargetInfo.cpp +++ b/lib/Basic/TargetInfo.cpp @@ -306,8 +306,9 @@ void TargetInfo::adjust(const LangOptions &Opts) { } LongDoubleWidth = LongDoubleAlign = 128; - assert(PointerWidth == 32 || PointerWidth == 64); - bool Is32BitArch = PointerWidth == 32; + unsigned MaxPointerWidth = getMaxPointerWidth(); + assert(MaxPointerWidth == 32 || MaxPointerWidth == 64); + bool Is32BitArch = MaxPointerWidth == 32; SizeType = Is32BitArch ? UnsignedInt : UnsignedLong; PtrDiffType = Is32BitArch ? SignedInt : SignedLong; IntPtrType = Is32BitArch ? SignedInt : SignedLong; diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp index 793b25e928..36e6d4594f 100644 --- a/lib/Basic/Targets.cpp +++ b/lib/Basic/Targets.cpp @@ -2004,6 +2004,10 @@ public: } } + uint64_t getMaxPointerWidth() const override { + return getTriple().getArch() == llvm::Triple::amdgcn ? 64 : 32; + } + const char * getClobbers() const override { return ""; } diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp index ba7f49b750..e70c31ad63 100644 --- a/lib/CodeGen/CGExprScalar.cpp +++ b/lib/CodeGen/CGExprScalar.cpp @@ -787,7 +787,7 @@ Value *ScalarExprEmitter::EmitScalarConversion(Value *Src, QualType SrcType, // Handle pointer conversions next: pointers can only be converted to/from // other pointers and integers. Check for pointer types in terms of LLVM, as // some native types (like Obj-C id) may map to a pointer type. - if (isa(DstTy)) { + if (auto DstPT = dyn_cast(DstTy)) { // The source value may be an integer, or a pointer. if (isa(SrcTy)) return Builder.CreateBitCast(Src, DstTy, "conv"); @@ -795,7 +795,7 @@ Value *ScalarExprEmitter::EmitScalarConversion(Value *Src, QualType SrcType, assert(SrcType->isIntegerType() && "Not ptr->ptr or int->ptr conversion?"); // First, convert to the correct width so that we control the kind of // extension. - llvm::Type *MiddleTy = CGF.IntPtrTy; + llvm::Type *MiddleTy = CGF.CGM.getDataLayout().getIntPtrType(DstPT); bool InputSigned = SrcType->isSignedIntegerOrEnumerationType(); llvm::Value* IntResult = Builder.CreateIntCast(Src, MiddleTy, InputSigned, "conv"); @@ -1510,12 +1510,13 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) { // First, convert to the correct width so that we control the kind of // extension. - llvm::Type *MiddleTy = CGF.IntPtrTy; + auto DestLLVMTy = ConvertType(DestTy); + llvm::Type *MiddleTy = CGF.CGM.getDataLayout().getIntPtrType(DestLLVMTy); bool InputSigned = E->getType()->isSignedIntegerOrEnumerationType(); llvm::Value* IntResult = Builder.CreateIntCast(Src, MiddleTy, InputSigned, "conv"); - return Builder.CreateIntToPtr(IntResult, ConvertType(DestTy)); + return Builder.CreateIntToPtr(IntResult, DestLLVMTy); } case CK_PointerToIntegral: assert(!DestTy->isBooleanType() && "bool should use PointerToBool"); @@ -2436,11 +2437,13 @@ static Value *emitPointerArithmetic(CodeGenFunction &CGF, } unsigned width = cast(index->getType())->getBitWidth(); - if (width != CGF.PointerWidthInBits) { + auto &DL = CGF.CGM.getDataLayout(); + auto PtrTy = cast(pointer->getType()); + if (width != DL.getTypeSizeInBits(PtrTy)) { // Zero-extend or sign-extend the pointer value according to // whether the index is signed or not. bool isSigned = indexOperand->getType()->isSignedIntegerOrEnumerationType(); - index = CGF.Builder.CreateIntCast(index, CGF.PtrDiffTy, isSigned, + index = CGF.Builder.CreateIntCast(index, DL.getIntPtrType(PtrTy), isSigned, "idx.ext"); } diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index 2dcccf4c6c..1d74e4cd83 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -101,10 +101,13 @@ CodeGenModule::CodeGenModule(ASTContext &C, const HeaderSearchOptions &HSO, PointerWidthInBits = C.getTargetInfo().getPointerWidth(0); PointerAlignInBytes = C.toCharUnitsFromBits(C.getTargetInfo().getPointerAlign(0)).getQuantity(); + SizeSizeInBytes = + C.toCharUnitsFromBits(C.getTargetInfo().getMaxPointerWidth()).getQuantity(); IntAlignInBytes = C.toCharUnitsFromBits(C.getTargetInfo().getIntAlign()).getQuantity(); IntTy = llvm::IntegerType::get(LLVMContext, C.getTargetInfo().getIntWidth()); - IntPtrTy = llvm::IntegerType::get(LLVMContext, PointerWidthInBits); + IntPtrTy = llvm::IntegerType::get(LLVMContext, + C.getTargetInfo().getMaxPointerWidth()); Int8PtrTy = Int8Ty->getPointerTo(0); Int8PtrPtrTy = Int8PtrTy->getPointerTo(0); diff --git a/lib/CodeGen/CodeGenTypeCache.h b/lib/CodeGen/CodeGenTypeCache.h index c32b66d129..47e26bcaa1 100644 --- a/lib/CodeGen/CodeGenTypeCache.h +++ b/lib/CodeGen/CodeGenTypeCache.h @@ -80,9 +80,14 @@ struct CodeGenTypeCache { union { unsigned char PointerAlignInBytes; unsigned char PointerSizeInBytes; + }; + + /// The size and alignment of size_t. + union { unsigned char SizeSizeInBytes; // sizeof(size_t) unsigned char SizeAlignInBytes; }; + CharUnits getSizeSize() const { return CharUnits::fromQuantity(SizeSizeInBytes); } diff --git a/test/CodeGenOpenCL/size_t.cl b/test/CodeGenOpenCL/size_t.cl new file mode 100644 index 0000000000..ed941e0185 --- /dev/null +++ b/test/CodeGenOpenCL/size_t.cl @@ -0,0 +1,110 @@ +// RUN: %clang_cc1 %s -cl-std=CL2.0 -finclude-default-header -emit-llvm -O0 -triple spir-unknown-unknown -o - | FileCheck --check-prefix=SZ32 %s +// 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 +// 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 + +//SZ32: define{{.*}} i32 @test_ptrtoint_private(i8* %x) +//SZ32: ptrtoint i8* %{{.*}} to i32 +//SZ64: define{{.*}} i64 @test_ptrtoint_private(i8* %x) +//SZ64: ptrtoint i8* %{{.*}} to i64 +size_t test_ptrtoint_private(private char* x) { + return (size_t)x; +} + +//SZ32: define{{.*}} i32 @test_ptrtoint_global(i8 addrspace(1)* %x) +//SZ32: ptrtoint i8 addrspace(1)* %{{.*}} to i32 +//SZ64: define{{.*}} i64 @test_ptrtoint_global(i8 addrspace(1)* %x) +//SZ64: ptrtoint i8 addrspace(1)* %{{.*}} to i64 +intptr_t test_ptrtoint_global(global char* x) { + return (intptr_t)x; +} + +//SZ32: define{{.*}} i32 @test_ptrtoint_constant(i8 addrspace(2)* %x) +//SZ32: ptrtoint i8 addrspace(2)* %{{.*}} to i32 +//SZ64: define{{.*}} i64 @test_ptrtoint_constant(i8 addrspace(2)* %x) +//SZ64: ptrtoint i8 addrspace(2)* %{{.*}} to i64 +uintptr_t test_ptrtoint_constant(constant char* x) { + return (uintptr_t)x; +} + +//SZ32: define{{.*}} i32 @test_ptrtoint_local(i8 addrspace(3)* %x) +//SZ32: ptrtoint i8 addrspace(3)* %{{.*}} to i32 +//SZ64: define{{.*}} i64 @test_ptrtoint_local(i8 addrspace(3)* %x) +//SZ64: ptrtoint i8 addrspace(3)* %{{.*}} to i64 +size_t test_ptrtoint_local(local char* x) { + return (size_t)x; +} + +//SZ32: define{{.*}} i32 @test_ptrtoint_generic(i8 addrspace(4)* %x) +//SZ32: ptrtoint i8 addrspace(4)* %{{.*}} to i32 +//SZ64: define{{.*}} i64 @test_ptrtoint_generic(i8 addrspace(4)* %x) +//SZ64: ptrtoint i8 addrspace(4)* %{{.*}} to i64 +size_t test_ptrtoint_generic(generic char* x) { + return (size_t)x; +} + +//SZ32: define{{.*}} i8* @test_inttoptr_private(i32 %x) +//SZ32: inttoptr i32 %{{.*}} to i8* +//SZ64: define{{.*}} i8* @test_inttoptr_private(i64 %x) +//AMDONLY: trunc i64 %{{.*}} to i32 +//AMDONLY: inttoptr i32 %{{.*}} to i8* +//SZ64ONLY: inttoptr i64 %{{.*}} to i8* +private char* test_inttoptr_private(size_t x) { + return (private char*)x; +} + +//SZ32: define{{.*}} i8 addrspace(1)* @test_inttoptr_global(i32 %x) +//SZ32: inttoptr i32 %{{.*}} to i8 addrspace(1)* +//SZ64: define{{.*}} i8 addrspace(1)* @test_inttoptr_global(i64 %x) +//SZ64: inttoptr i64 %{{.*}} to i8 addrspace(1)* +global char* test_inttoptr_global(size_t x) { + return (global char*)x; +} + +//SZ32: define{{.*}} i8 addrspace(3)* @test_add_local(i8 addrspace(3)* %x, i32 %y) +//SZ32: getelementptr inbounds i8, i8 addrspace(3)* %{{.*}}, i32 +//SZ64: define{{.*}} i8 addrspace(3)* @test_add_local(i8 addrspace(3)* %x, i64 %y) +//AMDONLY: trunc i64 %{{.*}} to i32 +//AMDONLY: getelementptr inbounds i8, i8 addrspace(3)* %{{.*}}, i32 +//SZ64ONLY: getelementptr inbounds i8, i8 addrspace(3)* %{{.*}}, i64 +local char* test_add_local(local char* x, ptrdiff_t y) { + return x + y; +} + +//SZ32: define{{.*}} i8 addrspace(1)* @test_add_global(i8 addrspace(1)* %x, i32 %y) +//SZ32: getelementptr inbounds i8, i8 addrspace(1)* %{{.*}}, i32 +//SZ64: define{{.*}} i8 addrspace(1)* @test_add_global(i8 addrspace(1)* %x, i64 %y) +//SZ64: getelementptr inbounds i8, i8 addrspace(1)* %{{.*}}, i64 +global char* test_add_global(global char* x, ptrdiff_t y) { + return x + y; +} + +//SZ32: define{{.*}} i32 @test_sub_local(i8 addrspace(3)* %x, i8 addrspace(3)* %y) +//SZ32: ptrtoint i8 addrspace(3)* %{{.*}} to i32 +//SZ32: ptrtoint i8 addrspace(3)* %{{.*}} to i32 +//SZ64: define{{.*}} i64 @test_sub_local(i8 addrspace(3)* %x, i8 addrspace(3)* %y) +//SZ64: ptrtoint i8 addrspace(3)* %{{.*}} to i64 +//SZ64: ptrtoint i8 addrspace(3)* %{{.*}} to i64 +ptrdiff_t test_sub_local(local char* x, local char *y) { + return x - y; +} + +//SZ32: define{{.*}} i32 @test_sub_private(i8* %x, i8* %y) +//SZ32: ptrtoint i8* %{{.*}} to i32 +//SZ32: ptrtoint i8* %{{.*}} to i32 +//SZ64: define{{.*}} i64 @test_sub_private(i8* %x, i8* %y) +//SZ64: ptrtoint i8* %{{.*}} to i64 +//SZ64: ptrtoint i8* %{{.*}} to i64 +ptrdiff_t test_sub_private(private char* x, private char *y) { + return x - y; +} + +//SZ32: define{{.*}} i32 @test_sub_mix(i8* %x, i8 addrspace(4)* %y) +//SZ32: ptrtoint i8* %{{.*}} to i32 +//SZ32: ptrtoint i8 addrspace(4)* %{{.*}} to i32 +//SZ64: define{{.*}} i64 @test_sub_mix(i8* %x, i8 addrspace(4)* %y) +//SZ64: ptrtoint i8* %{{.*}} to i64 +//SZ64: ptrtoint i8 addrspace(4)* %{{.*}} to i64 +ptrdiff_t test_sub_mix(private char* x, generic char *y) { + return x - y; +} +