Skip to content

Commit

Permalink
Fix issue #3806 - Fix size_t size for 32bit ABI on 64bit architectures.
Browse files Browse the repository at this point in the history
  • Loading branch information
JohanEngelen committed Aug 7, 2021
1 parent dae61cb commit c00302a
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 20 deletions.
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
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
12 changes: 12 additions & 0 deletions tests/compilable/arch64bit_abi32bit_gh3802.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Tests compilation for 64-bit architecture with 32-bit word size ABI.
// Triple examples: mips64el-linux, x86_64-linux-gnux32, aarch64-linux-gnu_ilp32
// 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 -c %s

bool equals(string lhs, string rhs)
{
foreach (const i; 0 .. lhs.length) {}
return false;
}

0 comments on commit c00302a

Please sign in to comment.