diff options
| -rw-r--r-- | clang/include/clang/Basic/TargetInfo.h | 5 | ||||
| -rw-r--r-- | clang/lib/Basic/TargetInfo.cpp | 5 | ||||
| -rw-r--r-- | clang/lib/Basic/Targets.cpp | 4 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CGExprScalar.cpp | 15 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 5 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CodeGenTypeCache.h | 5 | ||||
| -rw-r--r-- | clang/test/CodeGenOpenCL/size_t.cl | 110 | 
7 files changed, 140 insertions, 9 deletions
diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h index a9378f83afd..de94cdacd2c 100644 --- a/clang/include/clang/Basic/TargetInfo.h +++ b/clang/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/clang/lib/Basic/TargetInfo.cpp b/clang/lib/Basic/TargetInfo.cpp index dec8b7cda4e..592b877fadd 100644 --- a/clang/lib/Basic/TargetInfo.cpp +++ b/clang/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/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp index 793b25e9287..36e6d4594fa 100644 --- a/clang/lib/Basic/Targets.cpp +++ b/clang/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/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp index ba7f49b750b..e70c31ad63a 100644 --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/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<llvm::PointerType>(DstTy)) { +  if (auto DstPT = dyn_cast<llvm::PointerType>(DstTy)) {      // The source value may be an integer, or a pointer.      if (isa<llvm::PointerType>(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<llvm::IntegerType>(index->getType())->getBitWidth(); -  if (width != CGF.PointerWidthInBits) { +  auto &DL = CGF.CGM.getDataLayout(); +  auto PtrTy = cast<llvm::PointerType>(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/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 2dcccf4c6c8..1d74e4cd838 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/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/clang/lib/CodeGen/CodeGenTypeCache.h b/clang/lib/CodeGen/CodeGenTypeCache.h index c32b66d129d..47e26bcaa1b 100644 --- a/clang/lib/CodeGen/CodeGenTypeCache.h +++ b/clang/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/clang/test/CodeGenOpenCL/size_t.cl b/clang/test/CodeGenOpenCL/size_t.cl new file mode 100644 index 00000000000..ed941e01852 --- /dev/null +++ b/clang/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; +} +  | 

