Skip to content

Commit 0739031

Browse files
committed
Add support for requiring Win x64 Unwind V2
1 parent 6f6dc9c commit 0739031

File tree

11 files changed

+501
-43
lines changed

11 files changed

+501
-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 "
@@ -8968,7 +8971,9 @@ def _SLASH_volatile_Group : OptionGroup<"</volatile group>">,
89688971
Group<cl_compile_Group>;
89698972

89708973
def _SLASH_d2epilogunwind : CLFlag<"d2epilogunwind">,
8971-
HelpText<"Enable unwind v2 (epilog) information for x64 Windows">;
8974+
HelpText<"Best effort generate unwind v2 (epilog) information for x64 Windows">;
8975+
def _SLASH_d2epilogunwindrequirev2 : CLFlag<"d2epilogunwindrequirev2">,
8976+
HelpText<"Require generation of unwind v2 (epilog) information for x64 Windows">;
89728977
def _SLASH_EH : CLJoined<"EH">, HelpText<"Set exception handling model">;
89738978
def _SLASH_EP : CLFlag<"EP">,
89748979
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
@@ -7471,8 +7471,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
74717471
}
74727472

74737473
// Unwind v2 (epilog) information for x64 Windows.
7474-
Args.addOptInFlag(CmdArgs, options::OPT_fwinx64_eh_unwindv2,
7475-
options::OPT_fno_winx64_eh_unwindv2);
7474+
Args.AddLastArg(CmdArgs, options::OPT_winx64_eh_unwindv2);
74767475

74777476
// C++ "sane" operator new.
74787477
Args.addOptOutFlag(CmdArgs, options::OPT_fassume_sane_operator_new,
@@ -8529,8 +8528,10 @@ void Clang::AddClangCLArgs(const ArgList &Args, types::ID InputType,
85298528
CmdArgs.push_back("-fms-kernel");
85308529

85318530
// Unwind v2 (epilog) information for x64 Windows.
8532-
if (Args.hasArg(options::OPT__SLASH_d2epilogunwind))
8533-
CmdArgs.push_back("-fwinx64-eh-unwindv2");
8531+
if (Args.hasArg(options::OPT__SLASH_d2epilogunwindrequirev2))
8532+
CmdArgs.push_back("-fwinx64-eh-unwindv2=required");
8533+
else if (Args.hasArg(options::OPT__SLASH_d2epilogunwind))
8534+
CmdArgs.push_back("-fwinx64-eh-unwindv2=best-effort");
85348535

85358536
for (const Arg *A : Args.filtered(options::OPT__SLASH_guard)) {
85368537
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
@@ -1061,6 +1061,10 @@ class LLVM_ABI Module {
10611061

10621062
/// Returns target-abi from MDString, null if target-abi is absent.
10631063
StringRef getTargetABIFromMD();
1064+
1065+
/// Get how unwind v2 (epilog) information should be generated for x64
1066+
/// Windows.
1067+
WinX64EHUnwindV2Mode getWinX64EHUnwindV2Mode() const;
10641068
};
10651069

10661070
/// 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
@@ -919,3 +919,10 @@ StringRef Module::getTargetABIFromMD() {
919919
TargetABI = TargetABIMD->getString();
920920
return TargetABI;
921921
}
922+
923+
WinX64EHUnwindV2Mode Module::getWinX64EHUnwindV2Mode() const {
924+
Metadata *MD = getModuleFlag("winx64-eh-unwindv2");
925+
if (auto *CI = mdconst::dyn_extract_or_null<ConstantInt>(MD))
926+
return static_cast<WinX64EHUnwindV2Mode>(CI->getZExtValue());
927+
return WinX64EHUnwindV2Mode::Disabled;
928+
}

0 commit comments

Comments
 (0)