Skip to content

Commit 082514f

Browse files
committed
Add support for requiring Win x64 Unwind V2
1 parent ae7ea6e commit 082514f

File tree

12 files changed

+595
-43
lines changed

12 files changed

+595
-43
lines changed

clang/include/clang/Basic/CodeGenOptions.def

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -481,8 +481,10 @@ CODEGENOPT(StaticClosure, 1, 0)
481481
/// Assume that UAVs/SRVs may alias
482482
CODEGENOPT(ResMayAlias, 1, 0)
483483

484-
/// Enables unwind v2 (epilog) information for x64 Windows.
485-
CODEGENOPT(WinX64EHUnwindV2, 1, 0)
484+
/// Controls how unwind v2 (epilog) information should be generated for x64
485+
/// Windows.
486+
ENUM_CODEGENOPT(WinX64EHUnwindV2, llvm::WinX64EHUnwindV2Mode,
487+
2, llvm::WinX64EHUnwindV2Mode::Disabled)
486488

487489
/// FIXME: Make DebugOptions its own top-level .def file.
488490
#include "DebugOptions.def"

clang/include/clang/Driver/Options.td

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2167,11 +2167,14 @@ defm assume_nothrow_exception_dtor: BoolFOption<"assume-nothrow-exception-dtor",
21672167
LangOpts<"AssumeNothrowExceptionDtor">, DefaultFalse,
21682168
PosFlag<SetTrue, [], [ClangOption, CC1Option], "Assume that exception objects' destructors are non-throwing">,
21692169
NegFlag<SetFalse>>;
2170-
defm winx64_eh_unwindv2 : BoolFOption<"winx64-eh-unwindv2",
2171-
CodeGenOpts<"WinX64EHUnwindV2">, DefaultFalse,
2172-
PosFlag<SetTrue, [], [ClangOption, CC1Option], "Enable">,
2173-
NegFlag<SetFalse, [], [ClangOption], "Disable">,
2174-
BothFlags<[], [ClangOption], " unwind v2 (epilog) information for x64 Windows">>;
2170+
def winx64_eh_unwindv2
2171+
: Joined<["-"], "fwinx64-eh-unwindv2=">, Group<f_Group>,
2172+
Visibility<[ClangOption, CC1Option]>,
2173+
HelpText<"Generate unwind v2 (epilog) information for x64 Windows">,
2174+
Values<"disabled,best-effort,required">,
2175+
NormalizedValues<["Disabled", "BestEffort", "Required"]>,
2176+
NormalizedValuesScope<"llvm::WinX64EHUnwindV2Mode">,
2177+
MarshallingInfoEnum<CodeGenOpts<"WinX64EHUnwindV2">, "Disabled">;
21752178
def fexcess_precision_EQ : Joined<["-"], "fexcess-precision=">, Group<f_Group>,
21762179
Visibility<[ClangOption, CLOption]>,
21772180
HelpText<"Allows control over excess precision on targets where native "
@@ -8971,7 +8974,9 @@ def _SLASH_volatile_Group : OptionGroup<"</volatile group>">,
89718974
Group<cl_compile_Group>;
89728975

89738976
def _SLASH_d2epilogunwind : CLFlag<"d2epilogunwind">,
8974-
HelpText<"Enable unwind v2 (epilog) information for x64 Windows">;
8977+
HelpText<"Best effort generate unwind v2 (epilog) information for x64 Windows">;
8978+
def _SLASH_d2epilogunwindrequirev2 : CLFlag<"d2epilogunwindrequirev2">,
8979+
HelpText<"Require generation of unwind v2 (epilog) information for x64 Windows">;
89758980
def _SLASH_EH : CLJoined<"EH">, HelpText<"Set exception handling model">;
89768981
def _SLASH_EP : CLFlag<"EP">,
89778982
HelpText<"Disable linemarker output and preprocess to stdout">;

clang/lib/CodeGen/CodeGenModule.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1314,8 +1314,10 @@ void CodeGenModule::Release() {
13141314
1);
13151315

13161316
// Enable unwind v2 (epilog).
1317-
if (CodeGenOpts.WinX64EHUnwindV2)
1318-
getModule().addModuleFlag(llvm::Module::Warning, "winx64-eh-unwindv2", 1);
1317+
if (CodeGenOpts.getWinX64EHUnwindV2() != llvm::WinX64EHUnwindV2Mode::Disabled)
1318+
getModule().addModuleFlag(
1319+
llvm::Module::Warning, "winx64-eh-unwindv2",
1320+
static_cast<unsigned>(CodeGenOpts.getWinX64EHUnwindV2()));
13191321

13201322
// Indicate whether this Module was compiled with -fopenmp
13211323
if (getLangOpts().OpenMP && !getLangOpts().OpenMPSimd)

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7352,8 +7352,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
73527352
}
73537353

73547354
// Unwind v2 (epilog) information for x64 Windows.
7355-
Args.addOptInFlag(CmdArgs, options::OPT_fwinx64_eh_unwindv2,
7356-
options::OPT_fno_winx64_eh_unwindv2);
7355+
Args.AddLastArg(CmdArgs, options::OPT_winx64_eh_unwindv2);
73577356

73587357
// C++ "sane" operator new.
73597358
Args.addOptOutFlag(CmdArgs, options::OPT_fassume_sane_operator_new,
@@ -8410,8 +8409,10 @@ void Clang::AddClangCLArgs(const ArgList &Args, types::ID InputType,
84108409
CmdArgs.push_back("-fms-kernel");
84118410

84128411
// Unwind v2 (epilog) information for x64 Windows.
8413-
if (Args.hasArg(options::OPT__SLASH_d2epilogunwind))
8414-
CmdArgs.push_back("-fwinx64-eh-unwindv2");
8412+
if (Args.hasArg(options::OPT__SLASH_d2epilogunwindrequirev2))
8413+
CmdArgs.push_back("-fwinx64-eh-unwindv2=required");
8414+
else if (Args.hasArg(options::OPT__SLASH_d2epilogunwind))
8415+
CmdArgs.push_back("-fwinx64-eh-unwindv2=best-effort");
84158416

84168417
for (const Arg *A : Args.filtered(options::OPT__SLASH_guard)) {
84178418
StringRef GuardArgs = A->getValue();

clang/test/CodeGen/epilog-unwind.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s -check-prefix=DISABLED
2-
// RUN: %clang_cc1 -fwinx64-eh-unwindv2 -emit-llvm %s -o - | FileCheck %s -check-prefix=ENABLED
3-
// RUN: %clang -fwinx64-eh-unwindv2 -S -emit-llvm %s -o - | FileCheck %s -check-prefix=ENABLED
4-
// RUN: %clang -fno-winx64-eh-unwindv2 -S -emit-llvm %s -o - | FileCheck %s -check-prefix=DISABLED
2+
// RUN: %clang_cc1 -fwinx64-eh-unwindv2=disabled -emit-llvm %s -o - | FileCheck %s -check-prefix=DISABLED
3+
// RUN: %clang_cc1 -fwinx64-eh-unwindv2=best-effort -emit-llvm %s -o - | FileCheck %s -check-prefix=BESTEFFORT
4+
// RUN: %clang_cc1 -fwinx64-eh-unwindv2=required -emit-llvm %s -o - | FileCheck %s -check-prefix=REQUIRED
5+
// RUN: %clang -fwinx64-eh-unwindv2=best-effort -S -emit-llvm %s -o - | FileCheck %s -check-prefix=BESTEFFORT
56

67
void f(void) {}
78

8-
// ENABLED: !"winx64-eh-unwindv2", i32 1}
9+
// BESTEFFORT: !"winx64-eh-unwindv2", i32 1}
10+
// REQUIRED: !"winx64-eh-unwindv2", i32 2}
911
// DISABLED-NOT: "winx64-eh-unwindv2"

clang/test/Driver/cl-options.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -821,7 +821,11 @@
821821
// ARM64EC_OVERRIDE: warning: /arm64EC has been overridden by specified target: x86_64-pc-windows-msvc; option ignored
822822

823823
// RUN: %clang_cl /d2epilogunwind /c -### -- %s 2>&1 | FileCheck %s --check-prefix=EPILOGUNWIND
824-
// EPILOGUNWIND: -fwinx64-eh-unwindv2
824+
// EPILOGUNWIND: -fwinx64-eh-unwindv2=best-effort
825+
826+
// RUN: %clang_cl /d2epilogunwindrequirev2 /c -### -- %s 2>&1 | FileCheck %s --check-prefix=EPILOGUNWINDREQUIREV2
827+
// RUN: %clang_cl /d2epilogunwindrequirev2 /d2epilogunwind /c -### -- %s 2>&1 | FileCheck %s --check-prefix=EPILOGUNWINDREQUIREV2
828+
// EPILOGUNWINDREQUIREV2: -fwinx64-eh-unwindv2=require
825829

826830
// RUN: %clang_cl /funcoverride:override_me1 /funcoverride:override_me2 /c -### -- %s 2>&1 | FileCheck %s --check-prefix=FUNCOVERRIDE
827831
// FUNCOVERRIDE: -loader-replaceable-function=override_me1

llvm/include/llvm/IR/Module.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1041,6 +1041,10 @@ class LLVM_ABI Module {
10411041

10421042
/// Returns target-abi from MDString, null if target-abi is absent.
10431043
StringRef getTargetABIFromMD();
1044+
1045+
/// Get how unwind v2 (epilog) information should be generated for x64
1046+
/// Windows.
1047+
WinX64EHUnwindV2Mode getWinX64EHUnwindV2Mode() const;
10441048
};
10451049

10461050
/// Given "llvm.used" or "llvm.compiler.used" as a global name, collect the

llvm/include/llvm/Support/CodeGen.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,15 @@ namespace llvm {
130130
Invalid = 2, ///< Not used.
131131
};
132132

133+
enum class WinX64EHUnwindV2Mode {
134+
// Don't use unwind v2 (i.e., use v1).
135+
Disabled = 0,
136+
// Use unwind v2 here possible, otherwise fallback to v1.
137+
BestEffort = 1,
138+
// Use unwind v2 everywhere, otherwise raise an error.
139+
Required = 2,
140+
};
141+
133142
} // namespace llvm
134143

135144
#endif

llvm/lib/IR/Module.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -917,3 +917,10 @@ StringRef Module::getTargetABIFromMD() {
917917
TargetABI = TargetABIMD->getString();
918918
return TargetABI;
919919
}
920+
921+
WinX64EHUnwindV2Mode Module::getWinX64EHUnwindV2Mode() const {
922+
Metadata *MD = getModuleFlag("winx64-eh-unwindv2");
923+
if (auto *CI = mdconst::dyn_extract_or_null<ConstantInt>(MD))
924+
return static_cast<WinX64EHUnwindV2Mode>(CI->getZExtValue());
925+
return WinX64EHUnwindV2Mode::Disabled;
926+
}

0 commit comments

Comments
 (0)