Index: include/clang/Basic/TargetOptions.h =================================================================== --- include/clang/Basic/TargetOptions.h +++ include/clang/Basic/TargetOptions.h @@ -50,6 +50,10 @@ std::vector Features; std::vector Reciprocals; + + /// \brief Controls whether doubles and long longs should be aligned on two + // word boundaries. + bool AlignDouble; }; } // end namespace clang Index: include/clang/Driver/Options.td =================================================================== --- include/clang/Driver/Options.td +++ include/clang/Driver/Options.td @@ -1415,6 +1415,7 @@ def mno_xsaves : Flag<["-"], "mno-xsaves">, Group; def mno_pku : Flag<["-"], "mno-pku">, Group; +def malign_double : Flag<["-"], "malign-double">, Group; def munaligned_access : Flag<["-"], "munaligned-access">, Group, HelpText<"Allow memory accesses to be unaligned (AArch32/AArch64 only)">; def mno_unaligned_access : Flag<["-"], "mno-unaligned-access">, Group, Index: lib/Basic/Targets.cpp =================================================================== --- lib/Basic/Targets.cpp +++ lib/Basic/Targets.cpp @@ -751,7 +751,7 @@ if (Triple.getArch() == llvm::Triple::arm) { // Handled in ARM's setABI(). } else if (Triple.getArch() == llvm::Triple::x86) { - this->resetDataLayout("e-m:e-p:32:32-i64:64-n8:16:32-S128"); + // Handled in X86_32's setDataLayoutString. } else if (Triple.getArch() == llvm::Triple::x86_64) { this->resetDataLayout("e-m:e-p:32:32-i64:64-n8:16:32:64-S128"); } else if (Triple.getArch() == llvm::Triple::mipsel) { @@ -3767,7 +3767,15 @@ LongDoubleWidth = 96; LongDoubleAlign = 32; SuitableAlign = 128; - resetDataLayout("e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128"); + + if (getTriple().isOSNaCl()) { + resetDataLayout("e-m:e-p:32:32-i64:64-n8:16:32-S128"); + } else if (Opts.AlignDouble) { + resetDataLayout("e-m:e-p:32:32-i64:64-f80:32-n8:16:32-S128"); + } else { + resetDataLayout("e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128"); + } + SizeType = UnsignedInt; PtrDiffType = SignedInt; IntPtrType = SignedInt; Index: lib/Driver/Tools.cpp =================================================================== --- lib/Driver/Tools.cpp +++ lib/Driver/Tools.cpp @@ -2144,6 +2144,11 @@ CmdArgs.push_back("soft"); CmdArgs.push_back("-mstack-alignment=4"); } + + if (Args.getLastArg(options::OPT_malign_double)) { + CmdArgs.push_back("-mllvm"); + CmdArgs.push_back("-malign-double"); + } } void Clang::AddHexagonTargetArgs(const ArgList &Args, Index: lib/Frontend/CompilerInvocation.cpp =================================================================== --- lib/Frontend/CompilerInvocation.cpp +++ lib/Frontend/CompilerInvocation.cpp @@ -2091,6 +2091,9 @@ Opts.LinkerVersion = Args.getLastArgValue(OPT_target_linker_version); Opts.Triple = llvm::Triple::normalize(Args.getLastArgValue(OPT_triple)); Opts.Reciprocals = Args.getAllArgValues(OPT_mrecip_EQ); + auto LLVMArgs = Args.getAllArgValues(OPT_mllvm); + auto it = std::find(LLVMArgs.begin(), LLVMArgs.end(), "-malign-double"); + Opts.AlignDouble = (it != LLVMArgs.end()); // Use the default target triple if unspecified. if (Opts.Triple.empty()) Opts.Triple = llvm::sys::getDefaultTargetTriple(); Index: test/Driver/malign-double.c =================================================================== --- /dev/null +++ test/Driver/malign-double.c @@ -0,0 +1,22 @@ +// RUN: %clang -v -c -malign-double %s -target i686-unknown-linux 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-I686 %s + +// CHECK-I686: -cc1 +// CHECK-I686: -mllvm -malign-double +// CHECK-I686-NOT: backend data layout {{'[^']+'}} does not match expected target description {{'[^']+'}} + +// RUN: %clang -v -c -malign-double %s -target x86_64-unknown-linux 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-X86_64 %s + +// CHECK-X86_64: -cc1 +// CHECK-X86_64: -mllvm -malign-double + +// RUN: not %clang -v -c -mno-align-double %s -target i686-unknown-linux 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-NO-I686 %s + +// CHECK-NO-I686: unknown argument: '-mno-align-double' + +// RUN: not %clang -v -c -mno-align-double %s -target x86_64-unknown-linux 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-NO-X86_64 %s + +// CHECK-NO-X86_64: unknown argument: '-mno-align-double'