diff --git a/clang/lib/Basic/Targets/X86.h b/clang/lib/Basic/Targets/X86.h --- a/clang/lib/Basic/Targets/X86.h +++ b/clang/lib/Basic/Targets/X86.h @@ -661,7 +661,7 @@ public: X86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) : X86TargetInfo(Triple, Opts) { - const bool IsX32 = getTriple().getEnvironment() == llvm::Triple::GNUX32; + const bool IsX32 = getTriple().isX32(); bool IsWinCOFF = getTriple().isOSWindows() && getTriple().isOSBinFormatCOFF(); LongWidth = LongAlign = PointerWidth = PointerAlign = IsX32 ? 32 : 64; diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -519,14 +519,21 @@ AT = Target.get64BitArchVariant().getArch(); if (Target.getEnvironment() == llvm::Triple::GNUX32) Target.setEnvironment(llvm::Triple::GNU); + else if (Target.getEnvironment() == llvm::Triple::MuslX32) + Target.setEnvironment(llvm::Triple::Musl); } else if (A->getOption().matches(options::OPT_mx32) && Target.get64BitArchVariant().getArch() == llvm::Triple::x86_64) { AT = llvm::Triple::x86_64; - Target.setEnvironment(llvm::Triple::GNUX32); + if (Target.getEnvironment() == llvm::Triple::Musl) + Target.setEnvironment(llvm::Triple::MuslX32); + else + Target.setEnvironment(llvm::Triple::GNUX32); } else if (A->getOption().matches(options::OPT_m32)) { AT = Target.get32BitArchVariant().getArch(); if (Target.getEnvironment() == llvm::Triple::GNUX32) Target.setEnvironment(llvm::Triple::GNU); + else if (Target.getEnvironment() == llvm::Triple::MuslX32) + Target.setEnvironment(llvm::Triple::Musl); } else if (A->getOption().matches(options::OPT_m16) && Target.get32BitArchVariant().getArch() == llvm::Triple::x86) { AT = llvm::Triple::x86; diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp b/clang/lib/Driver/ToolChains/Gnu.cpp --- a/clang/lib/Driver/ToolChains/Gnu.cpp +++ b/clang/lib/Driver/ToolChains/Gnu.cpp @@ -294,7 +294,7 @@ case llvm::Triple::systemz: return "elf64_s390"; case llvm::Triple::x86_64: - if (T.getEnvironment() == llvm::Triple::GNUX32) + if (T.isX32()) return "elf32_x86_64"; return "elf_x86_64"; case llvm::Triple::ve: @@ -725,7 +725,7 @@ CmdArgs.push_back("--32"); break; case llvm::Triple::x86_64: - if (getToolChain().getTriple().getEnvironment() == llvm::Triple::GNUX32) + if (getToolChain().getTriple().isX32()) CmdArgs.push_back("--x32"); else CmdArgs.push_back("--64"); @@ -1733,7 +1733,7 @@ // Determine default multilib from: 32, 64, x32 // Also handle cases such as 64 on 32, 32 on 64, etc. enum { UNKNOWN, WANT32, WANT64, WANTX32 } Want = UNKNOWN; - const bool IsX32 = TargetTriple.getEnvironment() == llvm::Triple::GNUX32; + const bool IsX32 = TargetTriple.isX32(); if (TargetTriple.isArch32Bit() && !NonExistent(Alt32)) Want = WANT64; else if (TargetTriple.isArch64Bit() && IsX32 && !NonExistent(Altx32)) @@ -2339,7 +2339,7 @@ TripleAliases.append(begin(AVRTriples), end(AVRTriples)); break; case llvm::Triple::x86_64: - if (TargetTriple.getEnvironment() == llvm::Triple::GNUX32) { + if (TargetTriple.isX32()) { LibDirs.append(begin(X32LibDirs), end(X32LibDirs)); TripleAliases.append(begin(X32Triples), end(X32Triples)); BiarchLibDirs.append(begin(X86_64LibDirs), end(X86_64LibDirs)); diff --git a/clang/lib/Driver/ToolChains/Linux.cpp b/clang/lib/Driver/ToolChains/Linux.cpp --- a/clang/lib/Driver/ToolChains/Linux.cpp +++ b/clang/lib/Driver/ToolChains/Linux.cpp @@ -166,8 +166,7 @@ Triple.getArch() == llvm::Triple::sparc) return "lib32"; - if (Triple.getArch() == llvm::Triple::x86_64 && - Triple.getEnvironment() == llvm::Triple::GNUX32) + if (Triple.getArch() == llvm::Triple::x86_64 && Triple.isX32()) return "libx32"; if (Triple.getArch() == llvm::Triple::riscv32) @@ -402,9 +401,7 @@ ArchName = "i386"; break; case llvm::Triple::x86_64: - ArchName = Triple.getEnvironment() == llvm::Triple::MuslX32 - ? "x32" - : Triple.getArchName().str(); + ArchName = Triple.isX32() ? "x32" : Triple.getArchName().str(); break; default: ArchName = Triple.getArchName().str(); @@ -515,7 +512,7 @@ Loader = "ld-linux.so.2"; break; case llvm::Triple::x86_64: { - bool X32 = Triple.getEnvironment() == llvm::Triple::GNUX32; + bool X32 = Triple.isX32(); LibDir = X32 ? "libx32" : "lib64"; Loader = X32 ? "ld-linux-x32.so.2" : "ld-linux-x86-64.so.2"; diff --git a/clang/test/Driver/linux-cross.cpp b/clang/test/Driver/linux-cross.cpp --- a/clang/test/Driver/linux-cross.cpp +++ b/clang/test/Driver/linux-cross.cpp @@ -136,4 +136,6 @@ // RUN: %clang -### %s --target=x86_64-linux-muslx32 --sysroot= \ // RUN: --stdlib=platform --rtlib=platform 2>&1 | FileCheck %s --check-prefix=MUSL_X32 +// RUN: %clang -### %s --target=i686-linux-musl -mx32 --sysroot= \ +// RUN: --stdlib=platform --rtlib=platform 2>&1 | FileCheck %s --check-prefix=MUSL_X32 // MUSL_X32: "-dynamic-linker" "/lib/ld-musl-x32.so.1" diff --git a/llvm/include/llvm/ADT/Triple.h b/llvm/include/llvm/ADT/Triple.h --- a/llvm/include/llvm/ADT/Triple.h +++ b/llvm/include/llvm/ADT/Triple.h @@ -805,6 +805,12 @@ getSubArch() == Triple::AArch64SubArch_arm64e; } + /// Tests whether the target is X32. + bool isX32() const { + EnvironmentType Env = getEnvironment(); + return Env == Triple::GNUX32 || Env == Triple::MuslX32; + } + /// Tests whether the target supports comdat bool supportsCOMDAT() const { return !(isOSBinFormatMachO() || isOSBinFormatXCOFF()); diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp --- a/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp +++ b/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp @@ -1631,7 +1631,7 @@ uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TheTriple.getOS()); - if (TheTriple.getEnvironment() == Triple::GNUX32) + if (TheTriple.isX32()) return new ELFX86_X32AsmBackend(T, OSABI, STI); return new ELFX86_64AsmBackend(T, OSABI, STI); } diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86MCAsmInfo.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86MCAsmInfo.cpp --- a/llvm/lib/Target/X86/MCTargetDesc/X86MCAsmInfo.cpp +++ b/llvm/lib/Target/X86/MCTargetDesc/X86MCAsmInfo.cpp @@ -81,7 +81,7 @@ X86ELFMCAsmInfo::X86ELFMCAsmInfo(const Triple &T) { bool is64Bit = T.getArch() == Triple::x86_64; - bool isX32 = T.getEnvironment() == Triple::GNUX32; + bool isX32 = T.isX32(); // For ELF, x86-64 pointer size depends on the ABI. // For x86-64 without the x32 ABI, pointer size is 8. For x86 and for x86-64 diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp --- a/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp +++ b/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp @@ -1231,8 +1231,7 @@ // FIXME: The caller of determineREXPrefix slaps this prefix onto // anything that returns non-zero. REX |= 0x40; // REX fixed encoding prefix - } else if (MO.isExpr() && - STI.getTargetTriple().getEnvironment() == Triple::GNUX32) { + } else if (MO.isExpr() && STI.getTargetTriple().isX32()) { // GOTTPOFF and TLSDESC relocations require a REX prefix to allow // linker optimizations: even if the instructions we see may not require // any prefix, they may be replaced by instructions that do. This is diff --git a/llvm/lib/Target/X86/X86AsmPrinter.cpp b/llvm/lib/Target/X86/X86AsmPrinter.cpp --- a/llvm/lib/Target/X86/X86AsmPrinter.cpp +++ b/llvm/lib/Target/X86/X86AsmPrinter.cpp @@ -643,8 +643,7 @@ OutStreamer->SwitchSection(Nt); // Emitting note header. - const int WordSize = - TT.isArch64Bit() && TT.getEnvironment() != Triple::GNUX32 ? 8 : 4; + const int WordSize = TT.isArch64Bit() && !TT.isX32() ? 8 : 4; emitAlignment(WordSize == 4 ? Align(4) : Align(8)); OutStreamer->emitIntValue(4, 4 /*size*/); // data size for "GNU\0" OutStreamer->emitIntValue(8 + WordSize, 4 /*size*/); // Elf_Prop size diff --git a/llvm/lib/Target/X86/X86RegisterInfo.cpp b/llvm/lib/Target/X86/X86RegisterInfo.cpp --- a/llvm/lib/Target/X86/X86RegisterInfo.cpp +++ b/llvm/lib/Target/X86/X86RegisterInfo.cpp @@ -62,7 +62,7 @@ // This matches the simplified 32-bit pointer code in the data layout // computation. // FIXME: Should use the data layout? - bool Use64BitReg = TT.getEnvironment() != Triple::GNUX32; + bool Use64BitReg = !TT.isX32(); StackPtr = Use64BitReg ? X86::RSP : X86::ESP; FramePtr = Use64BitReg ? X86::RBP : X86::EBP; BasePtr = Use64BitReg ? X86::RBX : X86::EBX; diff --git a/llvm/lib/Target/X86/X86Subtarget.h b/llvm/lib/Target/X86/X86Subtarget.h --- a/llvm/lib/Target/X86/X86Subtarget.h +++ b/llvm/lib/Target/X86/X86Subtarget.h @@ -610,14 +610,12 @@ /// Is this x86_64 with the ILP32 programming model (x32 ABI)? bool isTarget64BitILP32() const { - return In64BitMode && (TargetTriple.getEnvironment() == Triple::GNUX32 || - TargetTriple.isOSNaCl()); + return In64BitMode && (TargetTriple.isX32() || TargetTriple.isOSNaCl()); } /// Is this x86_64 with the LP64 programming model (standard AMD64, no x32)? bool isTarget64BitLP64() const { - return In64BitMode && (TargetTriple.getEnvironment() != Triple::GNUX32 && - !TargetTriple.isOSNaCl()); + return In64BitMode && (!TargetTriple.isX32() && !TargetTriple.isOSNaCl()); } PICStyles::Style getPICStyle() const { return PICStyle; } diff --git a/llvm/lib/Target/X86/X86TargetMachine.cpp b/llvm/lib/Target/X86/X86TargetMachine.cpp --- a/llvm/lib/Target/X86/X86TargetMachine.cpp +++ b/llvm/lib/Target/X86/X86TargetMachine.cpp @@ -110,9 +110,7 @@ Ret += DataLayout::getManglingComponent(TT); // X86 and x32 have 32 bit pointers. - if ((TT.isArch64Bit() && - (TT.getEnvironment() == Triple::GNUX32 || TT.isOSNaCl())) || - !TT.isArch64Bit()) + if (!TT.isArch64Bit() || TT.isX32() || TT.isOSNaCl()) Ret += "-p:32:32"; // Address spaces for 32 bit signed, 32 bit unsigned, and 64 bit pointers. diff --git a/llvm/test/CodeGen/X86/x32-lea-1.ll b/llvm/test/CodeGen/X86/x32-lea-1.ll --- a/llvm/test/CodeGen/X86/x32-lea-1.ll +++ b/llvm/test/CodeGen/X86/x32-lea-1.ll @@ -1,5 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ; RUN: llc < %s -mtriple=x86_64-linux-gnux32 -O0 | FileCheck %s +; RUN: llc < %s -mtriple=x86_64-linux-muslx32 -O0 | FileCheck %s define void @foo(i32** %p) { ; CHECK-LABEL: foo: