Add spvtools::opt::Operand::AsLiteralUint64 (#3320)

diff --git a/source/opt/instruction.h b/source/opt/instruction.h
index 008a831..df4a388 100644
--- a/source/opt/instruction.h
+++ b/source/opt/instruction.h
@@ -92,6 +92,19 @@
   // Returns a string operand as a std::string.
   std::string AsString() const { return AsCString(); }
 
+  // Returns a literal integer operand as a uint64_t
+  uint64_t AsLiteralUint64() const {
+    assert(type == SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER);
+    assert(1 <= words.size());
+    assert(words.size() <= 2);
+    // Load the low word.
+    uint64_t result = uint64_t(words[0]);
+    if (words.size() > 1) {
+      result = result | (uint64_t(words[1]) << 32);
+    }
+    return result;
+  }
+
   friend bool operator==(const Operand& o1, const Operand& o2) {
     return o1.type == o2.type && o1.words == o2.words;
   }
diff --git a/test/opt/instruction_test.cpp b/test/opt/instruction_test.cpp
index 1995c5b..1779720 100644
--- a/test/opt/instruction_test.cpp
+++ b/test/opt/instruction_test.cpp
@@ -74,6 +74,18 @@
   EXPECT_EQ("abcde", operand.AsString());
 }
 
+TEST(InstructionTest, OperandAsLiteralUint64_32bits) {
+  Operand::OperandData words{0x1234};
+  Operand operand(SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER, std::move(words));
+  EXPECT_EQ(uint64_t(0x1234), operand.AsLiteralUint64());
+}
+
+TEST(InstructionTest, OperandAsLiteralUint64_64bits) {
+  Operand::OperandData words{0x1234, 0x89ab};
+  Operand operand(SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER, std::move(words));
+  EXPECT_EQ((uint64_t(0x89ab) << 32 | 0x1234), operand.AsLiteralUint64());
+}
+
 // The words for an OpTypeInt for 32-bit signed integer resulting in Id 44.
 uint32_t kSampleInstructionWords[] = {(4 << 16) | uint32_t(SpvOpTypeInt), 44,
                                       32, 1};