diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -6402,6 +6402,9 @@ class CLFlag : Option<["/", "-"], name, KIND_FLAG>, Group, Flags<[CLOption, NoXarchOption]>; +class CLDXCFlag : Option<["/", "-"], name, KIND_FLAG>, + Group, Flags<[CLDXCOption, NoXarchOption]>; + class CLCompileFlag : Option<["/", "-"], name, KIND_FLAG>, Group, Flags<[CLOption, NoXarchOption]>; @@ -6411,6 +6414,9 @@ class CLJoined : Option<["/", "-"], name, KIND_JOINED>, Group, Flags<[CLOption, NoXarchOption]>; +class CLDXCJoined : Option<["/", "-"], name, KIND_JOINED>, + Group, Flags<[CLDXCOption, NoXarchOption]>; + class CLCompileJoined : Option<["/", "-"], name, KIND_JOINED>, Group, Flags<[CLOption, NoXarchOption]>; @@ -6507,7 +6513,7 @@ // The _SLASH_O option handles all the /O flags, but we also provide separate // aliased options to provide separate help messages. -def _SLASH_O : CLJoined<"O">, +def _SLASH_O : CLDXCJoined<"O">, HelpText<"Set multiple /O flags at once; e.g. '/O2y-' for '/O2 /Oy-'">, MetaVarName<"">; def : CLFlag<"O1">, Alias<_SLASH_O>, AliasArgs<["1"]>, @@ -6520,7 +6526,7 @@ HelpText<"Only inline functions explicitly or implicitly marked inline">; def : CLFlag<"Ob2">, Alias<_SLASH_O>, AliasArgs<["b2"]>, HelpText<"Inline functions as deemed beneficial by the compiler">; -def : CLFlag<"Od">, Alias<_SLASH_O>, AliasArgs<["d"]>, +def : CLDXCFlag<"Od">, Alias<_SLASH_O>, AliasArgs<["d"]>, HelpText<"Disable optimization">; def : CLFlag<"Og">, Alias<_SLASH_O>, AliasArgs<["g"]>, HelpText<"No effect">; @@ -6932,6 +6938,7 @@ "as_6_5, as_6_6, as_6_7">; def dxc_D : Option<["--", "/", "-"], "D", KIND_JOINED_OR_SEPARATE>, Group, Flags<[DXCOption, NoXarchOption]>, Alias; + def emit_pristine_llvm : DXCFlag<"emit-pristine-llvm">, HelpText<"Emit pristine LLVM IR from the frontend by not running any LLVM passes at all." "Same as -S + -emit-llvm + -disable-llvm-passes.">; diff --git a/clang/lib/CodeGen/CGHLSLRuntime.cpp b/clang/lib/CodeGen/CGHLSLRuntime.cpp --- a/clang/lib/CodeGen/CGHLSLRuntime.cpp +++ b/clang/lib/CodeGen/CGHLSLRuntime.cpp @@ -46,6 +46,11 @@ auto *DXILValMD = M.getOrInsertNamedMetadata(DXILValKey); DXILValMD->addOperand(Val); } +void addDisableOptimizations(llvm::Module &M) { + StringRef Key = "dx.disable_optimizations"; + M.addModuleFlag(llvm::Module::ModFlagBehavior::Override, Key, 1); +} + } // namespace void CGHLSLRuntime::finishCodeGen() { @@ -56,6 +61,8 @@ addDxilValVersion(TargetOpts.DxilValidatorVersion, M); generateGlobalCtorCalls(); + if (CGM.getCodeGenOpts().OptimizationLevel == 0) + addDisableOptimizations(M); } void CGHLSLRuntime::annotateHLSLResource(const VarDecl *D, GlobalVariable *GV) { diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -3520,6 +3520,7 @@ options::OPT_D, options::OPT_I, options::OPT_S, + options::OPT_O, options::OPT_emit_llvm, options::OPT_emit_obj, options::OPT_disable_llvm_passes, diff --git a/clang/lib/Driver/ToolChains/HLSL.cpp b/clang/lib/Driver/ToolChains/HLSL.cpp --- a/clang/lib/Driver/ToolChains/HLSL.cpp +++ b/clang/lib/Driver/ToolChains/HLSL.cpp @@ -164,6 +164,18 @@ A->claim(); continue; } + if (A->getOption().getID() == options::OPT__SLASH_O) { + StringRef OStr = A->getValue(); + if (OStr == "d") { + DAL->AddFlagArg(nullptr, Opts.getOption(options::OPT_O0)); + A->claim(); + continue; + } else { + DAL->AddJoinedArg(nullptr, Opts.getOption(options::OPT_O), OStr); + A->claim(); + continue; + } + } if (A->getOption().getID() == options::OPT_emit_pristine_llvm) { // Translate fcgl into -S -emit-llvm and -disable-llvm-passes. DAL->AddFlagArg(nullptr, Opts.getOption(options::OPT_S)); @@ -192,6 +204,9 @@ Opts.getOption(options::OPT_dxil_validator_version), DefaultValidatorVer); } + if (!DAL->hasArg(options::OPT_O_Group)) { + DAL->AddJoinedArg(nullptr, Opts.getOption(options::OPT_O), "3"); + } // FIXME: add validation for enable_16bit_types should be after HLSL 2018 and // shader model 6.2. return DAL; diff --git a/clang/test/CodeGenHLSL/disable_opt.hlsl b/clang/test/CodeGenHLSL/disable_opt.hlsl new file mode 100644 --- /dev/null +++ b/clang/test/CodeGenHLSL/disable_opt.hlsl @@ -0,0 +1,12 @@ +// RUN: %clang -cc1 -S -triple dxil-pc-shadermodel6.3-library -O0 -emit-llvm -xhlsl -o - %s | FileCheck %s +// RUN: %clang -cc1 -S -triple dxil-pc-shadermodel6.3-library -O3 -emit-llvm -xhlsl -o - %s | FileCheck %s --check-prefix=OPT + +// CHECK:!"dx.disable_optimizations", i32 1} + +// OPT-NOT:"dx.disable_optimizations" + +float bar(float a, float b); + +float foo(float a, float b) { + return bar(a, b); +} diff --git a/clang/test/Driver/dxc_O.hlsl b/clang/test/Driver/dxc_O.hlsl new file mode 100644 --- /dev/null +++ b/clang/test/Driver/dxc_O.hlsl @@ -0,0 +1,18 @@ +// RUN: %clang_dxc -T lib_6_7 foo.hlsl -### %s 2>&1 | FileCheck %s +// RUN: %clang_dxc -T lib_6_7 -Od foo.hlsl -### %s 2>&1 | FileCheck %s --check-prefix=Od +// RUN: %clang_dxc -T lib_6_7 -O0 foo.hlsl -### %s 2>&1 | FileCheck %s --check-prefix=O0 +// RUN: %clang_dxc -T lib_6_7 -O1 foo.hlsl -### %s 2>&1 | FileCheck %s --check-prefix=O1 +// RUN: %clang_dxc -T lib_6_7 -O2 foo.hlsl -### %s 2>&1 | FileCheck %s --check-prefix=O2 +// RUN: %clang_dxc -T lib_6_7 -O3 foo.hlsl -### %s 2>&1 | FileCheck %s --check-prefix=O3 + +// Make sure default is O3. +// CHECK: "-O3" + +// Make sure Od/O0 option flag which translated into "-O0" "-dxc-opt-disable" +// Od: "-O0" +// O0: "-O0" + +// Make sure O1/O2/O3 is send to cc1. +// O1: "-O1" +// O2: "-O2" +// O3: "-O3" diff --git a/clang/test/Driver/dxc_fcgl.hlsl b/clang/test/Driver/dxc_fcgl.hlsl --- a/clang/test/Driver/dxc_fcgl.hlsl +++ b/clang/test/Driver/dxc_fcgl.hlsl @@ -1,5 +1,6 @@ // RUN: %clang_dxc -fcgl -T lib_6_7 foo.hlsl -### %s 2>&1 | FileCheck %s // Make sure fcgl option flag which translated into "-S" "-emit-llvm" "-disable-llvm-passes". -// CHECK:"-S" "-emit-llvm" "-disable-llvm-passes" +// CHECK:"-S" +// CHECK-SAME:"-emit-llvm" "-disable-llvm-passes"