Merge pull request #3808 from JohanEngelen/gh3802

Fix issue #3802 - Fix size_t size for 32bit ABI on 64bit architectures.
This commit is contained in:
Martin Kinkelin 2021-08-14 20:44:10 +02:00 committed by GitHub
commit d38c576919
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 52 additions and 21 deletions

View file

@ -728,6 +728,8 @@ void registerPredefinedTargetVersions() {
// Set versions for arch bitwidth // Set versions for arch bitwidth
if (gDataLayout->getPointerSizeInBits() == 64) { if (gDataLayout->getPointerSizeInBits() == 64) {
VersionCondition::addPredefinedGlobalIdent("D_LP64"); VersionCondition::addPredefinedGlobalIdent("D_LP64");
} else if (triple.isArch64Bit()) {
VersionCondition::addPredefinedGlobalIdent("D_X32");
} else if (triple.isArch16Bit()) { } else if (triple.isArch16Bit()) {
VersionCondition::addPredefinedGlobalIdent("D_P16"); VersionCondition::addPredefinedGlobalIdent("D_P16");
} }

View file

@ -210,16 +210,16 @@ struct LLVM_LIBRARY_VISIBILITY AllocationOpt : public LibCallOptimization {
// This module will also be used in jit runtime // This module will also be used in jit runtime
// copy these function here to avoid dependencies on rest of compiler // copy these function here to avoid dependencies on rest of compiler
LLIntegerType *DtoSize_t(llvm::LLVMContext &context, LLIntegerType *DtoSize_t(llvm::LLVMContext &context,
const llvm::Triple &triple) { const llvm::DataLayout &DL) {
// the type of size_t does not change once set // the type of size_t does not change once set
static LLIntegerType *t = nullptr; static LLIntegerType *t = nullptr;
if (t == nullptr) { if (t == nullptr) {
const auto ptrsize = DL.getPointerSize();
if (triple.isArch64Bit()) { if (ptrsize == 8) {
t = LLType::getInt64Ty(context); t = LLType::getInt64Ty(context);
} else if (triple.isArch32Bit()) { } else if (ptrsize == 4) {
t = LLType::getInt32Ty(context); t = LLType::getInt32Ty(context);
} else if (triple.isArch16Bit()) { } else if (ptrsize == 2) {
t = LLType::getInt16Ty(context); t = LLType::getInt16Ty(context);
} else { } else {
llvm_unreachable("Unsupported size_t width"); llvm_unreachable("Unsupported size_t width");
@ -229,9 +229,8 @@ LLIntegerType *DtoSize_t(llvm::LLVMContext &context,
} }
llvm::ConstantInt *DtoConstSize_t(llvm::LLVMContext &context, llvm::ConstantInt *DtoConstSize_t(llvm::LLVMContext &context,
const llvm::Triple &targetTriple, const llvm::DataLayout &DL, uint64_t i) {
uint64_t i) { return LLConstantInt::get(DtoSize_t(context, DL), i, false);
return LLConstantInt::get(DtoSize_t(context, targetTriple), i, false);
} }
/// ArraySliceCopyOpt - Turn slice copies into llvm.memcpy when safe /// ArraySliceCopyOpt - Turn slice copies into llvm.memcpy when safe
@ -272,13 +271,11 @@ struct LLVM_LIBRARY_VISIBILITY ArraySliceCopyOpt : public LibCallOptimization {
// Equal length and the pointers definitely don't alias, so it's safe to // Equal length and the pointers definitely don't alias, so it's safe to
// replace the call with memcpy // replace the call with memcpy
auto Size = auto size = Sz != llvm::MemoryLocation::UnknownSize
Sz != llvm::MemoryLocation::UnknownSize ? DtoConstSize_t(Callee->getContext(),
? DtoConstSize_t( Callee->getParent()->getDataLayout(), Sz)
Callee->getContext(),
llvm::Triple(Callee->getParent()->getTargetTriple()), Sz)
: B.CreateMul(DstLength, ElemSz); : B.CreateMul(DstLength, ElemSz);
return EmitMemCpy(CI->getOperand(0), CI->getOperand(2), Size, 1, B); return EmitMemCpy(CI->getOperand(0), CI->getOperand(2), size, 1, B);
} }
}; };

View file

@ -90,7 +90,7 @@ void Target::_init(const Param &params) {
classinfosize = 0; // unused classinfosize = 0; // unused
maxStaticDataSize = std::numeric_limits<unsigned long long>::max(); maxStaticDataSize = std::numeric_limits<unsigned long long>::max();
c.longsize = triple.isArch64Bit() && !isMSVC ? 8 : 4; c.longsize = (ptrsize == 8) && !isMSVC ? 8 : 4;
c.long_doublesize = realsize; c.long_doublesize = realsize;
c.wchar_tsize = triple.isOSWindows() ? 2 : 4; c.wchar_tsize = triple.isOSWindows() ? 2 : 4;

View file

@ -16,6 +16,7 @@
#include "dmd/id.h" #include "dmd/id.h"
#include "dmd/init.h" #include "dmd/init.h"
#include "dmd/module.h" #include "dmd/module.h"
#include "dmd/target.h"
#include "driver/cl_options.h" #include "driver/cl_options.h"
#include "gen/abi.h" #include "gen/abi.h"
#include "gen/arrays.h" #include "gen/arrays.h"
@ -298,13 +299,11 @@ LLIntegerType *DtoSize_t() {
// the type of size_t does not change once set // the type of size_t does not change once set
static LLIntegerType *t = nullptr; static LLIntegerType *t = nullptr;
if (t == nullptr) { if (t == nullptr) {
auto triple = global.params.targetTriple; if (target.ptrsize == 8) {
if (triple->isArch64Bit()) {
t = LLType::getInt64Ty(gIR->context()); t = LLType::getInt64Ty(gIR->context());
} else if (triple->isArch32Bit()) { } else if (target.ptrsize == 4) {
t = LLType::getInt32Ty(gIR->context()); t = LLType::getInt32Ty(gIR->context());
} else if (triple->isArch16Bit()) { } else if (target.ptrsize == 2) {
t = LLType::getInt16Ty(gIR->context()); t = LLType::getInt16Ty(gIR->context());
} else { } else {
llvm_unreachable("Unsupported size_t width"); llvm_unreachable("Unsupported size_t width");

View file

@ -0,0 +1,33 @@
// Tests compilation for 64-bit architecture with 32-bit word size ABI.
// Triple examples: mips64el-linux-gnuabin32, x86_64-linux-gnux32
// Targeting x86 because that's the most widely available target in our CI/developer systems.
// REQUIRES: target_X86
// RUN: %ldc -mtriple=x86_64-linux-gnux32 -O -c %s
static assert((void*).sizeof == 4);
static assert(size_t.sizeof == 4);
static assert(ptrdiff_t.sizeof == 4);
version (D_LP64) static assert(0);
version (D_X32) { /* expected */ } else static assert(0);
bool equals(string lhs, string rhs)
{
foreach (const i; 0 .. lhs.length) {}
return false;
}
// test _d_array_slice_copy optimization IR pass (requires -O)
auto test_ArraySliceCopyOpt()
{
static void copy(int[] a, int[] b)
{
a[] = b[];
}
int[2] a = [1, 2];
int[2] b = [3, 4];
copy(a, b);
return a;
}