From 70ecbc8b8db977c90042322e3b7b7e87d359c36e Mon Sep 17 00:00:00 2001 From: Johan Engelen Date: Sat, 7 Aug 2021 23:44:44 +0200 Subject: [PATCH 1/5] Fix issue #3802 - Fix size_t size for 32bit ABI on 64bit architectures. --- gen/passes/SimplifyDRuntimeCalls.cpp | 27 +++++++++----------- gen/tollvm.cpp | 9 +++---- tests/compilable/arch64bit_abi32bit_gh3802.d | 12 +++++++++ 3 files changed, 28 insertions(+), 20 deletions(-) create mode 100644 tests/compilable/arch64bit_abi32bit_gh3802.d diff --git a/gen/passes/SimplifyDRuntimeCalls.cpp b/gen/passes/SimplifyDRuntimeCalls.cpp index bd42c926f66..40b565511dd 100644 --- a/gen/passes/SimplifyDRuntimeCalls.cpp +++ b/gen/passes/SimplifyDRuntimeCalls.cpp @@ -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) - : 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); } }; diff --git a/gen/tollvm.cpp b/gen/tollvm.cpp index 586de4fd81e..04df875bb07 100644 --- a/gen/tollvm.cpp +++ b/gen/tollvm.cpp @@ -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"); diff --git a/tests/compilable/arch64bit_abi32bit_gh3802.d b/tests/compilable/arch64bit_abi32bit_gh3802.d new file mode 100644 index 00000000000..fac051dc26f --- /dev/null +++ b/tests/compilable/arch64bit_abi32bit_gh3802.d @@ -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; +} From a6cc5cde38188bac9367bec660ff6762ffca52d7 Mon Sep 17 00:00:00 2001 From: Martin Kinkelin Date: Sat, 14 Aug 2021 18:47:41 +0200 Subject: [PATCH 2/5] Extend test for issue #3802 --- tests/compilable/arch64bit_abi32bit_gh3802.d | 23 ++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/tests/compilable/arch64bit_abi32bit_gh3802.d b/tests/compilable/arch64bit_abi32bit_gh3802.d index fac051dc26f..4ff9776bd5d 100644 --- a/tests/compilable/arch64bit_abi32bit_gh3802.d +++ b/tests/compilable/arch64bit_abi32bit_gh3802.d @@ -1,12 +1,31 @@ // Tests compilation for 64-bit architecture with 32-bit word size ABI. -// Triple examples: mips64el-linux, x86_64-linux-gnux32, aarch64-linux-gnu_ilp32 +// 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 -c %s +// RUN: %ldc -mtriple=x86_64-linux-gnux32 -O -c %s + +static assert(size_t.sizeof == 4); +static assert(ptrdiff_t.sizeof == 4); + +version (D_LP64) 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; +} From ec5fd799b953034bdd37151b7ee0db315e2e122f Mon Sep 17 00:00:00 2001 From: Martin Kinkelin Date: Sat, 14 Aug 2021 18:52:23 +0200 Subject: [PATCH 3/5] Predefine version D_X32 for 64-bit targets with 32-bit pointer size --- driver/main.cpp | 2 ++ tests/compilable/arch64bit_abi32bit_gh3802.d | 1 + 2 files changed, 3 insertions(+) diff --git a/driver/main.cpp b/driver/main.cpp index 0bd8c8dd150..7f0bf61707f 100644 --- a/driver/main.cpp +++ b/driver/main.cpp @@ -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"); } diff --git a/tests/compilable/arch64bit_abi32bit_gh3802.d b/tests/compilable/arch64bit_abi32bit_gh3802.d index 4ff9776bd5d..8492c81e53f 100644 --- a/tests/compilable/arch64bit_abi32bit_gh3802.d +++ b/tests/compilable/arch64bit_abi32bit_gh3802.d @@ -9,6 +9,7 @@ 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) { From 7c8df8012a45bc91299140378a35aef970ed0638 Mon Sep 17 00:00:00 2001 From: Martin Kinkelin Date: Sat, 14 Aug 2021 18:59:17 +0200 Subject: [PATCH 4/5] Set target C long size to 4 for 64-bit targets with 32-bit pointer size Which is correct for mips64el-linux-gnuabin32 and x86_64-linux-gnux32 at least. --- gen/target.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gen/target.cpp b/gen/target.cpp index 779584ed555..38dcd70f152 100644 --- a/gen/target.cpp +++ b/gen/target.cpp @@ -90,7 +90,7 @@ void Target::_init(const Param ¶ms) { classinfosize = 0; // unused maxStaticDataSize = std::numeric_limits::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; From 44e9e4db56b103fe86aa412437683982e2b64c84 Mon Sep 17 00:00:00 2001 From: Martin Kinkelin Date: Sat, 14 Aug 2021 19:17:55 +0200 Subject: [PATCH 5/5] Add a little test assertion --- tests/compilable/arch64bit_abi32bit_gh3802.d | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/compilable/arch64bit_abi32bit_gh3802.d b/tests/compilable/arch64bit_abi32bit_gh3802.d index 8492c81e53f..1a533e52611 100644 --- a/tests/compilable/arch64bit_abi32bit_gh3802.d +++ b/tests/compilable/arch64bit_abi32bit_gh3802.d @@ -5,6 +5,7 @@ // 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);