[Lldb-commits] [lldb] 230df79 - [lldb] Use llvm::transformOptional (NFC)

Kazu Hirata via lldb-commits lldb-commits at lists.llvm.org
Wed Dec 14 18:36:56 PST 2022


Author: Kazu Hirata
Date: 2022-12-14T18:36:49-08:00
New Revision: 230df792e17519071a9ef4dc0fb10132540dfbb8

URL: https://github.com/llvm/llvm-project/commit/230df792e17519071a9ef4dc0fb10132540dfbb8
DIFF: https://github.com/llvm/llvm-project/commit/230df792e17519071a9ef4dc0fb10132540dfbb8.diff

LOG: [lldb] Use llvm::transformOptional (NFC)

This is part of an effort to migrate from llvm::Optional to
std::optional:

https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716

Added: 
    

Modified: 
    lldb/source/Plugins/Instruction/RISCV/EmulateInstructionRISCV.cpp
    lldb/source/Plugins/Process/Linux/IntelPTSingleBufferTrace.cpp
    lldb/unittests/Instruction/RISCV/TestRISCVEmulator.cpp

Removed: 
    


################################################################################
diff  --git a/lldb/source/Plugins/Instruction/RISCV/EmulateInstructionRISCV.cpp b/lldb/source/Plugins/Instruction/RISCV/EmulateInstructionRISCV.cpp
index b3fefb2f481fa..42b3c56dfe9f0 100644
--- a/lldb/source/Plugins/Instruction/RISCV/EmulateInstructionRISCV.cpp
+++ b/lldb/source/Plugins/Instruction/RISCV/EmulateInstructionRISCV.cpp
@@ -138,18 +138,18 @@ llvm::Optional<uint64_t> Rs::Read(EmulateInstructionRISCV &emulator) {
 }
 
 llvm::Optional<int32_t> Rs::ReadI32(EmulateInstructionRISCV &emulator) {
-  return Read(emulator).transform(
-      [](uint64_t value) { return int32_t(uint32_t(value)); });
+  return llvm::transformOptional(
+      Read(emulator), [](uint64_t value) { return int32_t(uint32_t(value)); });
 }
 
 llvm::Optional<int64_t> Rs::ReadI64(EmulateInstructionRISCV &emulator) {
-  return Read(emulator).transform(
-      [](uint64_t value) { return int64_t(value); });
+  return llvm::transformOptional(Read(emulator),
+                                 [](uint64_t value) { return int64_t(value); });
 }
 
 llvm::Optional<uint32_t> Rs::ReadU32(EmulateInstructionRISCV &emulator) {
-  return Read(emulator).transform(
-      [](uint64_t value) { return uint32_t(value); });
+  return llvm::transformOptional(
+      Read(emulator), [](uint64_t value) { return uint32_t(value); });
 }
 
 llvm::Optional<llvm::APFloat> Rs::ReadAPFloat(EmulateInstructionRISCV &emulator,
@@ -217,8 +217,9 @@ constexpr bool is_amo_cmp =
 template <typename I>
 static std::enable_if_t<is_load<I> || is_store<I>, llvm::Optional<uint64_t>>
 LoadStoreAddr(EmulateInstructionRISCV &emulator, I inst) {
-  return inst.rs1.Read(emulator).transform(
-      [&](uint64_t rs1) { return rs1 + uint64_t(SignExt(inst.imm)); });
+  return llvm::transformOptional(inst.rs1.Read(emulator), [&](uint64_t rs1) {
+    return rs1 + uint64_t(SignExt(inst.imm));
+  });
 }
 
 // Read T from memory, then load its sign-extended value m_emu to register.
@@ -228,8 +229,9 @@ Load(EmulateInstructionRISCV &emulator, I inst, uint64_t (*extend)(E)) {
   auto addr = LoadStoreAddr(emulator, inst);
   if (!addr)
     return false;
-  return emulator.ReadMem<T>(*addr)
-      .transform([&](T t) { return inst.rd.Write(emulator, extend(E(t))); })
+  return llvm::transformOptional(
+             emulator.ReadMem<T>(*addr),
+             [&](T t) { return inst.rd.Write(emulator, extend(E(t))); })
       .value_or(false);
 }
 
@@ -239,8 +241,9 @@ Store(EmulateInstructionRISCV &emulator, I inst) {
   auto addr = LoadStoreAddr(emulator, inst);
   if (!addr)
     return false;
-  return inst.rs2.Read(emulator)
-      .transform([&](uint64_t rs2) { return emulator.WriteMem<T>(*addr, rs2); })
+  return llvm::transformOptional(
+             inst.rs2.Read(emulator),
+             [&](uint64_t rs2) { return emulator.WriteMem<T>(*addr, rs2); })
       .value_or(false);
 }
 
@@ -249,10 +252,12 @@ static std::enable_if_t<is_amo_add<I> || is_amo_bit_op<I> || is_amo_swap<I> ||
                             is_amo_cmp<I>,
                         llvm::Optional<uint64_t>>
 AtomicAddr(EmulateInstructionRISCV &emulator, I inst, unsigned int align) {
-  return inst.rs1.Read(emulator)
-      .transform([&](uint64_t rs1) {
-        return rs1 % align == 0 ? llvm::Optional<uint64_t>(rs1) : std::nullopt;
-      })
+  return llvm::transformOptional(inst.rs1.Read(emulator),
+                                 [&](uint64_t rs1) {
+                                   return rs1 % align == 0
+                                              ? llvm::Optional<uint64_t>(rs1)
+                                              : std::nullopt;
+                                 })
       .value_or(std::nullopt);
 }
 
@@ -263,12 +268,13 @@ AtomicSwap(EmulateInstructionRISCV &emulator, I inst, int align,
   auto addr = AtomicAddr(emulator, inst, align);
   if (!addr)
     return false;
-  return zipOpt(emulator.ReadMem<T>(*addr), inst.rs2.Read(emulator))
-      .transform([&](auto &&tup) {
-        auto [tmp, rs2] = tup;
-        return emulator.WriteMem<T>(*addr, T(rs2)) &&
-               inst.rd.Write(emulator, extend(tmp));
-      })
+  return llvm::transformOptional(
+             zipOpt(emulator.ReadMem<T>(*addr), inst.rs2.Read(emulator)),
+             [&](auto &&tup) {
+               auto [tmp, rs2] = tup;
+               return emulator.WriteMem<T>(*addr, T(rs2)) &&
+                      inst.rd.Write(emulator, extend(tmp));
+             })
       .value_or(false);
 }
 
@@ -279,12 +285,13 @@ AtomicADD(EmulateInstructionRISCV &emulator, I inst, int align,
   auto addr = AtomicAddr(emulator, inst, align);
   if (!addr)
     return false;
-  return zipOpt(emulator.ReadMem<T>(*addr), inst.rs2.Read(emulator))
-      .transform([&](auto &&tup) {
-        auto [tmp, rs2] = tup;
-        return emulator.WriteMem<T>(*addr, T(tmp + rs2)) &&
-               inst.rd.Write(emulator, extend(tmp));
-      })
+  return llvm::transformOptional(
+             zipOpt(emulator.ReadMem<T>(*addr), inst.rs2.Read(emulator)),
+             [&](auto &&tup) {
+               auto [tmp, rs2] = tup;
+               return emulator.WriteMem<T>(*addr, T(tmp + rs2)) &&
+                      inst.rd.Write(emulator, extend(tmp));
+             })
       .value_or(false);
 }
 
@@ -295,12 +302,13 @@ AtomicBitOperate(EmulateInstructionRISCV &emulator, I inst, int align,
   auto addr = AtomicAddr(emulator, inst, align);
   if (!addr)
     return false;
-  return zipOpt(emulator.ReadMem<T>(*addr), inst.rs2.Read(emulator))
-      .transform([&](auto &&tup) {
-        auto [value, rs2] = tup;
-        return emulator.WriteMem<T>(*addr, operate(value, T(rs2))) &&
-               inst.rd.Write(emulator, extend(value));
-      })
+  return llvm::transformOptional(
+             zipOpt(emulator.ReadMem<T>(*addr), inst.rs2.Read(emulator)),
+             [&](auto &&tup) {
+               auto [value, rs2] = tup;
+               return emulator.WriteMem<T>(*addr, operate(value, T(rs2))) &&
+                      inst.rd.Write(emulator, extend(value));
+             })
       .value_or(false);
 }
 
@@ -311,12 +319,13 @@ AtomicCmp(EmulateInstructionRISCV &emulator, I inst, int align,
   auto addr = AtomicAddr(emulator, inst, align);
   if (!addr)
     return false;
-  return zipOpt(emulator.ReadMem<T>(*addr), inst.rs2.Read(emulator))
-      .transform([&](auto &&tup) {
-        auto [value, rs2] = tup;
-        return emulator.WriteMem<T>(*addr, cmp(value, T(rs2))) &&
-               inst.rd.Write(emulator, extend(value));
-      })
+  return llvm::transformOptional(
+             zipOpt(emulator.ReadMem<T>(*addr), inst.rs2.Read(emulator)),
+             [&](auto &&tup) {
+               auto [value, rs2] = tup;
+               return emulator.WriteMem<T>(*addr, cmp(value, T(rs2))) &&
+                      inst.rd.Write(emulator, extend(value));
+             })
       .value_or(false);
 }
 
@@ -614,37 +623,42 @@ class Executor {
 
   bool operator()(LUI inst) { return inst.rd.Write(m_emu, SignExt(inst.imm)); }
   bool operator()(AUIPC inst) {
-    return m_emu.ReadPC()
-        .transform([&](uint64_t pc) {
-          return inst.rd.Write(m_emu, SignExt(inst.imm) + pc);
-        })
+    return llvm::transformOptional(m_emu.ReadPC(),
+                                   [&](uint64_t pc) {
+                                     return inst.rd.Write(
+                                         m_emu, SignExt(inst.imm) + pc);
+                                   })
         .value_or(false);
   }
   bool operator()(JAL inst) {
-    return m_emu.ReadPC()
-        .transform([&](uint64_t pc) {
-          return inst.rd.Write(m_emu, pc + delta()) &&
-                 m_emu.WritePC(SignExt(inst.imm) + pc);
-        })
+    return llvm::transformOptional(
+               m_emu.ReadPC(),
+               [&](uint64_t pc) {
+                 return inst.rd.Write(m_emu, pc + delta()) &&
+                        m_emu.WritePC(SignExt(inst.imm) + pc);
+               })
         .value_or(false);
   }
   bool operator()(JALR inst) {
-    return zipOpt(m_emu.ReadPC(), inst.rs1.Read(m_emu))
-        .transform([&](auto &&tup) {
-          auto [pc, rs1] = tup;
-          return inst.rd.Write(m_emu, pc + delta()) &&
-                 m_emu.WritePC((SignExt(inst.imm) + rs1) & ~1);
-        })
+    return llvm::transformOptional(
+               zipOpt(m_emu.ReadPC(), inst.rs1.Read(m_emu)),
+               [&](auto &&tup) {
+                 auto [pc, rs1] = tup;
+                 return inst.rd.Write(m_emu, pc + delta()) &&
+                        m_emu.WritePC((SignExt(inst.imm) + rs1) & ~1);
+               })
         .value_or(false);
   }
   bool operator()(B inst) {
-    return zipOpt(m_emu.ReadPC(), inst.rs1.Read(m_emu), inst.rs2.Read(m_emu))
-        .transform([&](auto &&tup) {
-          auto [pc, rs1, rs2] = tup;
-          if (m_ignore_cond || CompareB(rs1, rs2, inst.funct3))
-            return m_emu.WritePC(SignExt(inst.imm) + pc);
-          return true;
-        })
+    return llvm::transformOptional(
+               zipOpt(m_emu.ReadPC(), inst.rs1.Read(m_emu),
+                      inst.rs2.Read(m_emu)),
+               [&](auto &&tup) {
+                 auto [pc, rs1, rs2] = tup;
+                 if (m_ignore_cond || CompareB(rs1, rs2, inst.funct3))
+                   return m_emu.WritePC(SignExt(inst.imm) + pc);
+                 return true;
+               })
         .value_or(false);
   }
   bool operator()(LB inst) {
@@ -666,125 +680,141 @@ class Executor {
   bool operator()(SH inst) { return Store<SH, uint16_t>(m_emu, inst); }
   bool operator()(SW inst) { return Store<SW, uint32_t>(m_emu, inst); }
   bool operator()(ADDI inst) {
-    return inst.rs1.ReadI64(m_emu)
-        .transform([&](int64_t rs1) {
-          return inst.rd.Write(m_emu, rs1 + int64_t(SignExt(inst.imm)));
-        })
+    return llvm::transformOptional(
+               inst.rs1.ReadI64(m_emu),
+               [&](int64_t rs1) {
+                 return inst.rd.Write(m_emu, rs1 + int64_t(SignExt(inst.imm)));
+               })
         .value_or(false);
   }
   bool operator()(SLTI inst) {
-    return inst.rs1.ReadI64(m_emu)
-        .transform([&](int64_t rs1) {
-          return inst.rd.Write(m_emu, rs1 < int64_t(SignExt(inst.imm)));
-        })
+    return llvm::transformOptional(
+               inst.rs1.ReadI64(m_emu),
+               [&](int64_t rs1) {
+                 return inst.rd.Write(m_emu, rs1 < int64_t(SignExt(inst.imm)));
+               })
         .value_or(false);
   }
   bool operator()(SLTIU inst) {
-    return inst.rs1.Read(m_emu)
-        .transform([&](uint64_t rs1) {
-          return inst.rd.Write(m_emu, rs1 < uint64_t(SignExt(inst.imm)));
-        })
+    return llvm::transformOptional(
+               inst.rs1.Read(m_emu),
+               [&](uint64_t rs1) {
+                 return inst.rd.Write(m_emu, rs1 < uint64_t(SignExt(inst.imm)));
+               })
         .value_or(false);
   }
   bool operator()(XORI inst) {
-    return inst.rs1.Read(m_emu)
-        .transform([&](uint64_t rs1) {
-          return inst.rd.Write(m_emu, rs1 ^ uint64_t(SignExt(inst.imm)));
-        })
+    return llvm::transformOptional(
+               inst.rs1.Read(m_emu),
+               [&](uint64_t rs1) {
+                 return inst.rd.Write(m_emu, rs1 ^ uint64_t(SignExt(inst.imm)));
+               })
         .value_or(false);
   }
   bool operator()(ORI inst) {
-    return inst.rs1.Read(m_emu)
-        .transform([&](uint64_t rs1) {
-          return inst.rd.Write(m_emu, rs1 | uint64_t(SignExt(inst.imm)));
-        })
+    return llvm::transformOptional(
+               inst.rs1.Read(m_emu),
+               [&](uint64_t rs1) {
+                 return inst.rd.Write(m_emu, rs1 | uint64_t(SignExt(inst.imm)));
+               })
         .value_or(false);
   }
   bool operator()(ANDI inst) {
-    return inst.rs1.Read(m_emu)
-        .transform([&](uint64_t rs1) {
-          return inst.rd.Write(m_emu, rs1 & uint64_t(SignExt(inst.imm)));
-        })
+    return llvm::transformOptional(
+               inst.rs1.Read(m_emu),
+               [&](uint64_t rs1) {
+                 return inst.rd.Write(m_emu, rs1 & uint64_t(SignExt(inst.imm)));
+               })
         .value_or(false);
   }
   bool operator()(ADD inst) {
-    return zipOpt(inst.rs1.Read(m_emu), inst.rs2.Read(m_emu))
-        .transform([&](auto &&tup) {
-          auto [rs1, rs2] = tup;
-          return inst.rd.Write(m_emu, rs1 + rs2);
-        })
+    return llvm::transformOptional(
+               zipOpt(inst.rs1.Read(m_emu), inst.rs2.Read(m_emu)),
+               [&](auto &&tup) {
+                 auto [rs1, rs2] = tup;
+                 return inst.rd.Write(m_emu, rs1 + rs2);
+               })
         .value_or(false);
   }
   bool operator()(SUB inst) {
-    return zipOpt(inst.rs1.Read(m_emu), inst.rs2.Read(m_emu))
-        .transform([&](auto &&tup) {
-          auto [rs1, rs2] = tup;
-          return inst.rd.Write(m_emu, rs1 - rs2);
-        })
+    return llvm::transformOptional(
+               zipOpt(inst.rs1.Read(m_emu), inst.rs2.Read(m_emu)),
+               [&](auto &&tup) {
+                 auto [rs1, rs2] = tup;
+                 return inst.rd.Write(m_emu, rs1 - rs2);
+               })
         .value_or(false);
   }
   bool operator()(SLL inst) {
-    return zipOpt(inst.rs1.Read(m_emu), inst.rs2.Read(m_emu))
-        .transform([&](auto &&tup) {
-          auto [rs1, rs2] = tup;
-          return inst.rd.Write(m_emu, rs1 << (rs2 & 0b111111));
-        })
+    return llvm::transformOptional(
+               zipOpt(inst.rs1.Read(m_emu), inst.rs2.Read(m_emu)),
+               [&](auto &&tup) {
+                 auto [rs1, rs2] = tup;
+                 return inst.rd.Write(m_emu, rs1 << (rs2 & 0b111111));
+               })
         .value_or(false);
   }
   bool operator()(SLT inst) {
-    return zipOpt(inst.rs1.ReadI64(m_emu), inst.rs2.ReadI64(m_emu))
-        .transform([&](auto &&tup) {
-          auto [rs1, rs2] = tup;
-          return inst.rd.Write(m_emu, rs1 < rs2);
-        })
+    return llvm::transformOptional(
+               zipOpt(inst.rs1.ReadI64(m_emu), inst.rs2.ReadI64(m_emu)),
+               [&](auto &&tup) {
+                 auto [rs1, rs2] = tup;
+                 return inst.rd.Write(m_emu, rs1 < rs2);
+               })
         .value_or(false);
   }
   bool operator()(SLTU inst) {
-    return zipOpt(inst.rs1.Read(m_emu), inst.rs2.Read(m_emu))
-        .transform([&](auto &&tup) {
-          auto [rs1, rs2] = tup;
-          return inst.rd.Write(m_emu, rs1 < rs2);
-        })
+    return llvm::transformOptional(
+               zipOpt(inst.rs1.Read(m_emu), inst.rs2.Read(m_emu)),
+               [&](auto &&tup) {
+                 auto [rs1, rs2] = tup;
+                 return inst.rd.Write(m_emu, rs1 < rs2);
+               })
         .value_or(false);
   }
   bool operator()(XOR inst) {
-    return zipOpt(inst.rs1.Read(m_emu), inst.rs2.Read(m_emu))
-        .transform([&](auto &&tup) {
-          auto [rs1, rs2] = tup;
-          return inst.rd.Write(m_emu, rs1 ^ rs2);
-        })
+    return llvm::transformOptional(
+               zipOpt(inst.rs1.Read(m_emu), inst.rs2.Read(m_emu)),
+               [&](auto &&tup) {
+                 auto [rs1, rs2] = tup;
+                 return inst.rd.Write(m_emu, rs1 ^ rs2);
+               })
         .value_or(false);
   }
   bool operator()(SRL inst) {
-    return zipOpt(inst.rs1.Read(m_emu), inst.rs2.Read(m_emu))
-        .transform([&](auto &&tup) {
-          auto [rs1, rs2] = tup;
-          return inst.rd.Write(m_emu, rs1 >> (rs2 & 0b111111));
-        })
+    return llvm::transformOptional(
+               zipOpt(inst.rs1.Read(m_emu), inst.rs2.Read(m_emu)),
+               [&](auto &&tup) {
+                 auto [rs1, rs2] = tup;
+                 return inst.rd.Write(m_emu, rs1 >> (rs2 & 0b111111));
+               })
         .value_or(false);
   }
   bool operator()(SRA inst) {
-    return zipOpt(inst.rs1.ReadI64(m_emu), inst.rs2.Read(m_emu))
-        .transform([&](auto &&tup) {
-          auto [rs1, rs2] = tup;
-          return inst.rd.Write(m_emu, rs1 >> (rs2 & 0b111111));
-        })
+    return llvm::transformOptional(
+               zipOpt(inst.rs1.ReadI64(m_emu), inst.rs2.Read(m_emu)),
+               [&](auto &&tup) {
+                 auto [rs1, rs2] = tup;
+                 return inst.rd.Write(m_emu, rs1 >> (rs2 & 0b111111));
+               })
         .value_or(false);
   }
   bool operator()(OR inst) {
-    return zipOpt(inst.rs1.Read(m_emu), inst.rs2.Read(m_emu))
-        .transform([&](auto &&tup) {
-          auto [rs1, rs2] = tup;
-          return inst.rd.Write(m_emu, rs1 | rs2);
-        })
+    return llvm::transformOptional(
+               zipOpt(inst.rs1.Read(m_emu), inst.rs2.Read(m_emu)),
+               [&](auto &&tup) {
+                 auto [rs1, rs2] = tup;
+                 return inst.rd.Write(m_emu, rs1 | rs2);
+               })
         .value_or(false);
   }
   bool operator()(AND inst) {
-    return zipOpt(inst.rs1.Read(m_emu), inst.rs2.Read(m_emu))
-        .transform([&](auto &&tup) {
-          auto [rs1, rs2] = tup;
-          return inst.rd.Write(m_emu, rs1 & rs2);
-        })
+    return llvm::transformOptional(
+               zipOpt(inst.rs1.Read(m_emu), inst.rs2.Read(m_emu)),
+               [&](auto &&tup) {
+                 auto [rs1, rs2] = tup;
+                 return inst.rd.Write(m_emu, rs1 & rs2);
+               })
         .value_or(false);
   }
   bool operator()(LWU inst) {
@@ -795,249 +825,278 @@ class Executor {
   }
   bool operator()(SD inst) { return Store<SD, uint64_t>(m_emu, inst); }
   bool operator()(SLLI inst) {
-    return inst.rs1.Read(m_emu)
-        .transform([&](uint64_t rs1) {
-          return inst.rd.Write(m_emu, rs1 << inst.shamt);
-        })
+    return llvm::transformOptional(inst.rs1.Read(m_emu),
+                                   [&](uint64_t rs1) {
+                                     return inst.rd.Write(m_emu,
+                                                          rs1 << inst.shamt);
+                                   })
         .value_or(false);
   }
   bool operator()(SRLI inst) {
-    return inst.rs1.Read(m_emu)
-        .transform([&](uint64_t rs1) {
-          return inst.rd.Write(m_emu, rs1 >> inst.shamt);
-        })
+    return llvm::transformOptional(inst.rs1.Read(m_emu),
+                                   [&](uint64_t rs1) {
+                                     return inst.rd.Write(m_emu,
+                                                          rs1 >> inst.shamt);
+                                   })
         .value_or(false);
   }
   bool operator()(SRAI inst) {
-    return inst.rs1.ReadI64(m_emu)
-        .transform([&](int64_t rs1) {
-          return inst.rd.Write(m_emu, rs1 >> inst.shamt);
-        })
+    return llvm::transformOptional(inst.rs1.ReadI64(m_emu),
+                                   [&](int64_t rs1) {
+                                     return inst.rd.Write(m_emu,
+                                                          rs1 >> inst.shamt);
+                                   })
         .value_or(false);
   }
   bool operator()(ADDIW inst) {
-    return inst.rs1.ReadI32(m_emu)
-        .transform([&](int32_t rs1) {
-          return inst.rd.Write(m_emu, SextW(rs1 + SignExt(inst.imm)));
-        })
+    return llvm::transformOptional(inst.rs1.ReadI32(m_emu),
+                                   [&](int32_t rs1) {
+                                     return inst.rd.Write(
+                                         m_emu, SextW(rs1 + SignExt(inst.imm)));
+                                   })
         .value_or(false);
   }
   bool operator()(SLLIW inst) {
-    return inst.rs1.ReadU32(m_emu)
-        .transform([&](uint32_t rs1) {
-          return inst.rd.Write(m_emu, SextW(rs1 << inst.shamt));
-        })
+    return llvm::transformOptional(inst.rs1.ReadU32(m_emu),
+                                   [&](uint32_t rs1) {
+                                     return inst.rd.Write(
+                                         m_emu, SextW(rs1 << inst.shamt));
+                                   })
         .value_or(false);
   }
   bool operator()(SRLIW inst) {
-    return inst.rs1.ReadU32(m_emu)
-        .transform([&](uint32_t rs1) {
-          return inst.rd.Write(m_emu, SextW(rs1 >> inst.shamt));
-        })
+    return llvm::transformOptional(inst.rs1.ReadU32(m_emu),
+                                   [&](uint32_t rs1) {
+                                     return inst.rd.Write(
+                                         m_emu, SextW(rs1 >> inst.shamt));
+                                   })
         .value_or(false);
   }
   bool operator()(SRAIW inst) {
-    return inst.rs1.ReadI32(m_emu)
-        .transform([&](int32_t rs1) {
-          return inst.rd.Write(m_emu, SextW(rs1 >> inst.shamt));
-        })
+    return llvm::transformOptional(inst.rs1.ReadI32(m_emu),
+                                   [&](int32_t rs1) {
+                                     return inst.rd.Write(
+                                         m_emu, SextW(rs1 >> inst.shamt));
+                                   })
         .value_or(false);
   }
   bool operator()(ADDW inst) {
-    return zipOpt(inst.rs1.Read(m_emu), inst.rs2.Read(m_emu))
-        .transform([&](auto &&tup) {
-          auto [rs1, rs2] = tup;
-          return inst.rd.Write(m_emu, SextW(uint32_t(rs1 + rs2)));
-        })
+    return llvm::transformOptional(
+               zipOpt(inst.rs1.Read(m_emu), inst.rs2.Read(m_emu)),
+               [&](auto &&tup) {
+                 auto [rs1, rs2] = tup;
+                 return inst.rd.Write(m_emu, SextW(uint32_t(rs1 + rs2)));
+               })
         .value_or(false);
   }
   bool operator()(SUBW inst) {
-    return zipOpt(inst.rs1.Read(m_emu), inst.rs2.Read(m_emu))
-        .transform([&](auto &&tup) {
-          auto [rs1, rs2] = tup;
-          return inst.rd.Write(m_emu, SextW(uint32_t(rs1 - rs2)));
-        })
+    return llvm::transformOptional(
+               zipOpt(inst.rs1.Read(m_emu), inst.rs2.Read(m_emu)),
+               [&](auto &&tup) {
+                 auto [rs1, rs2] = tup;
+                 return inst.rd.Write(m_emu, SextW(uint32_t(rs1 - rs2)));
+               })
         .value_or(false);
   }
   bool operator()(SLLW inst) {
-    return zipOpt(inst.rs1.ReadU32(m_emu), inst.rs2.ReadU32(m_emu))
-        .transform([&](auto &&tup) {
-          auto [rs1, rs2] = tup;
-          return inst.rd.Write(m_emu, SextW(rs1 << (rs2 & 0b11111)));
-        })
+    return llvm::transformOptional(
+               zipOpt(inst.rs1.ReadU32(m_emu), inst.rs2.ReadU32(m_emu)),
+               [&](auto &&tup) {
+                 auto [rs1, rs2] = tup;
+                 return inst.rd.Write(m_emu, SextW(rs1 << (rs2 & 0b11111)));
+               })
         .value_or(false);
   }
   bool operator()(SRLW inst) {
-    return zipOpt(inst.rs1.ReadU32(m_emu), inst.rs2.ReadU32(m_emu))
-        .transform([&](auto &&tup) {
-          auto [rs1, rs2] = tup;
-          return inst.rd.Write(m_emu, SextW(rs1 >> (rs2 & 0b11111)));
-        })
+    return llvm::transformOptional(
+               zipOpt(inst.rs1.ReadU32(m_emu), inst.rs2.ReadU32(m_emu)),
+               [&](auto &&tup) {
+                 auto [rs1, rs2] = tup;
+                 return inst.rd.Write(m_emu, SextW(rs1 >> (rs2 & 0b11111)));
+               })
         .value_or(false);
   }
   bool operator()(SRAW inst) {
-    return zipOpt(inst.rs1.ReadI32(m_emu), inst.rs2.Read(m_emu))
-        .transform([&](auto &&tup) {
-          auto [rs1, rs2] = tup;
-          return inst.rd.Write(m_emu, SextW(rs1 >> (rs2 & 0b11111)));
-        })
+    return llvm::transformOptional(
+               zipOpt(inst.rs1.ReadI32(m_emu), inst.rs2.Read(m_emu)),
+               [&](auto &&tup) {
+                 auto [rs1, rs2] = tup;
+                 return inst.rd.Write(m_emu, SextW(rs1 >> (rs2 & 0b11111)));
+               })
         .value_or(false);
   }
   // RV32M & RV64M (Integer Multiplication and Division Extension) //
   bool operator()(MUL inst) {
-    return zipOpt(inst.rs1.Read(m_emu), inst.rs2.Read(m_emu))
-        .transform([&](auto &&tup) {
-          auto [rs1, rs2] = tup;
-          return inst.rd.Write(m_emu, rs1 * rs2);
-        })
+    return llvm::transformOptional(
+               zipOpt(inst.rs1.Read(m_emu), inst.rs2.Read(m_emu)),
+               [&](auto &&tup) {
+                 auto [rs1, rs2] = tup;
+                 return inst.rd.Write(m_emu, rs1 * rs2);
+               })
         .value_or(false);
   }
   bool operator()(MULH inst) {
-    return zipOpt(inst.rs1.Read(m_emu), inst.rs2.Read(m_emu))
-        .transform([&](auto &&tup) {
-          auto [rs1, rs2] = tup;
-          // signed * signed
-          auto mul = llvm::APInt(128, rs1, true) * llvm::APInt(128, rs2, true);
-          return inst.rd.Write(m_emu, mul.ashr(64).trunc(64).getZExtValue());
-        })
+    return llvm::transformOptional(
+               zipOpt(inst.rs1.Read(m_emu), inst.rs2.Read(m_emu)),
+               [&](auto &&tup) {
+                 auto [rs1, rs2] = tup;
+                 // signed * signed
+                 auto mul =
+                     llvm::APInt(128, rs1, true) * llvm::APInt(128, rs2, true);
+                 return inst.rd.Write(m_emu,
+                                      mul.ashr(64).trunc(64).getZExtValue());
+               })
         .value_or(false);
   }
   bool operator()(MULHSU inst) {
-    return zipOpt(inst.rs1.Read(m_emu), inst.rs2.Read(m_emu))
-        .transform([&](auto &&tup) {
-          auto [rs1, rs2] = tup;
-          // signed * unsigned
-          auto mul = llvm::APInt(128, rs1, true).zext(128) *
-                     llvm::APInt(128, rs2, false);
-          return inst.rd.Write(m_emu, mul.lshr(64).trunc(64).getZExtValue());
-        })
+    return llvm::transformOptional(
+               zipOpt(inst.rs1.Read(m_emu), inst.rs2.Read(m_emu)),
+               [&](auto &&tup) {
+                 auto [rs1, rs2] = tup;
+                 // signed * unsigned
+                 auto mul = llvm::APInt(128, rs1, true).zext(128) *
+                            llvm::APInt(128, rs2, false);
+                 return inst.rd.Write(m_emu,
+                                      mul.lshr(64).trunc(64).getZExtValue());
+               })
         .value_or(false);
   }
   bool operator()(MULHU inst) {
-    return zipOpt(inst.rs1.Read(m_emu), inst.rs2.Read(m_emu))
-        .transform([&](auto &&tup) {
-          auto [rs1, rs2] = tup;
-          // unsigned * unsigned
-          auto mul =
-              llvm::APInt(128, rs1, false) * llvm::APInt(128, rs2, false);
-          return inst.rd.Write(m_emu, mul.lshr(64).trunc(64).getZExtValue());
-        })
+    return llvm::transformOptional(
+               zipOpt(inst.rs1.Read(m_emu), inst.rs2.Read(m_emu)),
+               [&](auto &&tup) {
+                 auto [rs1, rs2] = tup;
+                 // unsigned * unsigned
+                 auto mul = llvm::APInt(128, rs1, false) *
+                            llvm::APInt(128, rs2, false);
+                 return inst.rd.Write(m_emu,
+                                      mul.lshr(64).trunc(64).getZExtValue());
+               })
         .value_or(false);
   }
   bool operator()(DIV inst) {
-    return zipOpt(inst.rs1.ReadI64(m_emu), inst.rs2.ReadI64(m_emu))
-        .transform([&](auto &&tup) {
-          auto [dividend, divisor] = tup;
+    return llvm::transformOptional(
+               zipOpt(inst.rs1.ReadI64(m_emu), inst.rs2.ReadI64(m_emu)),
+               [&](auto &&tup) {
+                 auto [dividend, divisor] = tup;
 
-          if (divisor == 0)
-            return inst.rd.Write(m_emu, UINT64_MAX);
+                 if (divisor == 0)
+                   return inst.rd.Write(m_emu, UINT64_MAX);
 
-          if (dividend == INT64_MIN && divisor == -1)
-            return inst.rd.Write(m_emu, dividend);
+                 if (dividend == INT64_MIN && divisor == -1)
+                   return inst.rd.Write(m_emu, dividend);
 
-          return inst.rd.Write(m_emu, dividend / divisor);
-        })
+                 return inst.rd.Write(m_emu, dividend / divisor);
+               })
         .value_or(false);
   }
   bool operator()(DIVU inst) {
-    return zipOpt(inst.rs1.Read(m_emu), inst.rs2.Read(m_emu))
-        .transform([&](auto &&tup) {
-          auto [dividend, divisor] = tup;
+    return llvm::transformOptional(
+               zipOpt(inst.rs1.Read(m_emu), inst.rs2.Read(m_emu)),
+               [&](auto &&tup) {
+                 auto [dividend, divisor] = tup;
 
-          if (divisor == 0)
-            return inst.rd.Write(m_emu, UINT64_MAX);
+                 if (divisor == 0)
+                   return inst.rd.Write(m_emu, UINT64_MAX);
 
-          return inst.rd.Write(m_emu, dividend / divisor);
-        })
+                 return inst.rd.Write(m_emu, dividend / divisor);
+               })
         .value_or(false);
   }
   bool operator()(REM inst) {
-    return zipOpt(inst.rs1.ReadI64(m_emu), inst.rs2.ReadI64(m_emu))
-        .transform([&](auto &&tup) {
-          auto [dividend, divisor] = tup;
+    return llvm::transformOptional(
+               zipOpt(inst.rs1.ReadI64(m_emu), inst.rs2.ReadI64(m_emu)),
+               [&](auto &&tup) {
+                 auto [dividend, divisor] = tup;
 
-          if (divisor == 0)
-            return inst.rd.Write(m_emu, dividend);
+                 if (divisor == 0)
+                   return inst.rd.Write(m_emu, dividend);
 
-          if (dividend == INT64_MIN && divisor == -1)
-            return inst.rd.Write(m_emu, 0);
+                 if (dividend == INT64_MIN && divisor == -1)
+                   return inst.rd.Write(m_emu, 0);
 
-          return inst.rd.Write(m_emu, dividend % divisor);
-        })
+                 return inst.rd.Write(m_emu, dividend % divisor);
+               })
         .value_or(false);
   }
   bool operator()(REMU inst) {
-    return zipOpt(inst.rs1.Read(m_emu), inst.rs2.Read(m_emu))
-        .transform([&](auto &&tup) {
-          auto [dividend, divisor] = tup;
+    return llvm::transformOptional(
+               zipOpt(inst.rs1.Read(m_emu), inst.rs2.Read(m_emu)),
+               [&](auto &&tup) {
+                 auto [dividend, divisor] = tup;
 
-          if (divisor == 0)
-            return inst.rd.Write(m_emu, dividend);
+                 if (divisor == 0)
+                   return inst.rd.Write(m_emu, dividend);
 
-          return inst.rd.Write(m_emu, dividend % divisor);
-        })
+                 return inst.rd.Write(m_emu, dividend % divisor);
+               })
         .value_or(false);
   }
   bool operator()(MULW inst) {
-    return zipOpt(inst.rs1.ReadI32(m_emu), inst.rs2.ReadI32(m_emu))
-        .transform([&](auto &&tup) {
-          auto [rs1, rs2] = tup;
-          return inst.rd.Write(m_emu, SextW(rs1 * rs2));
-        })
+    return llvm::transformOptional(
+               zipOpt(inst.rs1.ReadI32(m_emu), inst.rs2.ReadI32(m_emu)),
+               [&](auto &&tup) {
+                 auto [rs1, rs2] = tup;
+                 return inst.rd.Write(m_emu, SextW(rs1 * rs2));
+               })
         .value_or(false);
   }
   bool operator()(DIVW inst) {
-    return zipOpt(inst.rs1.ReadI32(m_emu), inst.rs2.ReadI32(m_emu))
-        .transform([&](auto &&tup) {
-          auto [dividend, divisor] = tup;
+    return llvm::transformOptional(
+               zipOpt(inst.rs1.ReadI32(m_emu), inst.rs2.ReadI32(m_emu)),
+               [&](auto &&tup) {
+                 auto [dividend, divisor] = tup;
 
-          if (divisor == 0)
-            return inst.rd.Write(m_emu, UINT64_MAX);
+                 if (divisor == 0)
+                   return inst.rd.Write(m_emu, UINT64_MAX);
 
-          if (dividend == INT32_MIN && divisor == -1)
-            return inst.rd.Write(m_emu, SextW(dividend));
+                 if (dividend == INT32_MIN && divisor == -1)
+                   return inst.rd.Write(m_emu, SextW(dividend));
 
-          return inst.rd.Write(m_emu, SextW(dividend / divisor));
-        })
+                 return inst.rd.Write(m_emu, SextW(dividend / divisor));
+               })
         .value_or(false);
   }
   bool operator()(DIVUW inst) {
-    return zipOpt(inst.rs1.ReadU32(m_emu), inst.rs2.ReadU32(m_emu))
-        .transform([&](auto &&tup) {
-          auto [dividend, divisor] = tup;
+    return llvm::transformOptional(
+               zipOpt(inst.rs1.ReadU32(m_emu), inst.rs2.ReadU32(m_emu)),
+               [&](auto &&tup) {
+                 auto [dividend, divisor] = tup;
 
-          if (divisor == 0)
-            return inst.rd.Write(m_emu, UINT64_MAX);
+                 if (divisor == 0)
+                   return inst.rd.Write(m_emu, UINT64_MAX);
 
-          return inst.rd.Write(m_emu, SextW(dividend / divisor));
-        })
+                 return inst.rd.Write(m_emu, SextW(dividend / divisor));
+               })
         .value_or(false);
   }
   bool operator()(REMW inst) {
-    return zipOpt(inst.rs1.ReadI32(m_emu), inst.rs2.ReadI32(m_emu))
-        .transform([&](auto &&tup) {
-          auto [dividend, divisor] = tup;
+    return llvm::transformOptional(
+               zipOpt(inst.rs1.ReadI32(m_emu), inst.rs2.ReadI32(m_emu)),
+               [&](auto &&tup) {
+                 auto [dividend, divisor] = tup;
 
-          if (divisor == 0)
-            return inst.rd.Write(m_emu, SextW(dividend));
+                 if (divisor == 0)
+                   return inst.rd.Write(m_emu, SextW(dividend));
 
-          if (dividend == INT32_MIN && divisor == -1)
-            return inst.rd.Write(m_emu, 0);
+                 if (dividend == INT32_MIN && divisor == -1)
+                   return inst.rd.Write(m_emu, 0);
 
-          return inst.rd.Write(m_emu, SextW(dividend % divisor));
-        })
+                 return inst.rd.Write(m_emu, SextW(dividend % divisor));
+               })
         .value_or(false);
   }
   bool operator()(REMUW inst) {
-    return zipOpt(inst.rs1.ReadU32(m_emu), inst.rs2.ReadU32(m_emu))
-        .transform([&](auto &&tup) {
-          auto [dividend, divisor] = tup;
+    return llvm::transformOptional(
+               zipOpt(inst.rs1.ReadU32(m_emu), inst.rs2.ReadU32(m_emu)),
+               [&](auto &&tup) {
+                 auto [dividend, divisor] = tup;
 
-          if (divisor == 0)
-            return inst.rd.Write(m_emu, SextW(dividend));
+                 if (divisor == 0)
+                   return inst.rd.Write(m_emu, SextW(dividend));
 
-          return inst.rd.Write(m_emu, SextW(dividend % divisor));
-        })
+                 return inst.rd.Write(m_emu, SextW(dividend % divisor));
+               })
         .value_or(false);
   }
   // RV32A & RV64A (The standard atomic instruction extension) //
@@ -1130,115 +1189,126 @@ class Executor {
         [](uint64_t a, uint64_t b) { return std::max(a, b); });
   }
   bool operator()(FLW inst) {
-    return inst.rs1.Read(m_emu)
-        .transform([&](auto &&rs1) {
-          uint64_t addr = rs1 + uint64_t(inst.imm);
-          uint64_t bits = m_emu.ReadMem<uint64_t>(addr).value();
-          llvm::APFloat f(llvm::APFloat::IEEEsingle(), llvm::APInt(32, bits));
-          return inst.rd.WriteAPFloat(m_emu, f);
-        })
+    return llvm::transformOptional(
+               inst.rs1.Read(m_emu),
+               [&](auto &&rs1) {
+                 uint64_t addr = rs1 + uint64_t(inst.imm);
+                 uint64_t bits = m_emu.ReadMem<uint64_t>(addr).value();
+                 llvm::APFloat f(llvm::APFloat::IEEEsingle(),
+                                 llvm::APInt(32, bits));
+                 return inst.rd.WriteAPFloat(m_emu, f);
+               })
         .value_or(false);
   }
   bool operator()(FSW inst) {
-    return zipOpt(inst.rs1.Read(m_emu), inst.rs2.ReadAPFloat(m_emu, false))
-        .transform([&](auto &&tup) {
-          auto [rs1, rs2] = tup;
-          uint64_t addr = rs1 + uint64_t(inst.imm);
-          uint64_t bits = rs2.bitcastToAPInt().getZExtValue();
-          return m_emu.WriteMem<uint64_t>(addr, bits);
-        })
+    return llvm::transformOptional(
+               zipOpt(inst.rs1.Read(m_emu), inst.rs2.ReadAPFloat(m_emu, false)),
+               [&](auto &&tup) {
+                 auto [rs1, rs2] = tup;
+                 uint64_t addr = rs1 + uint64_t(inst.imm);
+                 uint64_t bits = rs2.bitcastToAPInt().getZExtValue();
+                 return m_emu.WriteMem<uint64_t>(addr, bits);
+               })
         .value_or(false);
   }
   bool operator()(FMADD_S inst) {
-    return zipOpt(inst.rs1.ReadAPFloat(m_emu, false),
-                  inst.rs2.ReadAPFloat(m_emu, false),
-                  inst.rs3.ReadAPFloat(m_emu, false))
-        .transform([&](auto &&tup) {
-          auto [rs1, rs2, rs3] = tup;
-          auto res = rs1.fusedMultiplyAdd(rs2, rs3, m_emu.GetRoundingMode());
-          inst.rd.WriteAPFloat(m_emu, rs1);
-          return m_emu.SetAccruedExceptions(res);
-        })
+    return llvm::transformOptional(zipOpt(inst.rs1.ReadAPFloat(m_emu, false),
+                                          inst.rs2.ReadAPFloat(m_emu, false),
+                                          inst.rs3.ReadAPFloat(m_emu, false)),
+                                   [&](auto &&tup) {
+                                     auto [rs1, rs2, rs3] = tup;
+                                     auto res = rs1.fusedMultiplyAdd(
+                                         rs2, rs3, m_emu.GetRoundingMode());
+                                     inst.rd.WriteAPFloat(m_emu, rs1);
+                                     return m_emu.SetAccruedExceptions(res);
+                                   })
         .value_or(false);
   }
   bool operator()(FMSUB_S inst) {
-    return zipOpt(inst.rs1.ReadAPFloat(m_emu, false),
-                  inst.rs2.ReadAPFloat(m_emu, false),
-                  inst.rs3.ReadAPFloat(m_emu, false))
-        .transform([&](auto &&tup) {
-          auto [rs1, rs2, rs3] = tup;
-          auto res = rs1.fusedMultiplyAdd(rs2, -rs3, m_emu.GetRoundingMode());
-          inst.rd.WriteAPFloat(m_emu, rs1);
-          return m_emu.SetAccruedExceptions(res);
-        })
+    return llvm::transformOptional(zipOpt(inst.rs1.ReadAPFloat(m_emu, false),
+                                          inst.rs2.ReadAPFloat(m_emu, false),
+                                          inst.rs3.ReadAPFloat(m_emu, false)),
+                                   [&](auto &&tup) {
+                                     auto [rs1, rs2, rs3] = tup;
+                                     auto res = rs1.fusedMultiplyAdd(
+                                         rs2, -rs3, m_emu.GetRoundingMode());
+                                     inst.rd.WriteAPFloat(m_emu, rs1);
+                                     return m_emu.SetAccruedExceptions(res);
+                                   })
         .value_or(false);
   }
   bool operator()(FNMSUB_S inst) {
-    return zipOpt(inst.rs1.ReadAPFloat(m_emu, false),
-                  inst.rs2.ReadAPFloat(m_emu, false),
-                  inst.rs3.ReadAPFloat(m_emu, false))
-        .transform([&](auto &&tup) {
-          auto [rs1, rs2, rs3] = tup;
-          auto res = rs1.fusedMultiplyAdd(-rs2, rs3, m_emu.GetRoundingMode());
-          inst.rd.WriteAPFloat(m_emu, rs1);
-          return m_emu.SetAccruedExceptions(res);
-        })
+    return llvm::transformOptional(zipOpt(inst.rs1.ReadAPFloat(m_emu, false),
+                                          inst.rs2.ReadAPFloat(m_emu, false),
+                                          inst.rs3.ReadAPFloat(m_emu, false)),
+                                   [&](auto &&tup) {
+                                     auto [rs1, rs2, rs3] = tup;
+                                     auto res = rs1.fusedMultiplyAdd(
+                                         -rs2, rs3, m_emu.GetRoundingMode());
+                                     inst.rd.WriteAPFloat(m_emu, rs1);
+                                     return m_emu.SetAccruedExceptions(res);
+                                   })
         .value_or(false);
   }
   bool operator()(FNMADD_S inst) {
-    return zipOpt(inst.rs1.ReadAPFloat(m_emu, false),
-                  inst.rs2.ReadAPFloat(m_emu, false),
-                  inst.rs3.ReadAPFloat(m_emu, false))
-        .transform([&](auto &&tup) {
-          auto [rs1, rs2, rs3] = tup;
-          auto res = rs1.fusedMultiplyAdd(-rs2, -rs3, m_emu.GetRoundingMode());
-          inst.rd.WriteAPFloat(m_emu, rs1);
-          return m_emu.SetAccruedExceptions(res);
-        })
+    return llvm::transformOptional(zipOpt(inst.rs1.ReadAPFloat(m_emu, false),
+                                          inst.rs2.ReadAPFloat(m_emu, false),
+                                          inst.rs3.ReadAPFloat(m_emu, false)),
+                                   [&](auto &&tup) {
+                                     auto [rs1, rs2, rs3] = tup;
+                                     auto res = rs1.fusedMultiplyAdd(
+                                         -rs2, -rs3, m_emu.GetRoundingMode());
+                                     inst.rd.WriteAPFloat(m_emu, rs1);
+                                     return m_emu.SetAccruedExceptions(res);
+                                   })
         .value_or(false);
   }
   bool operator()(FADD_S inst) {
-    return zipOpt(inst.rs1.ReadAPFloat(m_emu, false),
-                  inst.rs2.ReadAPFloat(m_emu, false))
-        .transform([&](auto &&tup) {
-          auto [rs1, rs2] = tup;
-          auto res = rs1.add(rs2, m_emu.GetRoundingMode());
-          inst.rd.WriteAPFloat(m_emu, rs1);
-          return m_emu.SetAccruedExceptions(res);
-        })
+    return llvm::transformOptional(zipOpt(inst.rs1.ReadAPFloat(m_emu, false),
+                                          inst.rs2.ReadAPFloat(m_emu, false)),
+                                   [&](auto &&tup) {
+                                     auto [rs1, rs2] = tup;
+                                     auto res =
+                                         rs1.add(rs2, m_emu.GetRoundingMode());
+                                     inst.rd.WriteAPFloat(m_emu, rs1);
+                                     return m_emu.SetAccruedExceptions(res);
+                                   })
         .value_or(false);
   }
   bool operator()(FSUB_S inst) {
-    return zipOpt(inst.rs1.ReadAPFloat(m_emu, false),
-                  inst.rs2.ReadAPFloat(m_emu, false))
-        .transform([&](auto &&tup) {
-          auto [rs1, rs2] = tup;
-          auto res = rs1.subtract(rs2, m_emu.GetRoundingMode());
-          inst.rd.WriteAPFloat(m_emu, rs1);
-          return m_emu.SetAccruedExceptions(res);
-        })
+    return llvm::transformOptional(zipOpt(inst.rs1.ReadAPFloat(m_emu, false),
+                                          inst.rs2.ReadAPFloat(m_emu, false)),
+                                   [&](auto &&tup) {
+                                     auto [rs1, rs2] = tup;
+                                     auto res = rs1.subtract(
+                                         rs2, m_emu.GetRoundingMode());
+                                     inst.rd.WriteAPFloat(m_emu, rs1);
+                                     return m_emu.SetAccruedExceptions(res);
+                                   })
         .value_or(false);
   }
   bool operator()(FMUL_S inst) {
-    return zipOpt(inst.rs1.ReadAPFloat(m_emu, false),
-                  inst.rs2.ReadAPFloat(m_emu, false))
-        .transform([&](auto &&tup) {
-          auto [rs1, rs2] = tup;
-          auto res = rs1.multiply(rs2, m_emu.GetRoundingMode());
-          inst.rd.WriteAPFloat(m_emu, rs1);
-          return m_emu.SetAccruedExceptions(res);
-        })
+    return llvm::transformOptional(zipOpt(inst.rs1.ReadAPFloat(m_emu, false),
+                                          inst.rs2.ReadAPFloat(m_emu, false)),
+                                   [&](auto &&tup) {
+                                     auto [rs1, rs2] = tup;
+                                     auto res = rs1.multiply(
+                                         rs2, m_emu.GetRoundingMode());
+                                     inst.rd.WriteAPFloat(m_emu, rs1);
+                                     return m_emu.SetAccruedExceptions(res);
+                                   })
         .value_or(false);
   }
   bool operator()(FDIV_S inst) {
-    return zipOpt(inst.rs1.ReadAPFloat(m_emu, false),
-                  inst.rs2.ReadAPFloat(m_emu, false))
-        .transform([&](auto &&tup) {
-          auto [rs1, rs2] = tup;
-          auto res = rs1.divide(rs2, m_emu.GetRoundingMode());
-          inst.rd.WriteAPFloat(m_emu, rs1);
-          return m_emu.SetAccruedExceptions(res);
-        })
+    return llvm::transformOptional(zipOpt(inst.rs1.ReadAPFloat(m_emu, false),
+                                          inst.rs2.ReadAPFloat(m_emu, false)),
+                                   [&](auto &&tup) {
+                                     auto [rs1, rs2] = tup;
+                                     auto res = rs1.divide(
+                                         rs2, m_emu.GetRoundingMode());
+                                     inst.rd.WriteAPFloat(m_emu, rs1);
+                                     return m_emu.SetAccruedExceptions(res);
+                                   })
         .value_or(false);
   }
   bool operator()(FSQRT_S inst) {
@@ -1246,236 +1316,249 @@ class Executor {
     return false;
   }
   bool operator()(FSGNJ_S inst) {
-    return zipOpt(inst.rs1.ReadAPFloat(m_emu, false),
-                  inst.rs2.ReadAPFloat(m_emu, false))
-        .transform([&](auto &&tup) {
-          auto [rs1, rs2] = tup;
-          rs1.copySign(rs2);
-          return inst.rd.WriteAPFloat(m_emu, rs1);
-        })
+    return llvm::transformOptional(zipOpt(inst.rs1.ReadAPFloat(m_emu, false),
+                                          inst.rs2.ReadAPFloat(m_emu, false)),
+                                   [&](auto &&tup) {
+                                     auto [rs1, rs2] = tup;
+                                     rs1.copySign(rs2);
+                                     return inst.rd.WriteAPFloat(m_emu, rs1);
+                                   })
         .value_or(false);
   }
   bool operator()(FSGNJN_S inst) {
-    return zipOpt(inst.rs1.ReadAPFloat(m_emu, false),
-                  inst.rs2.ReadAPFloat(m_emu, false))
-        .transform([&](auto &&tup) {
-          auto [rs1, rs2] = tup;
-          rs1.copySign(-rs2);
-          return inst.rd.WriteAPFloat(m_emu, rs1);
-        })
+    return llvm::transformOptional(zipOpt(inst.rs1.ReadAPFloat(m_emu, false),
+                                          inst.rs2.ReadAPFloat(m_emu, false)),
+                                   [&](auto &&tup) {
+                                     auto [rs1, rs2] = tup;
+                                     rs1.copySign(-rs2);
+                                     return inst.rd.WriteAPFloat(m_emu, rs1);
+                                   })
         .value_or(false);
   }
   bool operator()(FSGNJX_S inst) {
-    return zipOpt(inst.rs1.ReadAPFloat(m_emu, false),
-                  inst.rs2.ReadAPFloat(m_emu, false))
-        .transform([&](auto &&tup) {
-          auto [rs1, rs2] = tup;
-          // spec: the sign bit is the XOR of the sign bits of rs1 and rs2.
-          // if rs1 and rs2 have the same signs
-          // set rs1 to positive
-          // else set rs1 to negative
-          if (rs1.isNegative() == rs2.isNegative()) {
-            rs1.clearSign();
-          } else {
-            rs1.clearSign();
-            rs1.changeSign();
-          }
-          return inst.rd.WriteAPFloat(m_emu, rs1);
-        })
+    return llvm::transformOptional(zipOpt(inst.rs1.ReadAPFloat(m_emu, false),
+                                          inst.rs2.ReadAPFloat(m_emu, false)),
+                                   [&](auto &&tup) {
+                                     auto [rs1, rs2] = tup;
+                                     // spec: the sign bit is the XOR of the
+                                     // sign bits of rs1 and rs2. if rs1 and rs2
+                                     // have the same signs set rs1 to positive
+                                     // else set rs1 to negative
+                                     if (rs1.isNegative() == rs2.isNegative()) {
+                                       rs1.clearSign();
+                                     } else {
+                                       rs1.clearSign();
+                                       rs1.changeSign();
+                                     }
+                                     return inst.rd.WriteAPFloat(m_emu, rs1);
+                                   })
         .value_or(false);
   }
   bool operator()(FMIN_S inst) {
-    return zipOpt(inst.rs1.ReadAPFloat(m_emu, false),
-                  inst.rs2.ReadAPFloat(m_emu, false))
-        .transform([&](auto &&tup) {
-          auto [rs1, rs2] = tup;
-          // If both inputs are NaNs, the result is the canonical NaN.
-          // If only one operand is a NaN, the result is the non-NaN operand.
-          // Signaling NaN inputs set the invalid operation exception flag, even
-          // when the result is not NaN.
-          if (rs1.isNaN() || rs2.isNaN())
-            m_emu.SetAccruedExceptions(llvm::APFloat::opInvalidOp);
-          if (rs1.isNaN() && rs2.isNaN()) {
-            auto canonicalNaN = llvm::APFloat::getQNaN(rs1.getSemantics());
-            return inst.rd.WriteAPFloat(m_emu, canonicalNaN);
-          }
-          return inst.rd.WriteAPFloat(m_emu, minnum(rs1, rs2));
-        })
+    return llvm::transformOptional(
+               zipOpt(inst.rs1.ReadAPFloat(m_emu, false),
+                      inst.rs2.ReadAPFloat(m_emu, false)),
+               [&](auto &&tup) {
+                 auto [rs1, rs2] = tup;
+                 // If both inputs are NaNs, the result is the canonical NaN.
+                 // If only one operand is a NaN, the result is the non-NaN
+                 // operand. Signaling NaN inputs set the invalid operation
+                 // exception flag, even when the result is not NaN.
+                 if (rs1.isNaN() || rs2.isNaN())
+                   m_emu.SetAccruedExceptions(llvm::APFloat::opInvalidOp);
+                 if (rs1.isNaN() && rs2.isNaN()) {
+                   auto canonicalNaN =
+                       llvm::APFloat::getQNaN(rs1.getSemantics());
+                   return inst.rd.WriteAPFloat(m_emu, canonicalNaN);
+                 }
+                 return inst.rd.WriteAPFloat(m_emu, minnum(rs1, rs2));
+               })
         .value_or(false);
   }
   bool operator()(FMAX_S inst) {
-    return zipOpt(inst.rs1.ReadAPFloat(m_emu, false),
-                  inst.rs2.ReadAPFloat(m_emu, false))
-        .transform([&](auto &&tup) {
-          auto [rs1, rs2] = tup;
-          if (rs1.isNaN() || rs2.isNaN())
-            m_emu.SetAccruedExceptions(llvm::APFloat::opInvalidOp);
-          if (rs1.isNaN() && rs2.isNaN()) {
-            auto canonicalNaN = llvm::APFloat::getQNaN(rs1.getSemantics());
-            return inst.rd.WriteAPFloat(m_emu, canonicalNaN);
-          }
-          return inst.rd.WriteAPFloat(m_emu, maxnum(rs1, rs2));
-        })
+    return llvm::transformOptional(
+               zipOpt(inst.rs1.ReadAPFloat(m_emu, false),
+                      inst.rs2.ReadAPFloat(m_emu, false)),
+               [&](auto &&tup) {
+                 auto [rs1, rs2] = tup;
+                 if (rs1.isNaN() || rs2.isNaN())
+                   m_emu.SetAccruedExceptions(llvm::APFloat::opInvalidOp);
+                 if (rs1.isNaN() && rs2.isNaN()) {
+                   auto canonicalNaN =
+                       llvm::APFloat::getQNaN(rs1.getSemantics());
+                   return inst.rd.WriteAPFloat(m_emu, canonicalNaN);
+                 }
+                 return inst.rd.WriteAPFloat(m_emu, maxnum(rs1, rs2));
+               })
         .value_or(false);
   }
   bool operator()(FCVT_W_S inst) {
-    return inst.rs1.ReadAPFloat(m_emu, false)
-        .transform([&](auto &&rs1) {
-          int32_t res = rs1.convertToFloat();
-          return inst.rd.Write(m_emu, uint64_t(res));
-        })
+    return llvm::transformOptional(inst.rs1.ReadAPFloat(m_emu, false),
+                                   [&](auto &&rs1) {
+                                     int32_t res = rs1.convertToFloat();
+                                     return inst.rd.Write(m_emu, uint64_t(res));
+                                   })
         .value_or(false);
   }
   bool operator()(FCVT_WU_S inst) {
-    return inst.rs1.ReadAPFloat(m_emu, false)
-        .transform([&](auto &&rs1) {
-          uint32_t res = rs1.convertToFloat();
-          return inst.rd.Write(m_emu, uint64_t(res));
-        })
+    return llvm::transformOptional(inst.rs1.ReadAPFloat(m_emu, false),
+                                   [&](auto &&rs1) {
+                                     uint32_t res = rs1.convertToFloat();
+                                     return inst.rd.Write(m_emu, uint64_t(res));
+                                   })
         .value_or(false);
   }
   bool operator()(FMV_X_W inst) {
-    return inst.rs1.ReadAPFloat(m_emu, false)
-        .transform([&](auto &&rs1) {
-          if (rs1.isNaN())
-            return inst.rd.Write(m_emu, 0x7fc00000);
-          auto bits = rs1.bitcastToAPInt();
-          return inst.rd.Write(m_emu, NanBoxing(uint64_t(bits.getSExtValue())));
-        })
+    return llvm::transformOptional(
+               inst.rs1.ReadAPFloat(m_emu, false),
+               [&](auto &&rs1) {
+                 if (rs1.isNaN())
+                   return inst.rd.Write(m_emu, 0x7fc00000);
+                 auto bits = rs1.bitcastToAPInt();
+                 return inst.rd.Write(m_emu,
+                                      NanBoxing(uint64_t(bits.getSExtValue())));
+               })
         .value_or(false);
   }
   bool operator()(FEQ_S inst) {
-    return zipOpt(inst.rs1.ReadAPFloat(m_emu, false),
-                  inst.rs2.ReadAPFloat(m_emu, false))
-        .transform([&](auto &&tup) {
-          auto [rs1, rs2] = tup;
-          if (rs1.isNaN() || rs2.isNaN()) {
-            if (rs1.isSignaling() || rs2.isSignaling())
-              m_emu.SetAccruedExceptions(llvm::APFloat::opInvalidOp);
-            return inst.rd.Write(m_emu, 0);
-          }
-          return inst.rd.Write(m_emu,
-                               rs1.compare(rs2) == llvm::APFloat::cmpEqual);
-        })
+    return llvm::transformOptional(
+               zipOpt(inst.rs1.ReadAPFloat(m_emu, false),
+                      inst.rs2.ReadAPFloat(m_emu, false)),
+               [&](auto &&tup) {
+                 auto [rs1, rs2] = tup;
+                 if (rs1.isNaN() || rs2.isNaN()) {
+                   if (rs1.isSignaling() || rs2.isSignaling())
+                     m_emu.SetAccruedExceptions(llvm::APFloat::opInvalidOp);
+                   return inst.rd.Write(m_emu, 0);
+                 }
+                 return inst.rd.Write(m_emu, rs1.compare(rs2) ==
+                                                 llvm::APFloat::cmpEqual);
+               })
         .value_or(false);
   }
   bool operator()(FLT_S inst) {
-    return zipOpt(inst.rs1.ReadAPFloat(m_emu, false),
-                  inst.rs2.ReadAPFloat(m_emu, false))
-        .transform([&](auto &&tup) {
-          auto [rs1, rs2] = tup;
-          if (rs1.isNaN() || rs2.isNaN()) {
-            m_emu.SetAccruedExceptions(llvm::APFloat::opInvalidOp);
-            return inst.rd.Write(m_emu, 0);
-          }
-          return inst.rd.Write(m_emu,
-                               rs1.compare(rs2) == llvm::APFloat::cmpLessThan);
-        })
+    return llvm::transformOptional(
+               zipOpt(inst.rs1.ReadAPFloat(m_emu, false),
+                      inst.rs2.ReadAPFloat(m_emu, false)),
+               [&](auto &&tup) {
+                 auto [rs1, rs2] = tup;
+                 if (rs1.isNaN() || rs2.isNaN()) {
+                   m_emu.SetAccruedExceptions(llvm::APFloat::opInvalidOp);
+                   return inst.rd.Write(m_emu, 0);
+                 }
+                 return inst.rd.Write(m_emu, rs1.compare(rs2) ==
+                                                 llvm::APFloat::cmpLessThan);
+               })
         .value_or(false);
   }
   bool operator()(FLE_S inst) {
-    return zipOpt(inst.rs1.ReadAPFloat(m_emu, false),
-                  inst.rs2.ReadAPFloat(m_emu, false))
-        .transform([&](auto &&tup) {
-          auto [rs1, rs2] = tup;
-          if (rs1.isNaN() || rs2.isNaN()) {
-            m_emu.SetAccruedExceptions(llvm::APFloat::opInvalidOp);
-            return inst.rd.Write(m_emu, 0);
-          }
-          return inst.rd.Write(m_emu, rs1.compare(rs2) !=
-                                          llvm::APFloat::cmpGreaterThan);
-        })
+    return llvm::transformOptional(
+               zipOpt(inst.rs1.ReadAPFloat(m_emu, false),
+                      inst.rs2.ReadAPFloat(m_emu, false)),
+               [&](auto &&tup) {
+                 auto [rs1, rs2] = tup;
+                 if (rs1.isNaN() || rs2.isNaN()) {
+                   m_emu.SetAccruedExceptions(llvm::APFloat::opInvalidOp);
+                   return inst.rd.Write(m_emu, 0);
+                 }
+                 return inst.rd.Write(m_emu, rs1.compare(rs2) !=
+                                                 llvm::APFloat::cmpGreaterThan);
+               })
         .value_or(false);
   }
   bool operator()(FCLASS_S inst) {
-    return inst.rs1.ReadAPFloat(m_emu, false)
-        .transform([&](auto &&rs1) {
-          uint64_t result = 0;
-          if (rs1.isInfinity() && rs1.isNegative())
-            result |= 1 << 0;
-          // neg normal
-          if (rs1.isNormal() && rs1.isNegative())
-            result |= 1 << 1;
-          // neg subnormal
-          if (rs1.isDenormal() && rs1.isNegative())
-            result |= 1 << 2;
-          if (rs1.isNegZero())
-            result |= 1 << 3;
-          if (rs1.isPosZero())
-            result |= 1 << 4;
-          // pos normal
-          if (rs1.isNormal() && !rs1.isNegative())
-            result |= 1 << 5;
-          // pos subnormal
-          if (rs1.isDenormal() && !rs1.isNegative())
-            result |= 1 << 6;
-          if (rs1.isInfinity() && !rs1.isNegative())
-            result |= 1 << 7;
-          if (rs1.isNaN()) {
-            if (rs1.isSignaling())
-              result |= 1 << 8;
-            else
-              result |= 1 << 9;
-          }
-          return inst.rd.Write(m_emu, result);
-        })
+    return llvm::transformOptional(inst.rs1.ReadAPFloat(m_emu, false),
+                                   [&](auto &&rs1) {
+                                     uint64_t result = 0;
+                                     if (rs1.isInfinity() && rs1.isNegative())
+                                       result |= 1 << 0;
+                                     // neg normal
+                                     if (rs1.isNormal() && rs1.isNegative())
+                                       result |= 1 << 1;
+                                     // neg subnormal
+                                     if (rs1.isDenormal() && rs1.isNegative())
+                                       result |= 1 << 2;
+                                     if (rs1.isNegZero())
+                                       result |= 1 << 3;
+                                     if (rs1.isPosZero())
+                                       result |= 1 << 4;
+                                     // pos normal
+                                     if (rs1.isNormal() && !rs1.isNegative())
+                                       result |= 1 << 5;
+                                     // pos subnormal
+                                     if (rs1.isDenormal() && !rs1.isNegative())
+                                       result |= 1 << 6;
+                                     if (rs1.isInfinity() && !rs1.isNegative())
+                                       result |= 1 << 7;
+                                     if (rs1.isNaN()) {
+                                       if (rs1.isSignaling())
+                                         result |= 1 << 8;
+                                       else
+                                         result |= 1 << 9;
+                                     }
+                                     return inst.rd.Write(m_emu, result);
+                                   })
         .value_or(false);
   }
   bool operator()(FCVT_S_W inst) {
-    return inst.rs1.ReadI32(m_emu)
-        .transform([&](auto &&rs1) {
-          llvm::APFloat apf(llvm::APFloat::IEEEsingle(), rs1);
-          return inst.rd.WriteAPFloat(m_emu, apf);
-        })
+    return llvm::transformOptional(inst.rs1.ReadI32(m_emu),
+                                   [&](auto &&rs1) {
+                                     llvm::APFloat apf(
+                                         llvm::APFloat::IEEEsingle(), rs1);
+                                     return inst.rd.WriteAPFloat(m_emu, apf);
+                                   })
         .value_or(false);
   }
   bool operator()(FCVT_S_WU inst) {
-    return inst.rs1.ReadU32(m_emu)
-        .transform([&](auto &&rs1) {
-          llvm::APFloat apf(llvm::APFloat::IEEEsingle(), rs1);
-          return inst.rd.WriteAPFloat(m_emu, apf);
-        })
+    return llvm::transformOptional(inst.rs1.ReadU32(m_emu),
+                                   [&](auto &&rs1) {
+                                     llvm::APFloat apf(
+                                         llvm::APFloat::IEEEsingle(), rs1);
+                                     return inst.rd.WriteAPFloat(m_emu, apf);
+                                   })
         .value_or(false);
   }
   bool operator()(FMV_W_X inst) {
-    return inst.rs1.Read(m_emu)
-        .transform([&](auto &&rs1) {
-          llvm::APInt apInt(32, NanUnBoxing(rs1));
-          llvm::APFloat apf(apInt.bitsToFloat());
-          return inst.rd.WriteAPFloat(m_emu, apf);
-        })
+    return llvm::transformOptional(inst.rs1.Read(m_emu),
+                                   [&](auto &&rs1) {
+                                     llvm::APInt apInt(32, NanUnBoxing(rs1));
+                                     llvm::APFloat apf(apInt.bitsToFloat());
+                                     return inst.rd.WriteAPFloat(m_emu, apf);
+                                   })
         .value_or(false);
   }
   bool operator()(FCVT_L_S inst) {
-    return inst.rs1.ReadAPFloat(m_emu, false)
-        .transform([&](auto &&rs1) {
-          int64_t res = rs1.convertToFloat();
-          return inst.rd.Write(m_emu, uint64_t(res));
-        })
+    return llvm::transformOptional(inst.rs1.ReadAPFloat(m_emu, false),
+                                   [&](auto &&rs1) {
+                                     int64_t res = rs1.convertToFloat();
+                                     return inst.rd.Write(m_emu, uint64_t(res));
+                                   })
         .value_or(false);
   }
   bool operator()(FCVT_LU_S inst) {
-    return inst.rs1.ReadAPFloat(m_emu, false)
-        .transform([&](auto &&rs1) {
-          uint64_t res = rs1.convertToFloat();
-          return inst.rd.Write(m_emu, res);
-        })
+    return llvm::transformOptional(inst.rs1.ReadAPFloat(m_emu, false),
+                                   [&](auto &&rs1) {
+                                     uint64_t res = rs1.convertToFloat();
+                                     return inst.rd.Write(m_emu, res);
+                                   })
         .value_or(false);
   }
   bool operator()(FCVT_S_L inst) {
-    return inst.rs1.ReadI64(m_emu)
-        .transform([&](auto &&rs1) {
-          llvm::APFloat apf(llvm::APFloat::IEEEsingle(), rs1);
-          return inst.rd.WriteAPFloat(m_emu, apf);
-        })
+    return llvm::transformOptional(inst.rs1.ReadI64(m_emu),
+                                   [&](auto &&rs1) {
+                                     llvm::APFloat apf(
+                                         llvm::APFloat::IEEEsingle(), rs1);
+                                     return inst.rd.WriteAPFloat(m_emu, apf);
+                                   })
         .value_or(false);
   }
   bool operator()(FCVT_S_LU inst) {
-    return inst.rs1.Read(m_emu)
-        .transform([&](auto &&rs1) {
-          llvm::APFloat apf(llvm::APFloat::IEEEsingle(), rs1);
-          return inst.rd.WriteAPFloat(m_emu, apf);
-        })
+    return llvm::transformOptional(inst.rs1.Read(m_emu),
+                                   [&](auto &&rs1) {
+                                     llvm::APFloat apf(
+                                         llvm::APFloat::IEEEsingle(), rs1);
+                                     return inst.rd.WriteAPFloat(m_emu, apf);
+                                   })
         .value_or(false);
   }
   bool operator()(INVALID inst) { return false; }
@@ -1515,8 +1598,8 @@ bool EmulateInstructionRISCV::EvaluateInstruction(uint32_t options) {
 
 llvm::Optional<DecodeResult>
 EmulateInstructionRISCV::ReadInstructionAt(lldb::addr_t addr) {
-  return ReadMem<uint32_t>(addr)
-      .transform([&](uint32_t inst) { return Decode(inst); })
+  return llvm::transformOptional(ReadMem<uint32_t>(addr),
+                                 [&](uint32_t inst) { return Decode(inst); })
       .value_or(std::nullopt);
 }
 

diff  --git a/lldb/source/Plugins/Process/Linux/IntelPTSingleBufferTrace.cpp b/lldb/source/Plugins/Process/Linux/IntelPTSingleBufferTrace.cpp
index 0ce901e7becb6..a33108dbdb12b 100644
--- a/lldb/source/Plugins/Process/Linux/IntelPTSingleBufferTrace.cpp
+++ b/lldb/source/Plugins/Process/Linux/IntelPTSingleBufferTrace.cpp
@@ -251,7 +251,8 @@ Expected<IntelPTSingleBufferTrace> IntelPTSingleBufferTrace::Start(
       (request.ipt_trace_size + page_size - 1) / page_size));
 
   Expected<perf_event_attr> attr = CreateIntelPTPerfEventConfiguration(
-      request.enable_tsc, request.psb_period.transform([](int value) {
+      request.enable_tsc,
+      llvm::transformOptional(request.psb_period, [](int value) {
         return static_cast<uint64_t>(value);
       }));
   if (!attr)

diff  --git a/lldb/unittests/Instruction/RISCV/TestRISCVEmulator.cpp b/lldb/unittests/Instruction/RISCV/TestRISCVEmulator.cpp
index 164a0d7391042..88e0fb89c9d46 100644
--- a/lldb/unittests/Instruction/RISCV/TestRISCVEmulator.cpp
+++ b/lldb/unittests/Instruction/RISCV/TestRISCVEmulator.cpp
@@ -88,8 +88,9 @@ struct RISCVEmulatorTester : public EmulateInstructionRISCV, testing::Test {
   };
 
   bool DecodeAndExecute(uint32_t inst, bool ignore_cond) {
-    return Decode(inst)
-        .transform([&](DecodeResult res) { return Execute(res, ignore_cond); })
+    return llvm::transformOptional(
+               Decode(inst),
+               [&](DecodeResult res) { return Execute(res, ignore_cond); })
         .value_or(false);
   }
 


        


More information about the lldb-commits mailing list