diff --git a/ddmd/func.d b/ddmd/func.d index 1b88603950..ba5e7b1909 100644 --- a/ddmd/func.d +++ b/ddmd/func.d @@ -1583,7 +1583,7 @@ public: if (f.linkage == LINKd || (f.parameters && Parameter.dim(f.parameters))) { // Declare _argptr - Type t = Type.tvalist; + Type t = Type.tvalist.semantic(loc, sc); argptr = new VarDeclaration(Loc(), t, Id._argptr, null); argptr.storage_class |= STCtemp; argptr.semantic(sc2); diff --git a/driver/linker.cpp b/driver/linker.cpp index ca5e5fa335..ef9934406c 100644 --- a/driver/linker.cpp +++ b/driver/linker.cpp @@ -230,10 +230,23 @@ static int linkObjToBinaryGcc(bool sharedLib, bool fullyStatic) { break; } } else { - if (global.params.is64bit) { - args.push_back("-m64"); - } else { - args.push_back("-m32"); + switch (global.params.targetTriple.getArch()) { + case llvm::Triple::arm: + case llvm::Triple::armeb: + case llvm::Triple::aarch64: + case llvm::Triple::aarch64_be: +#if LDC_LLVM_VER == 305 + case llvm::Triple::arm64: + case llvm::Triple::arm64_be: +#endif + break; + default: + if (global.params.is64bit) { + args.push_back("-m64"); + } + else { + args.push_back("-m32"); + } } } } diff --git a/gen/abi-aarch64.cpp b/gen/abi-aarch64.cpp index de6b277a53..86feb4dcab 100644 --- a/gen/abi-aarch64.cpp +++ b/gen/abi-aarch64.cpp @@ -112,8 +112,7 @@ struct AArch64TargetABI : TargetABI { // using TypeIdentifier here is a bit wonky but works, as long as the name // is actually available in the scope (this is what DMD does, so if a better // solution is found there, this should be adapted). - return (createTypeIdentifier(Loc(), Identifier::idPool("__va_list_tag"))) - ->pointerTo(); + return (new TypeIdentifier(Loc(), Identifier::idPool("__va_list"))); } }; diff --git a/gen/abi-arm.cpp b/gen/abi-arm.cpp index 3f4626cb22..81ae57651e 100644 --- a/gen/abi-arm.cpp +++ b/gen/abi-arm.cpp @@ -67,14 +67,29 @@ struct ArmTargetABI : TargetABI { } bool passByVal(Type *t) override { - // AAPCS does not pass byval - return false; + // AAPCS does not use an indirect arg to pass aggregates, however + // clang uses byval for types > 64-bytes, then llvm backend + // converts back to non-byval. Without this special handling the + // optimzer generates bad code (e.g. std.random unittest crash). + t = t->toBasetype(); + return ((t->ty == Tsarray || t->ty == Tstruct) && t->size() > 64); - // Note: the codegen is horrible for Tsarrays passed this way - tries to do - // copy without a loop for huge arrays. Would be better if byval was used - // for arrays, but then there is an optimizer problem in the "top-down list - // latency scheduler" pass that reorders instructions incorrectly if byval - // used. + // Note: byval can have a codegen problem with -O1 and higher. + // What happens is that load instructions are being incorrectly + // reordered before stores. It is a problem in the LLVM backend. + // The outcome is a program with incorrect results or crashes. + // It happens in the "top-down list latency scheduler" pass + // + // https://forum.dlang.org/post/m2r3u5ac0c.fsf@comcast.net + // + // Revist and determine if the byval problem is only for small + // structs, say 16-bytes or less, that can entirely fit in + // registers. + + // Note: the codegen is horrible for Tsarrays passed this way - + // does a copy without a loop for huge arrays. Could be better if + // byval was always used for sarrays, and maybe can if above + // problem is better understood. } void rewriteFunctionType(TypeFunction *tf, IrFuncTy &fty) override { @@ -94,6 +109,11 @@ struct ArmTargetABI : TargetABI { if (!arg->byref) rewriteArgument(fty, *arg); } + + // extern(D): reverse parameter order for non variadics, for DMD-compliance + if (tf->linkage == LINKd && tf->varargs != 1 && fty.args.size() > 1) { + fty.reverseParams = true; + } } void rewriteArgument(IrFuncTy &fty, IrFuncTyArg &arg) override { diff --git a/gen/asmstmt.cpp b/gen/asmstmt.cpp index 9fca1a77ca..85071dc68b 100644 --- a/gen/asmstmt.cpp +++ b/gen/asmstmt.cpp @@ -114,7 +114,10 @@ Statement *asmSemantic(AsmStatement *s, Scope *sc) { err = true; } if (err) { - fatal(); + if (!global.gag) { + fatal(); + } + return s; } // puts(toChars()); diff --git a/gen/functions.cpp b/gen/functions.cpp index 9af72f71b9..630d739b56 100644 --- a/gen/functions.cpp +++ b/gen/functions.cpp @@ -883,7 +883,7 @@ void DtoDefineFunction(FuncDeclaration *fd) { // D varargs: prepare _argptr and _arguments if (f->linkage == LINKd && f->varargs == 1) { // allocate _argptr (of type core.stdc.stdarg.va_list) - LLValue *argptrmem = DtoAlloca(Type::tvalist, "_argptr_mem"); + LLValue *argptrmem = DtoAlloca(Type::tvalist->semantic(fd->loc, fd->scope), "_argptr_mem"); irFunc->_argptr = argptrmem; // initialize _argptr with a call to the va_start intrinsic diff --git a/gen/tollvm.cpp b/gen/tollvm.cpp index 37454dfcdb..b599b43401 100644 --- a/gen/tollvm.cpp +++ b/gen/tollvm.cpp @@ -63,7 +63,9 @@ LLAttribute DtoShouldExtend(Type *type) { case Tuns8: case Tuns16: - return LLAttribute::ZExt; + case Tchar: + case Twchar: + return LLAttribute::ZExt; default: // Do not extend. @@ -410,6 +412,15 @@ LLConstant *DtoConstFP(Type *t, longdouble value) { return LLConstantFP::get(gIR->context(), APFloat(APFloat::x87DoubleExtended, APInt(80, 2, bits))); } + if (llty == LLType::getFP128Ty(gIR->context())) { + union { + longdouble ld; + uint64_t bits[2]; + } t; + t.ld = value; + return LLConstantFP::get( + gIR->context(), APFloat(APFloat::IEEEquad, APInt(128, 2, t.bits))); + } if (llty == LLType::getPPC_FP128Ty(gIR->context())) { uint64_t bits[] = {0, 0}; bits[0] = *reinterpret_cast(&value); diff --git a/ir/irdsymbol.cpp b/ir/irdsymbol.cpp index efa772ec16..c821da7d83 100644 --- a/ir/irdsymbol.cpp +++ b/ir/irdsymbol.cpp @@ -27,7 +27,9 @@ void IrDsymbol::resetAll() { } } -IrDsymbol::IrDsymbol() { list.push_back(this); } +IrDsymbol::IrDsymbol() : irData(nullptr) { + list.push_back(this); +} IrDsymbol::IrDsymbol(const IrDsymbol &s) { list.push_back(this); diff --git a/ir/irdsymbol.h b/ir/irdsymbol.h index b277210f2b..82f38f02ab 100644 --- a/ir/irdsymbol.h +++ b/ir/irdsymbol.h @@ -83,7 +83,7 @@ private: friend IrField *getIrField(VarDeclaration *decl, bool create); union { - void *irData = nullptr; + void *irData; IrModule *irModule; IrAggr *irAggr; IrFunction *irFunc; diff --git a/ir/irtype.cpp b/ir/irtype.cpp index 211fd65183..51697be847 100644 --- a/ir/irtype.cpp +++ b/ir/irtype.cpp @@ -48,12 +48,21 @@ namespace { llvm::Type *getReal80Type(llvm::LLVMContext &ctx) { llvm::Triple::ArchType const a = global.params.targetTriple->getArch(); bool const anyX86 = (a == llvm::Triple::x86) || (a == llvm::Triple::x86_64); + bool const anyAarch64 = (a == llvm::Triple::aarch64) || (a == llvm::Triple::aarch64_be) +#if LDC_LLVM_VER == 305 + || (a == llvm::Triple::arm64) || (a == llvm::Triple::arm64_be) +#endif + ; // only x86 has 80bit float - but no support with MS C Runtime! if (anyX86 && !global.params.targetTriple->isWindowsMSVCEnvironment()) { return llvm::Type::getX86_FP80Ty(ctx); } + if (anyAarch64) { + return llvm::Type::getFP128Ty(ctx); + } + return llvm::Type::getDoubleTy(ctx); } } diff --git a/runtime/CMakeLists.txt b/runtime/CMakeLists.txt index 91ff134ce0..e557d895a5 100644 --- a/runtime/CMakeLists.txt +++ b/runtime/CMakeLists.txt @@ -116,6 +116,7 @@ if(UNIX) message(WARNING "Please consider updating CMake to at least 2.8.5.") else() list(APPEND DCRT_ASM ${RUNTIME_DIR}/src/core/threadasm.S) + list(APPEND DCRT_ASM ${RUNTIME_DIR}/src/ldc/eh_asm.S) endif() if(APPLE) list(APPEND CORE_D_SYS ${CORE_D_OSX}) diff --git a/runtime/druntime b/runtime/druntime index ced8af41ff..fa0c558126 160000 --- a/runtime/druntime +++ b/runtime/druntime @@ -1 +1 @@ -Subproject commit ced8af41ffaf887ef534279289fd857eaa45648a +Subproject commit fa0c558126f108a4a991d1d206925427dd4bfaae diff --git a/runtime/phobos b/runtime/phobos index 32c89fac4e..1ada8d5571 160000 --- a/runtime/phobos +++ b/runtime/phobos @@ -1 +1 @@ -Subproject commit 32c89fac4ec8cf58b7489ff4437a2577a9a7dba9 +Subproject commit 1ada8d5571bbfefc71ab45bb102a5455ff54dcb5 diff --git a/tests/d2/dmd-testsuite b/tests/d2/dmd-testsuite index 331edbc588..729534b5cc 160000 --- a/tests/d2/dmd-testsuite +++ b/tests/d2/dmd-testsuite @@ -1 +1 @@ -Subproject commit 331edbc588b60f6adee8eddb78bed97415bc95da +Subproject commit 729534b5cc3d2f4e058c54796988efb6c3ed3151