Skip to content

Commit

Permalink
Merge pull request #3808 from JohanEngelen/gh3802
Browse files Browse the repository at this point in the history
Fix issue #3802 - Fix size_t size for 32bit ABI on 64bit architectures.
  • Loading branch information
kinke committed Aug 14, 2021
2 parents c517ce9 + 44e9e4d commit d38c576
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 21 deletions.
2 changes: 2 additions & 0 deletions driver/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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");
}
Expand Down
27 changes: 12 additions & 15 deletions gen/passes/SimplifyDRuntimeCalls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand All @@ -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
Expand Down Expand Up @@ -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)
: B.CreateMul(DstLength, ElemSz);
return EmitMemCpy(CI->getOperand(0), CI->getOperand(2), Size, 1, B);
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);
}
};

Expand Down
2 changes: 1 addition & 1 deletion gen/target.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ void Target::_init(const Param &params) {
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;

Expand Down
9 changes: 4 additions & 5 deletions gen/tollvm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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");
Expand Down
33 changes: 33 additions & 0 deletions tests/compilable/arch64bit_abi32bit_gh3802.d
Original file line number Diff line number Diff line change
@@ -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;
}

0 comments on commit d38c576

Please sign in to comment.