diff --git a/llvm/include/llvm/ADT/Triple.h b/llvm/include/llvm/ADT/Triple.h index d163ac7bd77e2db8740e9d0d464d480db4b5d52e..c89cf4dc2f35f1755201fd2ed255f32696ed83fb 100644 --- a/llvm/include/llvm/ADT/Triple.h +++ b/llvm/include/llvm/ADT/Triple.h @@ -523,6 +523,16 @@ public: return getOS() == Triple::Linux; } + /// Tests whether the OS is kFreeBSD. + bool isOSKFreeBSD() const { + return getOS() == Triple::KFreeBSD; + } + + /// Tests whether the OS uses glibc. + bool isOSGlibc() const { + return getOS() == Triple::Linux || getOS() == Triple::KFreeBSD; + } + /// Tests whether the OS uses the ELF binary format. bool isOSBinFormatELF() const { return getObjectFormat() == Triple::ELF; diff --git a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp index 4fa7a0fccc0c57d8da21857b310751b9bb0f21ad..a565a48b5f4633a1b3aa91e9ceac77386af88a8b 100644 --- a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp +++ b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp @@ -719,7 +719,7 @@ bool X86DAGToDAGISel::matchLoadInAddress(LoadSDNode *N, X86ISelAddressMode &AM){ // For more information see http://people.redhat.com/drepper/tls.pdf if (ConstantSDNode *C = dyn_cast(Address)) if (C->getSExtValue() == 0 && AM.Segment.getNode() == nullptr && - Subtarget->isTargetLinux()) + Subtarget->isTargetGlibc()) switch (N->getPointerInfo().getAddrSpace()) { case 256: AM.Segment = CurDAG->getRegister(X86::GS, MVT::i16); diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index d3457ed841f5bf9bb100ae7d3bc52b2c42df24a1..eeaffe9609a8f48a452221363ac0a342560ee48f 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -1919,7 +1919,9 @@ unsigned X86TargetLowering::getAddressSpace() const { } Value *X86TargetLowering::getIRStackGuard(IRBuilder<> &IRB) const { - if (!Subtarget.isTargetLinux()) + // glibc has a special slot for the stack guard in tcbhead_t, use it instead + // of the usual global variable (see sysdeps/{i386,x86_64}/nptl/tls.h) + if (!Subtarget.isTargetGlibc()) return TargetLowering::getIRStackGuard(IRB); // %fs:0x28, unless we're using a Kernel code model, in which case it's %gs: @@ -1932,7 +1934,7 @@ Value *X86TargetLowering::getIRStackGuard(IRBuilder<> &IRB) const { } void X86TargetLowering::insertSSPDeclarations(Module &M) const { - if (!Subtarget.isTargetLinux()) + if (!Subtarget.isTargetGlibc()) TargetLowering::insertSSPDeclarations(M); } diff --git a/llvm/lib/Target/X86/X86Subtarget.cpp b/llvm/lib/Target/X86/X86Subtarget.cpp index ad7c2578aa953d7a41c39d4131a9f7f61069cf95..896856c3489a7f8e4e3ebad12b45b5d4af8d968c 100644 --- a/llvm/lib/Target/X86/X86Subtarget.cpp +++ b/llvm/lib/Target/X86/X86Subtarget.cpp @@ -262,12 +262,12 @@ void X86Subtarget::initSubtargetFeatures(StringRef CPU, StringRef FS) { assert((!In64BitMode || HasX86_64) && "64-bit code requested on a subtarget that doesn't support it!"); - // Stack alignment is 16 bytes on Darwin, Linux and Solaris (both + // Stack alignment is 16 bytes on Darwin, Linux, kFreeBSD and Solaris (both // 32 and 64 bit) and for all 64-bit targets. if (StackAlignOverride) stackAlignment = StackAlignOverride; else if (isTargetDarwin() || isTargetLinux() || isTargetSolaris() || - In64BitMode) + isTargetKFreeBSD() || In64BitMode) stackAlignment = 16; } diff --git a/llvm/lib/Target/X86/X86Subtarget.h b/llvm/lib/Target/X86/X86Subtarget.h index 6ffbde2720a45345353735f48b2e59bf7060d78a..d8cf98b6e2acf5843852b39f8cc1c827c8fa18ce 100644 --- a/llvm/lib/Target/X86/X86Subtarget.h +++ b/llvm/lib/Target/X86/X86Subtarget.h @@ -467,6 +467,8 @@ public: bool isTargetMachO() const { return TargetTriple.isOSBinFormatMachO(); } bool isTargetLinux() const { return TargetTriple.isOSLinux(); } + bool isTargetKFreeBSD() const { return TargetTriple.isOSKFreeBSD(); } + bool isTargetGlibc() const { return TargetTriple.isOSGlibc(); } bool isTargetAndroid() const { return TargetTriple.isAndroid(); } bool isTargetNaCl() const { return TargetTriple.isOSNaCl(); } bool isTargetNaCl32() const { return isTargetNaCl() && !is64Bit(); } diff --git a/llvm/test/CodeGen/X86/stack-align2.ll b/llvm/test/CodeGen/X86/stack-align2.ll index 18cce7266d13cd582134e965a314c8677007a70a..7239198000c99bd0ee03481bd9310c9816d02d1e 100644 --- a/llvm/test/CodeGen/X86/stack-align2.ll +++ b/llvm/test/CodeGen/X86/stack-align2.ll @@ -1,7 +1,9 @@ ; RUN: llc < %s -mcpu=generic -mtriple=i386-linux | FileCheck %s -check-prefix=LINUX-I386 +; RUN: llc < %s -mcpu=generic -mtriple=i386-kfreebsd | FileCheck %s -check-prefix=KFREEBSD-I386 ; RUN: llc < %s -mcpu=generic -mtriple=i386-netbsd | FileCheck %s -check-prefix=NETBSD-I386 ; RUN: llc < %s -mcpu=generic -mtriple=i686-apple-darwin8 | FileCheck %s -check-prefix=DARWIN-I386 ; RUN: llc < %s -mcpu=generic -mtriple=x86_64-linux | FileCheck %s -check-prefix=LINUX-X86_64 +; RUN: llc < %s -mcpu=generic -mtriple=x86_64-kfreebsd | FileCheck %s -check-prefix=KFREEBSD-X86_64 ; RUN: llc < %s -mcpu=generic -mtriple=x86_64-netbsd | FileCheck %s -check-prefix=NETBSD-X86_64 ; RUN: llc < %s -mcpu=generic -mtriple=x86_64-apple-darwin8 | FileCheck %s -check-prefix=DARWIN-X86_64 @@ -11,6 +13,7 @@ entry: ret i32 0 ; LINUX-I386: subl $12, %esp +; KFREEBSD-I386: subl $12, %esp ; DARWIN-I386: subl $12, %esp ; NETBSD-I386-NOT: subl {{.*}}, %esp @@ -20,6 +23,8 @@ entry: ; DARWIN-X86_64-NOT: subq {{.*}}, %rsp ; NETBSD-X86_64: pushq %{{.*}} ; NETBSD-X86_64-NOT: subq {{.*}}, %rsp +; KFREEBSD-X86_64: pushq %{{.*}} +; KFREEBSD-X86_64-NOT: subq {{.*}}, %rsp } declare void @test2() diff --git a/llvm/test/CodeGen/X86/stack-protector-target.ll b/llvm/test/CodeGen/X86/stack-protector-target.ll index 3f69bfd7e7b4342871f5caa33cf875286b41cd34..66e45055b2b51f78299449a65421e70fa4237be4 100644 --- a/llvm/test/CodeGen/X86/stack-protector-target.ll +++ b/llvm/test/CodeGen/X86/stack-protector-target.ll @@ -3,6 +3,8 @@ ; RUN: llc -mtriple=x86_64-linux < %s -o - | FileCheck --check-prefix=LINUX-X64 %s ; RUN: llc -mtriple=i386-linux-android < %s -o - | FileCheck --check-prefix=LINUX-I386 %s ; RUN: llc -mtriple=x86_64-linux-android < %s -o - | FileCheck --check-prefix=LINUX-X64 %s +; RUN: llc -mtriple=i386-kfreebsd < %s -o - | FileCheck --check-prefix=LINUX-I386 %s +; RUN: llc -mtriple=x86_64-kfreebsd < %s -o - | FileCheck --check-prefix=LINUX-X64 %s define void @_Z1fv() sspreq { entry: