[llvm] [RISCV] Support postRA vsetvl insertion pass (PR #70549)

Luke Lau via llvm-commits llvm-commits at lists.llvm.org
Mon Nov 13 08:21:48 PST 2023


================
@@ -44,6 +45,86 @@ static cl::opt<bool> UseStrictAsserts(
 
 namespace {
 
+// Return true when CandidateDefMI can arrive UserMI without reach other defMI
+// thought CFG. Otherwise, if it:
+//    1. Encounter the DefMI again
+//    2. Seen the all BasicBlock can reach
+// return false
+static bool isReachingDef(const MachineInstr &UserMI,
+                          const MachineInstr &CandidateDefMI, Register Reg,
+                          const MachineRegisterInfo *MRI) {
+  std::queue<std::pair<const MachineBasicBlock *, bool>> MBBQ;
+  llvm::DenseMap<int, bool> SeenMBB;
+
+  MBBQ.push(std::make_pair(CandidateDefMI.getParent(), false));
+  while (!MBBQ.empty()) {
+
+    const MachineBasicBlock *CurrMBB = MBBQ.front().first;
+    bool SeenDef = MBBQ.front().second;
+    MBBQ.pop();
+    SeenMBB[CurrMBB->getNumber()] = true;
+    bool NeedSkip = false;
+    for (auto &MI : *CurrMBB) {
+      // If we encounter DefMI more than once, this CandidateDefMI is not
+      // reaching definition for UserMI.
+      if (SeenDef && llvm::any_of(MRI->def_instructions(Reg),
+                                  [&MI](const MachineInstr &DefMI) {
+                                    return DefMI.isIdenticalTo(MI);
+                                  })) {
+        NeedSkip = true;
+        break;
+      }
+
+      if (MI.isIdenticalTo(CandidateDefMI))
+        SeenDef = true;
+
+      if (SeenDef && MI.isIdenticalTo(UserMI))
+        return true;
+    }
+
+    if (NeedSkip)
+      continue;
+
+    for (auto *Succ : CurrMBB->successors()) {
+      if (SeenMBB[Succ->getNumber()])
+        continue;
+      MBBQ.push(std::make_pair(Succ, SeenDef));
+    }
+  }
+
+  return false;
+}
----------------
lukel97 wrote:

This case ends up taking a pathologically long time/doesn't seem to terminate:

```llvm
declare <32 x i8> @llvm.masked.gather.v32i8.v32p0(<32 x ptr> %ptrs, i32, <32 x i1> %m, <32 x i8> %passthru)
define <32 x i8> @mgather_baseidx_v32i8(ptr %base, <32 x i8> %idxs, <32 x i1> %m, <32 x i8> %passthru) {
  %ptrs = getelementptr inbounds i8, ptr %base, <32 x i8> %idxs
  %v = call <32 x i8> @llvm.masked.gather.v32i8.v32p0(<32 x ptr> %ptrs, i32 2, <32 x i1> %m, <32 x i8> %passthru)
  ret <32 x i8> %v
}
```

With `-mattr=+m,+d,+zfh,+zvfh,+zve32f,+zvl128b -target-abi=lp64d -riscv-enable-sink-fold -verify-machineinstrs -print-after=riscv-insert-vsetvli scratch/mgather_baseidx_v32i8.ll` (and split-ra and post-ra insertion)

By adding another `SeenMBB[Succ->getNumber()] = true;` when pushing to the queue I was able to get it to finish, but it still takes a very long time to run. I haven't looked at the CFG that's generated for this, so I'm not sure why it seems to explode. Is there a better way to get the reaching definition from just querying the liveintervals?

https://github.com/llvm/llvm-project/pull/70549


More information about the llvm-commits mailing list