Index: include/clang/Driver/Options.td =================================================================== --- include/clang/Driver/Options.td +++ include/clang/Driver/Options.td @@ -1407,6 +1407,7 @@ def mno_xsavec : Flag<["-"], "mno-xsavec">, Group; def mno_xsaves : Flag<["-"], "mno-xsaves">, Group; def mno_pku : Flag<["-"], "mno-pku">, Group; +def mseparate_stack_seg : Flag<["-"], "mseparate-stack-seg">, Group; def munaligned_access : Flag<["-"], "munaligned-access">, Group, HelpText<"Allow memory accesses to be unaligned (AArch32/AArch64 only)">; Index: lib/CodeGen/TargetInfo.cpp =================================================================== --- lib/CodeGen/TargetInfo.cpp +++ lib/CodeGen/TargetInfo.cpp @@ -1690,9 +1690,26 @@ TypeInfo.second = CharUnits::fromQuantity( getTypeStackAlignInBytes(Ty, TypeInfo.second.getQuantity())); - return emitVoidPtrVAArg(CGF, VAListAddr, Ty, /*Indirect*/ false, - TypeInfo, CharUnits::fromQuantity(4), - /*AllowHigherAlign*/ true); + const Address Addr = emitVoidPtrVAArg(CGF, VAListAddr, Ty, /*Indirect*/ false, + TypeInfo, CharUnits::fromQuantity(4), + /*AllowHigherAlign*/ true); + + const std::vector &TargetFeatures = + CGF.getTarget().getTargetOpts().Features; + if (std::find(TargetFeatures.begin(), TargetFeatures.end(), + "+separate-stack-seg") != TargetFeatures.end()) { + // Cast the pointer into the address space for the stack segment. + // This is to help support multi-segment memory models in which DS and SS + // may differ from each other. + llvm::Type *DirectTy = CGF.ConvertTypeForMem(Ty); + llvm::Value *PtrAsInt = + CGF.Builder.CreatePtrToInt(Addr.getPointer(), CGF.IntPtrTy); + llvm::Value *PtrInStackSeg = + CGF.Builder.CreateIntToPtr(PtrAsInt, DirectTy->getPointerTo(258)); + return Address(PtrInStackSeg, Addr.getAlignment()); + } + + return Addr; } bool X86_32TargetCodeGenInfo::isStructReturnInRegABI( Index: test/CodeGen/varargs.c =================================================================== --- test/CodeGen/varargs.c +++ test/CodeGen/varargs.c @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple i386-unknown-unknown -target-feature +separate-stack-seg -emit-llvm -o - %s | FileCheck -check-prefix=SEPARATE-SS %s // PR6433 - Don't crash on va_arg(typedef). typedef double gdouble; @@ -20,4 +21,5 @@ __builtin_va_list ap; void *p; p = __builtin_va_arg(ap, typeof (int (*)[++n])); // CHECK: add nsw i32 {{.*}}, 1 + // SEPARATE-SS: load i32*, i32* addrspace(258)* {{.*}} }