mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-05 01:20:51 +03:00
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:
commit
d38c576919
5 changed files with 52 additions and 21 deletions
|
@ -728,6 +728,8 @@ void registerPredefinedTargetVersions() {
|
|||
// Set versions for arch bitwidth
|
||||
if (gDataLayout->getPointerSizeInBits() == 64) {
|
||||
VersionCondition::addPredefinedGlobalIdent("D_LP64");
|
||||
} else if (triple.isArch64Bit()) {
|
||||
VersionCondition::addPredefinedGlobalIdent("D_X32");
|
||||
} else if (triple.isArch16Bit()) {
|
||||
VersionCondition::addPredefinedGlobalIdent("D_P16");
|
||||
}
|
||||
|
|
|
@ -210,16 +210,16 @@ struct LLVM_LIBRARY_VISIBILITY AllocationOpt : public LibCallOptimization {
|
|||
// This module will also be used in jit runtime
|
||||
// copy these function here to avoid dependencies on rest of compiler
|
||||
LLIntegerType *DtoSize_t(llvm::LLVMContext &context,
|
||||
const llvm::Triple &triple) {
|
||||
const llvm::DataLayout &DL) {
|
||||
// the type of size_t does not change once set
|
||||
static LLIntegerType *t = nullptr;
|
||||
if (t == nullptr) {
|
||||
|
||||
if (triple.isArch64Bit()) {
|
||||
const auto ptrsize = DL.getPointerSize();
|
||||
if (ptrsize == 8) {
|
||||
t = LLType::getInt64Ty(context);
|
||||
} else if (triple.isArch32Bit()) {
|
||||
} else if (ptrsize == 4) {
|
||||
t = LLType::getInt32Ty(context);
|
||||
} else if (triple.isArch16Bit()) {
|
||||
} else if (ptrsize == 2) {
|
||||
t = LLType::getInt16Ty(context);
|
||||
} else {
|
||||
llvm_unreachable("Unsupported size_t width");
|
||||
|
@ -229,9 +229,8 @@ LLIntegerType *DtoSize_t(llvm::LLVMContext &context,
|
|||
}
|
||||
|
||||
llvm::ConstantInt *DtoConstSize_t(llvm::LLVMContext &context,
|
||||
const llvm::Triple &targetTriple,
|
||||
uint64_t i) {
|
||||
return LLConstantInt::get(DtoSize_t(context, targetTriple), i, false);
|
||||
const llvm::DataLayout &DL, uint64_t i) {
|
||||
return LLConstantInt::get(DtoSize_t(context, DL), i, false);
|
||||
}
|
||||
|
||||
/// 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
|
||||
// replace the call with memcpy
|
||||
auto Size =
|
||||
Sz != llvm::MemoryLocation::UnknownSize
|
||||
? DtoConstSize_t(
|
||||
Callee->getContext(),
|
||||
llvm::Triple(Callee->getParent()->getTargetTriple()), Sz)
|
||||
auto size = Sz != llvm::MemoryLocation::UnknownSize
|
||||
? DtoConstSize_t(Callee->getContext(),
|
||||
Callee->getParent()->getDataLayout(), Sz)
|
||||
: 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);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -90,7 +90,7 @@ void Target::_init(const Param ¶ms) {
|
|||
classinfosize = 0; // unused
|
||||
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.wchar_tsize = triple.isOSWindows() ? 2 : 4;
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "dmd/id.h"
|
||||
#include "dmd/init.h"
|
||||
#include "dmd/module.h"
|
||||
#include "dmd/target.h"
|
||||
#include "driver/cl_options.h"
|
||||
#include "gen/abi.h"
|
||||
#include "gen/arrays.h"
|
||||
|
@ -298,13 +299,11 @@ LLIntegerType *DtoSize_t() {
|
|||
// the type of size_t does not change once set
|
||||
static LLIntegerType *t = nullptr;
|
||||
if (t == nullptr) {
|
||||
auto triple = global.params.targetTriple;
|
||||
|
||||
if (triple->isArch64Bit()) {
|
||||
if (target.ptrsize == 8) {
|
||||
t = LLType::getInt64Ty(gIR->context());
|
||||
} else if (triple->isArch32Bit()) {
|
||||
} else if (target.ptrsize == 4) {
|
||||
t = LLType::getInt32Ty(gIR->context());
|
||||
} else if (triple->isArch16Bit()) {
|
||||
} else if (target.ptrsize == 2) {
|
||||
t = LLType::getInt16Ty(gIR->context());
|
||||
} else {
|
||||
llvm_unreachable("Unsupported size_t width");
|
||||
|
|
33
tests/compilable/arch64bit_abi32bit_gh3802.d
Normal file
33
tests/compilable/arch64bit_abi32bit_gh3802.d
Normal 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;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue