Skip to content

Commit 054e0f5

Browse files
damyanpCopilotgithub-actions[bot]
authored
Rename /P to /Po; make /P match cl.exe behavior (microsoft#8165)
Rename the old FXC-style /P flag to /Po (deprecated) and make /P behave like cl.exe: preprocess to <input>.i by default, with /Fi to specify the output filename. The old /Po <filename> positional syntax is preserved with a deprecation warning directing users to /P /Fi. Fixes microsoft#4611 --------- Co-authored-by: Copilot <[email protected]> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
1 parent fb14c98 commit 054e0f5

6 files changed

Lines changed: 110 additions & 48 deletions

File tree

docs/ReleaseNotes.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,14 @@ line upon naming the release. Refer to previous for appropriate section names.
4343
- Fixed mesh shader semantics that were incorrectly case sensitive.
4444
- DXIL validation now rejects non-standard integer bit widths (e.g. `i25`) in instructions.
4545

46+
#### Other Changes
47+
48+
- `/P` now matches `cl.exe` behavior: preprocesses to `<inputname>.i` by
49+
default, with `/Fi` to override the output filename. The old FXC-style `/P
50+
<filename>` positional syntax has been renamed to `/Po`.
51+
[#4611](https://github.com/microsoft/DirectXShaderCompiler/issues/4611).
52+
53+
4654
### Version 1.9.2602
4755

4856
#### Shader Model 6.9 Release

include/dxc/Support/HLSLOptions.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,8 @@ def Lx : Flag<["-", "/"], "Lx">, HelpText<"Output hexadecimal literals">, Group<
514514
// In place of 'E' for clang; fxc uses 'E' for entry point.
515515
def P : Flag<["-", "/"], "P">, Flags<[CoreOption, DriverOption]>, Group<hlslutil_Group>,
516516
HelpText<"Preprocess to file">;
517+
def Po : Flag<["-", "/"], "Po">, Flags<[CoreOption, DriverOption]>, Group<hlslutil_Group>,
518+
HelpText<"Preprocess to file (deprecated, use /P /Fi instead)">;
517519

518520
// @<file> - options response file
519521

lib/DxcSupport/HLSLOptions.cpp

Lines changed: 55 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,60 @@ LangStd parseHLSLVersion(llvm::StringRef Ver) {
399399
.Case("202x", hlsl::LangStd::v202x)
400400
.Default(hlsl::LangStd::vError);
401401
}
402+
403+
// Returns the preprocess output filename based on /P or /Po flags,
404+
// or empty string if neither is set.
405+
static std::string getPreprocessOutput(InputArgList &Args,
406+
llvm::raw_ostream &Errors) {
407+
if (Args.hasFlag(OPT_P, OPT_INVALID, false)) {
408+
// cl.exe-compatible /P: preprocess to <inputname>.i, or use /Fi to
409+
// override.
410+
llvm::SmallString<128> Path(Args.getLastArgValue(OPT_INPUT));
411+
llvm::sys::path::replace_extension(Path, "i");
412+
return Args.getLastArgValue(OPT_Fi, Path).str();
413+
}
414+
415+
if (!Args.hasFlag(OPT_Po, OPT_INVALID, false))
416+
return "";
417+
418+
// /Po: backward-compatible preprocessing (deprecated, use /P instead).
419+
// Default preprocess filename is InputName.i.
420+
llvm::SmallString<128> Path(Args.getLastArgValue(OPT_INPUT));
421+
llvm::sys::path::replace_extension(Path, "i");
422+
// Try to get preprocess filename from Fi.
423+
std::string Result = Args.getLastArgValue(OPT_Fi, Path).str();
424+
425+
// Hack to support fxc style /Po preprocess_filename.
426+
// When there're more than 1 Input file, use the input which is after /Po
427+
// as preprocess.
428+
if (!Args.hasArg(OPT_Fi)) {
429+
std::vector<std::string> Inputs = Args.getAllArgValues(OPT_INPUT);
430+
if (Inputs.size() > 1) {
431+
llvm::opt::Arg *PoArg = Args.getLastArg(OPT_Po);
432+
std::string LastInput = Inputs.back();
433+
llvm::opt::Arg *PrevInputArg = nullptr;
434+
for (llvm::opt::Arg *InputArg : Args.filtered(OPT_INPUT)) {
435+
// Find Input after /Po.
436+
if ((PoArg->getIndex() + 1) == InputArg->getIndex()) {
437+
Result = InputArg->getValue();
438+
if (LastInput == Result && PrevInputArg) {
439+
// When InputArg is last Input, update it to other Input so
440+
// Args.getLastArgValue(OPT_INPUT) get expect Input.
441+
InputArg->getValues()[0] = PrevInputArg->getValues()[0];
442+
}
443+
break;
444+
}
445+
PrevInputArg = InputArg;
446+
}
447+
}
448+
}
449+
Errors << "warning: /Po is deprecated, please use /P";
450+
if (!Result.empty() && Result != Path.str())
451+
Errors << " /Fi " << Result;
452+
Errors << " instead.\n";
453+
return Result;
454+
}
455+
402456
namespace options {
403457

404458
/// Reads all options from the given argument strings, populates opts, and
@@ -583,40 +637,7 @@ int ReadDxcOpts(const OptTable *optionTable, unsigned flagsToInclude,
583637
opts.UseInstructionNumbers = Args.hasFlag(OPT_Ni, OPT_INVALID, false);
584638
opts.UseInstructionByteOffsets = Args.hasFlag(OPT_No, OPT_INVALID, false);
585639
opts.UseHexLiterals = Args.hasFlag(OPT_Lx, OPT_INVALID, false);
586-
if (Args.hasFlag(OPT_P, OPT_INVALID, false)) {
587-
// Default preprocess filename is InputName.i.
588-
llvm::SmallString<128> Path(Args.getLastArgValue(OPT_INPUT));
589-
llvm::sys::path::replace_extension(Path, "i");
590-
// Try to get preprocess filename from Fi.
591-
opts.Preprocess = Args.getLastArgValue(OPT_Fi, Path).str();
592-
// Hack to support fxc style /P preprocess_filename.
593-
// When there're more than 1 Input file, use the input which is after /P as
594-
// preprocess.
595-
if (!Args.hasArg(OPT_Fi)) {
596-
std::vector<std::string> Inputs = Args.getAllArgValues(OPT_INPUT);
597-
if (Inputs.size() > 1) {
598-
llvm::opt::Arg *PArg = Args.getLastArg(OPT_P);
599-
std::string LastInput = Inputs.back();
600-
llvm::opt::Arg *PrevInputArg = nullptr;
601-
for (llvm::opt::Arg *InputArg : Args.filtered(OPT_INPUT)) {
602-
// Find Input after /P.
603-
if ((PArg->getIndex() + 1) == InputArg->getIndex()) {
604-
opts.Preprocess = InputArg->getValue();
605-
if (LastInput == opts.Preprocess && PrevInputArg) {
606-
// When InputArg is last Input, update it to other Input so
607-
// Args.getLastArgValue(OPT_INPUT) get expect Input.
608-
InputArg->getValues()[0] = PrevInputArg->getValues()[0];
609-
}
610-
errors << "warning: -P " << opts.Preprocess
611-
<< " is deprecated, please use -P -Fi " << opts.Preprocess
612-
<< " instead.\n";
613-
break;
614-
}
615-
PrevInputArg = InputArg;
616-
}
617-
}
618-
}
619-
}
640+
opts.Preprocess = getPreprocessOutput(Args, errors);
620641
opts.AstDumpImplicit =
621642
Args.hasFlag(OPT_ast_dump_implicit, OPT_INVALID, false);
622643
// -ast-dump-implicit should imply -ast-dump.

tools/clang/test/DXC/VersionMacro.hlsl

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,25 @@
1-
// RUN: %dxc -HV 202x %s -P %t.v202x.hlsl.pp
1+
// RUN: %dxc -HV 202x %s -P -Fi %t.v202x.hlsl.pp
22
// RUN: FileCheck --input-file=%t.v202x.hlsl.pp %s --check-prefix=LATEST
33
// LATEST: 2029
44

5-
// RUN: %dxc -HV 2016 %s -P %t.v2016.hlsl.pp
5+
// RUN: %dxc -HV 2016 %s -P -Fi %t.v2016.hlsl.pp
66
// RUN: FileCheck --input-file=%t.v2016.hlsl.pp %s --check-prefix=HV16
77
// HV16: 2016
88

9-
// RUN: %dxc -HV 2017 %s -P %t.v2017.hlsl.pp
9+
// RUN: %dxc -HV 2017 %s -P -Fi %t.v2017.hlsl.pp
1010
// RUN: FileCheck --input-file=%t.v2017.hlsl.pp %s --check-prefix=HV17
1111
// HV17: 2017
1212

13-
// RUN: %dxc -HV 2018 %s -P %t.v2018.hlsl.pp
13+
// RUN: %dxc -HV 2018 %s -P -Fi %t.v2018.hlsl.pp
1414
// RUN: FileCheck --input-file=%t.v2018.hlsl.pp %s --check-prefix=HV18
1515
// HV18: 2018
1616

17-
// RUN: %dxc -HV 2021 %s -P %t.v2021.hlsl.pp
17+
// RUN: %dxc -HV 2021 %s -P -Fi %t.v2021.hlsl.pp
1818
// RUN: FileCheck --input-file=%t.v2021.hlsl.pp %s --check-prefix=HV21
1919
// HV21: 2021
2020

2121
// Verify the default version:
22-
// RUN: %dxc %s -P %t.default.hlsl.pp
22+
// RUN: %dxc %s -P -Fi %t.default.hlsl.pp
2323
// RUN: FileCheck --input-file=%t.v2021.hlsl.pp %s --check-prefix=Default
2424
// Default: 2021
2525

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,15 @@
11

22

3-
// Preprocess
4-
// RUN: %dxc /T ps_6_0 %S/Inputs/smoke.hlsl /P %t.preprocessed.hlsl
5-
// RUN: FileCheck --input-file=%t.preprocessed.hlsl %s --check-prefix=PREPROCESSED
3+
// Preprocess with /P
4+
// The default /P output filename (<input>.i) is verified by unit tests.
5+
// RUN: %dxc /T ps_6_0 %S/Inputs/smoke.hlsl /P /Fi %t.p_output.hlsl
6+
// RUN: FileCheck --input-file=%t.p_output.hlsl %s --check-prefix=PREPROCESSED
7+
8+
// Legacy FXC-style support (always warns)
9+
// RUN: %dxc /T ps_6_0 %S/Inputs/smoke.hlsl /Po %t.po_positional.hlsl 2>&1 | FileCheck %s --check-prefix=DEPRECATED
10+
// RUN: FileCheck --input-file=%t.po_positional.hlsl %s --check-prefix=PREPROCESSED
11+
// RUN: %dxc /T ps_6_0 %S/Inputs/smoke.hlsl /Po /Fi %t.po_fi.hlsl 2>&1 | FileCheck %s --check-prefix=DEPRECATED
12+
// RUN: FileCheck --input-file=%t.po_fi.hlsl %s --check-prefix=PREPROCESSED
13+
614
// PREPROCESSED:float4 main
15+
// DEPRECATED: /Po is deprecated

tools/clang/unittests/HLSL/OptionsTest.cpp

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -418,13 +418,35 @@ static void VerifyPreprocessOption(llvm::StringRef command,
418418
}
419419

420420
TEST_F(OptionsTest, TestPreprocessOption) {
421+
// /P (cl.exe-compatible): preprocesses to <input>.i by default.
421422
VerifyPreprocessOption("/T ps_6_0 -P input.hlsl", "input.i", "");
422-
VerifyPreprocessOption("/T ps_6_0 -Fi out.pp -P input.hlsl", "out.pp", "");
423+
// /P with /Fi: preprocesses to specified file.
423424
VerifyPreprocessOption("/T ps_6_0 -P -Fi out.pp input.hlsl", "out.pp", "");
424-
const char *Warning =
425-
"warning: -P out.pp is deprecated, please use -P -Fi out.pp instead.\n";
426-
VerifyPreprocessOption("/T ps_6_0 -P out.pp input.hlsl", "out.pp", Warning);
427-
VerifyPreprocessOption("/T ps_6_0 input.hlsl -P out.pp ", "out.pp", Warning);
425+
VerifyPreprocessOption("/T ps_6_0 -Fi out.pp -P input.hlsl", "out.pp", "");
426+
// /P never emits the deprecation warning, even with positional args that
427+
// would trigger it under /Po.
428+
VerifyPreprocessOption("/T ps_6_0 -P out.pp input.hlsl", "input.i", "");
429+
VerifyPreprocessOption("/T ps_6_0 input.hlsl -P out.pp", "out.i", "");
430+
431+
// /Po always emits a deprecation warning.
432+
// Simple /Po (default output): suggests /P.
433+
const char *SimpleWarning =
434+
"warning: /Po is deprecated, please use /P instead.\n";
435+
VerifyPreprocessOption("/T ps_6_0 -Po input.hlsl", "input.i", SimpleWarning);
436+
// /Po with /Fi: suggests /P /Fi.
437+
const char *FiWarning =
438+
"warning: /Po is deprecated, please use /P /Fi out.pp instead.\n";
439+
VerifyPreprocessOption("/T ps_6_0 -Fi out.pp -Po input.hlsl", "out.pp",
440+
FiWarning);
441+
VerifyPreprocessOption("/T ps_6_0 -Po -Fi out.pp input.hlsl", "out.pp",
442+
FiWarning);
443+
// /Po with positional filename: suggests /P /Fi.
444+
const char *PositionalWarning =
445+
"warning: /Po is deprecated, please use /P /Fi out.pp instead.\n";
446+
VerifyPreprocessOption("/T ps_6_0 -Po out.pp input.hlsl", "out.pp",
447+
PositionalWarning);
448+
VerifyPreprocessOption("/T ps_6_0 input.hlsl -Po out.pp ", "out.pp",
449+
PositionalWarning);
428450
}
429451

430452
static void VerifySerializeDxilFlags(llvm::StringRef command,

0 commit comments

Comments
 (0)