Browse Source

[spirv] Add mechanism for fine-grained control of debug info (#1518)

Added a new command-line option: -fspv-debug=<category>, where
category can be file, source, line, and tool, to give developers
fine-grained control of what debug information they want in
the generated SPIR-V code.
Lei Zhang 7 years ago
parent
commit
81b3451b4a

+ 19 - 0
docs/SPIR-V.rst

@@ -451,6 +451,9 @@ let the compiler emit the following additional debug information:
 * Full path of the main source file using ``OpSource``
 * Preprocessed source code using ``OpSource`` and ``OpSourceContinued``
 * Line information for certain instructions using ``OpLine`` (WIP)
+* DXC Git commit hash using ``OpModuleProcessed`` (requires Vulkan 1.1)
+* DXC command-line options used to compile the shader using ``OpModuleProcessed``
+  (requires Vulkan 1.1)
 
 We chose to embed preprocessed source code instead of original source code to
 avoid pulling in lots of contents unrelated to the current entry point, and
@@ -464,6 +467,19 @@ preprocessing the source code, and the second time is for feeding the
 preprocessed source code as input for a whole compilation. So using ``-Zi``
 means performance penality.
 
+If you want to have fine-grained control over the categories of emitted debug
+information, you can use ``-fspv-debug=``. It accepts:
+
+* ``file``: for emitting full path of the main source file
+* ``source``: for emitting preprocessed source code (turns on ``file`` implicitly)
+* ``line``: for emitting line information (turns on ``source`` implicitly)
+* ``tool``: for emitting DXC Git commit hash and command-line options
+
+``-fspv-debug=`` overrules ``-Zi``. And you can provide multiple instances of
+``-fspv-debug=``. For example, you can use ``-fspv-debug=file -fspv-debug=tool``
+to turn on emitting file path and DXC information; source code and line
+information will not be emitted.
+
 Reflection
 ----------
 
@@ -2877,6 +2893,9 @@ codegen for Vulkan:
   location number according to alphabetical order or declaration order. See
   `HLSL semantic and Vulkan Location`_ for more details.
 - ``-fspv-reflect``: Emits additional SPIR-V instructions to aid reflection.
+- ``-fspv-debug=<category>``: Controls what category of debug information
+  should be emitted. Accepted values are ``file``, ``source``, ``line``, and
+  ``tool``. See `Debugging`_ for more details.
 - ``-fspv-extension=<extension>``: Only allows using ``<extension>`` in CodeGen.
   If you want to allow multiple extensions, provide more than one such option. If you
   want to allow *all* KHR extensions, use ``-fspv-extension=KHR``.

+ 4 - 0
include/dxc/Support/HLSLOptions.h

@@ -167,6 +167,10 @@ public:
   bool VkUseDxLayout;                      // OPT_fvk_use_dx_layout
   bool SpvEnableReflect;                   // OPT_fspv_reflect
   bool VkNoWarnIgnoredFeatures;            // OPT_Wno_vk_ignored_features
+  bool SpvDebugFile;                       // OPT_fspv_debug
+  bool SpvDebugSource;                     // OPT_fspv_debug
+  bool SpvDebugLine;                       // OPT_fspv_debug
+  bool SpvDebugTool;                       // OPT_fspv_debug
   llvm::StringRef VkStageIoOrder;          // OPT_fvk_stage_io_order
   llvm::SmallVector<int32_t, 4> VkBShift;  // OPT_fvk_b_shift
   llvm::SmallVector<int32_t, 4> VkTShift;  // OPT_fvk_t_shift

+ 2 - 0
include/dxc/Support/HLSLOptions.td

@@ -259,6 +259,8 @@ def fvk_use_dx_layout: Flag<["-"], "fvk-use-dx-layout">, Group<spirv_Group>, Fla
   HelpText<"Use DirectX memory layout for Vulkan resources">;
 def fspv_reflect: Flag<["-"], "fspv-reflect">, Group<spirv_Group>, Flags<[CoreOption, DriverOption]>,
   HelpText<"Emit additional SPIR-V instructions to aid reflection">;
+def fspv_debug_EQ : Joined<["-"], "fspv-debug=">, Group<spirv_Group>, Flags<[CoreOption, DriverOption]>,
+  HelpText<"Specify whitelist of debug info category (file -> source -> line, tool)">;
 def fspv_extension_EQ : Joined<["-"], "fspv-extension=">, Group<spirv_Group>, Flags<[CoreOption, DriverOption]>,
   HelpText<"Specify SPIR-V extension permitted to use">;
 def fspv_target_env_EQ : Joined<["-"], "fspv-target-env=">, Group<spirv_Group>, Flags<[CoreOption, DriverOption]>,

+ 28 - 1
lib/DxcSupport/HLSLOptions.cpp

@@ -556,7 +556,7 @@ int ReadDxcOpts(const OptTable *optionTable, unsigned flagsToInclude,
 
   // SPIRV Change Starts
 #ifdef ENABLE_SPIRV_CODEGEN
-  const bool genSpirv = opts.GenSPIRV = Args.hasFlag(OPT_spirv, OPT_INVALID, false);
+  opts.GenSPIRV = Args.hasFlag(OPT_spirv, OPT_INVALID, false);
   opts.VkInvertY = Args.hasFlag(OPT_fvk_invert_y, OPT_INVALID, false);
   opts.VkInvertW = Args.hasFlag(OPT_fvk_use_dx_position_w, OPT_INVALID, false);
   opts.VkUseGlLayout = Args.hasFlag(OPT_fvk_use_gl_layout, OPT_INVALID, false);
@@ -583,6 +583,32 @@ int ReadDxcOpts(const OptTable *optionTable, unsigned flagsToInclude,
     opts.SpvExtensions.push_back(A->getValue());
   }
 
+  opts.SpvDebugFile = opts.SpvDebugSource = false;
+  opts.SpvDebugLine = opts.SpvDebugTool = false;
+  if (Args.hasArg(OPT_fspv_debug_EQ)) {
+    opts.DebugInfo = true;
+    for (const Arg *A : Args.filtered(OPT_fspv_debug_EQ)) {
+      const llvm::StringRef v = A->getValue();
+      if (v == "file") {
+        opts.SpvDebugFile = true;
+      } else if (v == "source") {
+        opts.SpvDebugFile = opts.SpvDebugSource = true;
+      } else if (v == "line") {
+        opts.SpvDebugFile = opts.SpvDebugSource = true;
+        opts.SpvDebugLine = true;
+      } else if (v == "tool") {
+        opts.SpvDebugTool = true;
+      } else {
+        errors << "unknown SPIR-V debug info control parameter: " << v;
+        return 1;
+      }
+    }
+  } else if (opts.DebugInfo) {
+    // By default turn on all categories
+    opts.SpvDebugFile = opts.SpvDebugSource = true;
+    opts.SpvDebugLine = opts.SpvDebugTool = true;
+  }
+
   opts.SpvTargetEnv = Args.getLastArgValue(OPT_fspv_target_env_EQ, "vulkan1.0");
 
   // Handle -Oconfig=<comma-separated-list> option.
@@ -611,6 +637,7 @@ int ReadDxcOpts(const OptTable *optionTable, unsigned flagsToInclude,
       Args.hasFlag(OPT_fspv_reflect, OPT_INVALID, false) ||
       Args.hasFlag(OPT_Wno_vk_ignored_features, OPT_INVALID, false) ||
       !Args.getLastArgValue(OPT_fvk_stage_io_order_EQ).empty() ||
+      !Args.getLastArgValue(OPT_fspv_debug_EQ).empty() ||
       !Args.getLastArgValue(OPT_fspv_extension_EQ).empty() ||
       !Args.getLastArgValue(OPT_fspv_target_env_EQ).empty() ||
       !Args.getLastArgValue(OPT_Oconfig).empty() ||

+ 6 - 2
tools/clang/include/clang/SPIRV/EmitSPIRVOptions.h

@@ -41,7 +41,10 @@ struct EmitSPIRVOptions {
   bool useDxLayout;
   bool enable16BitTypes;
   bool enableReflect;
-  bool enableDebugInfo;
+  bool debugInfoFile;
+  bool debugInfoSource;
+  bool debugInfoLine;
+  bool debugInfoTool;
   bool noWarnIgnoredFeatures;
   llvm::StringRef stageIoOrder;
   llvm::SmallVector<int32_t, 4> bShift;
@@ -55,10 +58,11 @@ struct EmitSPIRVOptions {
   spirv::LayoutRule tBufferLayoutRule;
   spirv::LayoutRule sBufferLayoutRule;
   llvm::SmallVector<llvm::StringRef, 4> optConfig;
+
   // String representation of all command line options.
   std::string clOptions;
 
-  // Initializes dependent fields appropriately
+  /// Initializes dependent fields appropriately
   void Initialize();
 };
 } // end namespace clang

+ 7 - 13
tools/clang/include/clang/SPIRV/Structure.h

@@ -26,6 +26,7 @@
 
 #include "spirv/unified1/spirv.hpp11"
 #include "clang/SPIRV/Constant.h"
+#include "clang/SPIRV/EmitSPIRVOptions.h"
 #include "clang/SPIRV/InstBuilder.h"
 #include "clang/SPIRV/Type.h"
 #include "llvm/ADT/ArrayRef.h"
@@ -272,7 +273,7 @@ struct TypeIdPair {
 class SPIRVModule {
 public:
   /// \brief Default constructs an empty SPIR-V module.
-  inline SPIRVModule();
+  inline SPIRVModule(const EmitSPIRVOptions &options);
 
   // Disable copy constructor/assignment
   SPIRVModule(const SPIRVModule &) = delete;
@@ -293,13 +294,10 @@ public:
   /// destructive; the module will be consumed and cleared after calling it.
   void take(InstBuilder *builder);
 
-  inline void useVulkan1p1();
   /// \brief Sets the id bound to the given bound.
   inline void setBound(uint32_t newBound);
 
   /// \brief Sets the string representation of the command line options.
-  inline void setClOptions(llvm::StringRef opts);
-
   inline void addCapability(spv::Capability);
   inline void addExtension(llvm::StringRef extension);
   inline void addExtInstSet(uint32_t setId, llvm::StringRef extInstSet);
@@ -331,7 +329,8 @@ public:
   inline uint32_t getExtInstSetId(llvm::StringRef setName);
 
 private:
-  bool isVulkan1p1;
+  const EmitSPIRVOptions &spirvOptions;
+
   Header header; ///< SPIR-V module header.
   llvm::SetVector<spv::Capability> capabilities;
   llvm::SetVector<std::string> extensions;
@@ -458,16 +457,11 @@ TypeIdPair::TypeIdPair(const Type &ty, uint32_t id) : type(ty), resultId(id) {}
 
 // === Module inline implementations ===
 
-SPIRVModule::SPIRVModule()
-    : isVulkan1p1(false), addressingModel(llvm::None), memoryModel(llvm::None),
-      shaderModelVersion(0), sourceFileNameId(0) {}
+SPIRVModule::SPIRVModule(const EmitSPIRVOptions &options)
+    : spirvOptions(options), addressingModel(llvm::None),
+      memoryModel(llvm::None), shaderModelVersion(0), sourceFileNameId(0) {}
 
-void SPIRVModule::useVulkan1p1() {
-  isVulkan1p1 = true;
-  header.version = 0x00010300u;
-}
 void SPIRVModule::setBound(uint32_t newBound) { header.bound = newBound; }
-void SPIRVModule::setClOptions(llvm::StringRef opts) { clOptions = opts; }
 
 void SPIRVModule::addCapability(spv::Capability cap) {
   capabilities.insert(cap);

+ 4 - 12
tools/clang/lib/SPIRV/ModuleBuilder.cpp

@@ -10,7 +10,7 @@
 #include "clang/SPIRV/ModuleBuilder.h"
 
 #include "TypeTranslator.h"
-#include "spirv/unified1//spirv.hpp11"
+#include "spirv/unified1/spirv.hpp11"
 #include "clang/SPIRV/BitwiseCast.h"
 #include "clang/SPIRV/InstBuilder.h"
 
@@ -19,20 +19,12 @@ namespace spirv {
 
 ModuleBuilder::ModuleBuilder(SPIRVContext *C, FeatureManager *features,
                              const EmitSPIRVOptions &opts)
-    : theContext(*C), featureManager(features), spirvOptions(opts), theModule(),
-      theFunction(nullptr), insertPoint(nullptr), instBuilder(nullptr),
-      glslExtSetId(0) {
+    : theContext(*C), featureManager(features), spirvOptions(opts),
+      theModule(opts), theFunction(nullptr), insertPoint(nullptr),
+      instBuilder(nullptr), glslExtSetId(0) {
   instBuilder.setConsumer([this](std::vector<uint32_t> &&words) {
     this->constructSite = std::move(words);
   });
-
-  // Set the SPIR-V version and the command line options that were used to
-  // generate this module, if needed.
-  if (featureManager && featureManager->getTargetEnv() == SPV_ENV_VULKAN_1_1) {
-    theModule.useVulkan1p1();
-    if (spirvOptions.enableDebugInfo)
-      theModule.setClOptions(opts.clOptions);
-  }
 }
 
 std::vector<uint32_t> ModuleBuilder::takeModule() {

+ 2 - 2
tools/clang/lib/SPIRV/SPIRVEmitter.cpp

@@ -623,7 +623,7 @@ SPIRVEmitter::SPIRVEmitter(CompilerInstance &ci, EmitSPIRVOptions &options)
 
   // Set debug info
   const auto &inputFiles = ci.getFrontendOpts().Inputs;
-  if (options.enableDebugInfo && !inputFiles.empty()) {
+  if (options.debugInfoFile && !inputFiles.empty()) {
     // File name
     mainSourceFileId = theContext.takeNextId();
     theBuilder.setSourceFileName(mainSourceFileId,
@@ -9999,7 +9999,7 @@ uint32_t SPIRVEmitter::extractVecFromVec4(uint32_t fromId,
 }
 
 void SPIRVEmitter::emitDebugLine(SourceLocation loc) {
-  if (spirvOptions.enableDebugInfo && mainSourceFileId != 0) {
+  if (spirvOptions.debugInfoLine && mainSourceFileId != 0) {
     auto floc = FullSourceLoc(loc, theCompilerInstance.getSourceManager());
     theBuilder.debugLine(mainSourceFileId, floc.getSpellingLineNumber(),
                          floc.getSpellingColumnNumber());

+ 26 - 15
tools/clang/lib/SPIRV/Structure.cpp

@@ -288,6 +288,8 @@ void SPIRVModule::take(InstBuilder *builder) {
 
   // Order matters here.
 
+  if (spirvOptions.targetEnv == "vulkan1.1")
+    header.version = 0x00010300u;
   header.collect(consumer);
 
   for (auto &cap : capabilities) {
@@ -319,25 +321,34 @@ void SPIRVModule::take(InstBuilder *builder) {
 
   if (shaderModelVersion != 0) {
     llvm::Optional<uint32_t> fileName = llvm::None;
-    if (!sourceFileName.empty() && sourceFileNameId) {
+
+    if (spirvOptions.debugInfoFile && !sourceFileName.empty() &&
+        sourceFileNameId) {
       builder->opString(sourceFileNameId, sourceFileName).x();
       fileName = sourceFileNameId;
     }
 
-    llvm::SmallVector<llvm::StringRef, 2> choppedSrcCode;
     llvm::Optional<llvm::StringRef> firstSnippet;
-    chopString(sourceFileContent, &choppedSrcCode);
-    if (!choppedSrcCode.empty()) {
-      firstSnippet = llvm::Optional<llvm::StringRef>(choppedSrcCode.front());
-    }
+    if (spirvOptions.debugInfoSource) {
+      llvm::SmallVector<llvm::StringRef, 2> choppedSrcCode;
+      chopString(sourceFileContent, &choppedSrcCode);
+      if (!choppedSrcCode.empty()) {
+        firstSnippet = llvm::Optional<llvm::StringRef>(choppedSrcCode.front());
+      }
 
-    builder
-        ->opSource(spv::SourceLanguage::HLSL, shaderModelVersion, fileName,
-                   firstSnippet)
-        .x();
+      builder
+          ->opSource(spv::SourceLanguage::HLSL, shaderModelVersion, fileName,
+                     firstSnippet)
+          .x();
 
-    for (uint32_t i = 1; i < choppedSrcCode.size(); ++i) {
-      builder->opSourceContinued(choppedSrcCode[i]).x();
+      for (uint32_t i = 1; i < choppedSrcCode.size(); ++i) {
+        builder->opSourceContinued(choppedSrcCode[i]).x();
+      }
+    } else {
+      builder
+          ->opSource(spv::SourceLanguage::HLSL, shaderModelVersion, fileName,
+                     firstSnippet)
+          .x();
     }
   }
 
@@ -362,7 +373,7 @@ void SPIRVModule::take(InstBuilder *builder) {
     }
   }
 
-  if (isVulkan1p1) {
+  if (spirvOptions.debugInfoTool && spirvOptions.targetEnv == "vulkan1.1") {
     // Emit OpModuleProcessed to indicate the commit information.
     std::string commitHash =
         std::string("dxc-commit-hash: ") + clang::getGitCommitHash();
@@ -374,9 +385,9 @@ void SPIRVModule::take(InstBuilder *builder) {
 
     // Emit OpModuleProcessed to indicate the command line options that were
     // used to generate this module.
-    if (!clOptions.empty()) {
+    if (!spirvOptions.clOptions.empty()) {
       // Using this format: "dxc-cl-option: XXXXXX"
-      std::string clOptionStr = "dxc-cl-option:" + clOptions;
+      std::string clOptionStr = "dxc-cl-option:" + spirvOptions.clOptions;
       builder->opModuleProcessed(clOptionStr).x();
     }
   }

+ 17 - 0
tools/clang/test/CodeGenSPIRV/spirv.debug.ctrl.file.hlsl

@@ -0,0 +1,17 @@
+// Run: %dxc -T ps_6_1 -E main -fspv-target-env=vulkan1.1 -fspv-debug=file -Zi
+
+// Have file path
+// CHECK:      [[file:%\d+]] = OpString
+// CHECK-SAME: spirv.debug.ctrl.file.hlsl
+// CHECK:      OpSource HLSL 610 [[file]]
+// No source code
+// CHECK-NOT:  float4 main(uint val
+// No tool
+// CHECK-NOT: OpModuleProcessed
+// No line
+// CHECK-NOT: OpLine
+
+float4 main(uint val : A) : SV_Target {
+  uint a = reversebits(val);
+  return a;
+}

+ 17 - 0
tools/clang/test/CodeGenSPIRV/spirv.debug.ctrl.line.hlsl

@@ -0,0 +1,17 @@
+// Run: %dxc -T ps_6_1 -E main -fspv-debug=line
+
+// Have file path
+// CHECK:      [[file:%\d+]] = OpString
+// CHECK-SAME: spirv.debug.ctrl.line.hlsl
+// CHECK:      OpSource HLSL 610 [[file]]
+// Have source code
+// CHECK:      float4 main(uint val
+// No tool
+// CHECK-NOT:  OpModuleProcessed
+// Have line
+// CHECK:      OpLine
+
+float4 main(uint val : A) : SV_Target {
+  uint a = reversebits(val);
+  return a;
+}

+ 17 - 0
tools/clang/test/CodeGenSPIRV/spirv.debug.ctrl.source.hlsl

@@ -0,0 +1,17 @@
+// Run: %dxc -T ps_6_1 -E main -fspv-target-env=vulkan1.1 -fspv-debug=source
+
+// Have file path
+// CHECK:      [[file:%\d+]] = OpString
+// CHECK-SAME: spirv.debug.ctrl.source.hlsl
+// CHECK:      OpSource HLSL 610 [[file]]
+// Have source code
+// CHECK:      float4 main(uint val
+// No tool
+// CHECK-NOT: OpModuleProcessed
+// No line
+// CHECK-NOT: OpLine
+
+float4 main(uint val : A) : SV_Target {
+  uint a = reversebits(val);
+  return a;
+}

+ 15 - 0
tools/clang/test/CodeGenSPIRV/spirv.debug.ctrl.tool.hlsl

@@ -0,0 +1,15 @@
+// Run: %dxc -T ps_6_1 -E main -fspv-target-env=vulkan1.1 -fspv-debug=tool -Zi
+
+// No file path
+// CHECK-NOT: OpString
+// No source code
+// CHECK-NOT: float4 main(uint val
+// Have tool
+// CHECK:     OpModuleProcessed
+// No line
+// CHECK-NOT: OpLine
+
+float4 main(uint val : A) : SV_Target {
+  uint a = reversebits(val);
+  return a;
+}

+ 8 - 0
tools/clang/test/CodeGenSPIRV/spirv.debug.ctrl.unknown.hlsl

@@ -0,0 +1,8 @@
+// Run: %dxc -T ps_6_1 -E main -fspv-debug=t
+
+float4 main(uint val : A) : SV_Target {
+  uint a = reversebits(val);
+  return a;
+}
+
+// CHECK: unknown SPIR-V debug info control parameter: t

+ 4 - 1
tools/clang/tools/dxcompiler/dxcompilerobj.cpp

@@ -529,7 +529,10 @@ public:
           spirvOpts.allowedExtensions = opts.SpvExtensions;
           spirvOpts.targetEnv = opts.SpvTargetEnv;
           spirvOpts.enable16BitTypes = opts.Enable16BitTypes;
-          spirvOpts.enableDebugInfo = opts.DebugInfo;
+          spirvOpts.debugInfoFile = opts.SpvDebugFile;
+          spirvOpts.debugInfoSource = opts.SpvDebugSource;
+          spirvOpts.debugInfoLine = opts.SpvDebugLine;
+          spirvOpts.debugInfoTool = opts.SpvDebugTool;
           spirvOpts.optConfig = opts.SpvOconfig;
 
           // Store a string representation of command line options.

+ 27 - 6
tools/clang/unittests/SPIRV/CodeGenSPIRVTest.cpp

@@ -1269,12 +1269,6 @@ TEST_F(FileTest, SpirvOptOconfigInvalidFlag) {
 }
 TEST_F(FileTest, SpirvOptOconfig) { runFileTest("spirv.opt.cl.oconfig.hlsl"); }
 
-// Test that command line options are exposed using OpModuleProcessed.
-TEST_F(FileTest, SpirvDebugClOption) {
-  useVulkan1p1();
-  runFileTest("spirv.debug.cl-option.hlsl");
-}
-
 // For shader stage input/output interface
 // For semantic SV_Position, SV_ClipDistance, SV_CullDistance
 TEST_F(FileTest, SpirvStageIOInterfaceVS) {
@@ -1356,6 +1350,33 @@ TEST_F(FileTest, SpirvDebugDxcCommitInfo) {
   runFileTest("spirv.debug.commit.hlsl");
 }
 
+// Test that command line options are exposed using OpModuleProcessed.
+TEST_F(FileTest, SpirvDebugClOption) {
+  useVulkan1p1();
+  runFileTest("spirv.debug.cl-option.hlsl");
+}
+
+TEST_F(FileTest, SpirvDebugControlFile) {
+  useVulkan1p1();
+  runFileTest("spirv.debug.ctrl.file.hlsl");
+}
+TEST_F(FileTest, SpirvDebugControlSource) {
+  useVulkan1p1();
+  runFileTest("spirv.debug.ctrl.source.hlsl");
+}
+TEST_F(FileTest, SpirvDebugControlLine) {
+  useVulkan1p1();
+  runFileTest("spirv.debug.ctrl.line.hlsl");
+}
+TEST_F(FileTest, SpirvDebugControlTool) {
+  useVulkan1p1();
+  runFileTest("spirv.debug.ctrl.tool.hlsl");
+}
+TEST_F(FileTest, SpirvDebugControlUnknown) {
+  useVulkan1p1();
+  runFileTest("spirv.debug.ctrl.unknown.hlsl", Expect::Failure);
+}
+
 TEST_F(FileTest, VulkanAttributeErrors) {
   runFileTest("vk.attribute.error.hlsl", Expect::Failure);
 }

+ 4 - 4
tools/clang/unittests/SPIRV/StructureTest.cpp

@@ -107,12 +107,12 @@ TEST(Structure, AfterClearFunctionIsEmpty) {
 }
 
 TEST(Structure, DefaultConstructedModuleIsEmpty) {
-  auto m = SPIRVModule();
+  auto m = SPIRVModule({});
   EXPECT_TRUE(m.isEmpty());
 }
 
 TEST(Structure, AfterClearModuleIsEmpty) {
-  auto m = SPIRVModule();
+  auto m = SPIRVModule({});
   m.setBound(12);
   EXPECT_FALSE(m.isEmpty());
   m.clear();
@@ -121,7 +121,7 @@ TEST(Structure, AfterClearModuleIsEmpty) {
 
 TEST(Structure, TakeModuleHaveAllContents) {
   SPIRVContext context;
-  auto m = SPIRVModule();
+  auto m = SPIRVModule({});
 
   // Will fix up the bound later.
   SimpleInstBuilder sib(0);
@@ -226,7 +226,7 @@ TEST(Structure, TakeModuleHaveAllContents) {
 
 TEST(Structure, TakeModuleWithArrayAndConstantDependency) {
   SPIRVContext context;
-  auto m = SPIRVModule();
+  auto m = SPIRVModule({});
 
   // Will fix up the id bound later.
   SimpleInstBuilder sib(0);