llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-webassembly

Author: Aiden Grossman (boomanaiden154)

<details>
<summary>Changes</summary>

Standard NewPM pass porting. Made a little bit annoying by the module
caching that I'm not sure helps much, but I've left it in.


---
Full diff: https://github.com/llvm/llvm-project/pull/209043.diff


5 Files Affected:

- (modified) llvm/lib/Target/WebAssembly/WebAssembly.h (+15-1) 
- (modified) llvm/lib/Target/WebAssembly/WebAssemblyCodeGenPassBuilder.cpp (+1) 
- (modified) llvm/lib/Target/WebAssembly/WebAssemblyPassRegistry.def (+1) 
- (modified) llvm/lib/Target/WebAssembly/WebAssemblyReduceToAnyAllTrue.cpp 
(+109-88) 
- (modified) llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp (+2-1) 


``````````diff
diff --git a/llvm/lib/Target/WebAssembly/WebAssembly.h 
b/llvm/lib/Target/WebAssembly/WebAssembly.h
index c5b978402bc50..bfc2107858165 100644
--- a/llvm/lib/Target/WebAssembly/WebAssembly.h
+++ b/llvm/lib/Target/WebAssembly/WebAssembly.h
@@ -63,7 +63,21 @@ class WebAssemblyOptimizeReturnedPass
 
 FunctionPass *createWebAssemblyOptimizeReturnedLegacyPass();
 FunctionPass *createWebAssemblyRefTypeMem2Local();
-FunctionPass *createWebAssemblyReduceToAnyAllTrue(WebAssemblyTargetMachine 
&TM);
+
+class WebAssemblyReduceToAnyAllTruePass
+    : public RequiredPassInfoMixin<WebAssemblyReduceToAnyAllTruePass> {
+private:
+  Module *CachedModule = nullptr;
+  bool ModuleHasInterestingIntrinsics = false;
+  WebAssemblyTargetMachine &TM;
+
+public:
+  WebAssemblyReduceToAnyAllTruePass(WebAssemblyTargetMachine &TM) : TM(TM) {}
+  PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM);
+};
+
+FunctionPass *
+createWebAssemblyReduceToAnyAllTrueLegacyPass(WebAssemblyTargetMachine &TM);
 
 // GlobalISel
 InstructionSelector *
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyCodeGenPassBuilder.cpp 
b/llvm/lib/Target/WebAssembly/WebAssemblyCodeGenPassBuilder.cpp
index d867623f173cb..43990276561e0 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyCodeGenPassBuilder.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyCodeGenPassBuilder.cpp
@@ -113,6 +113,7 @@ void 
WebAssemblyCodeGenPassBuilder::addIRPasses(PassManagerWrapper &PMW) const {
 
   // Try to expand `vecreduce_{and, or}` into `{any, all}_true`.
   // TODO(boomanaiden154): WebAssemblyReduceToAnyAllTrue
+  addFunctionPass(WebAssemblyReduceToAnyAllTruePass(TM), PMW);
 
   Base::addIRPasses(PMW);
 }
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyPassRegistry.def 
b/llvm/lib/Target/WebAssembly/WebAssemblyPassRegistry.def
index fb70a7f0e1321..a771512786b6e 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyPassRegistry.def
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyPassRegistry.def
@@ -23,6 +23,7 @@ MODULE_PASS("wasm-lower-em-ehsjlj", 
WebAssemblyLowerEmscriptenEHSjLjPass())
 #define FUNCTION_PASS(NAME, CREATE_PASS)
 #endif
 FUNCTION_PASS("wasm-optimize-returned", WebAssemblyOptimizeReturnedPass())
+FUNCTION_PASS("wasm-reduce-to-any-all-true", 
WebAssemblyReduceToAnyAllTruePass(*this))
 #undef FUNCTION_PASS
 
 #ifndef MACHINE_FUNCTION_PASS
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyReduceToAnyAllTrue.cpp 
b/llvm/lib/Target/WebAssembly/WebAssemblyReduceToAnyAllTrue.cpp
index 4240c8978fd6d..6b2358c1a2d00 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyReduceToAnyAllTrue.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyReduceToAnyAllTrue.cpp
@@ -1,9 +1,11 @@
 #include "WebAssembly.h"
 #include "WebAssemblySubtarget.h"
 #include "WebAssemblyTargetMachine.h"
+#include "llvm/IR/Analysis.h"
 #include "llvm/IR/IRBuilder.h"
 #include "llvm/IR/IntrinsicsWebAssembly.h"
 #include "llvm/IR/Module.h"
+#include "llvm/IR/PassManager.h"
 #include "llvm/IR/PatternMatch.h"
 #include "llvm/Pass.h"
 
@@ -11,123 +13,142 @@ using namespace llvm;
 using namespace llvm::PatternMatch;
 
 namespace {
-struct WebAssemblyReduceToAnyAllTrue final : FunctionPass {
+struct WebAssemblyReduceToAnyAllTrueLegacy final : FunctionPass {
   static char ID;
 
   WebAssemblyTargetMachine &TM;
-  const Module *CachedModule = nullptr;
+  Module *CachedModule = nullptr;
   bool ModuleHasInterestingIntrinsics = false;
 
-  WebAssemblyReduceToAnyAllTrue(WebAssemblyTargetMachine &TM)
+  WebAssemblyReduceToAnyAllTrueLegacy(WebAssemblyTargetMachine &TM)
       : FunctionPass(ID), TM(TM) {}
 
   StringRef getPassName() const override {
     return "WebAssembly convert reduce to any_true/all_true";
   }
 
-  bool hasInterestingIntrinsics(const Module &M) {
-    if (CachedModule == &M)
-      return ModuleHasInterestingIntrinsics;
+  bool runOnFunction(Function &F) override;
+};
+} // end anonymous namespace
 
-    CachedModule = &M;
-    ModuleHasInterestingIntrinsics = false;
+char WebAssemblyReduceToAnyAllTrueLegacy::ID = 0;
 
-    for (const Function &Fn : M.functions()) {
-      switch (Fn.getIntrinsicID()) {
-      case Intrinsic::vector_reduce_or:
-      case Intrinsic::vector_reduce_and:
-        ModuleHasInterestingIntrinsics = true;
-        return true;
-      default:
-        break;
-      }
+static bool hasInterestingIntrinsics(Module &M, Module *&CachedModule,
+                                     bool &ModuleHasInterestingIntrinsics) {
+  if (CachedModule == &M)
+    return ModuleHasInterestingIntrinsics;
+
+  CachedModule = &M;
+  ModuleHasInterestingIntrinsics = false;
+
+  for (const Function &Fn : M.functions()) {
+    switch (Fn.getIntrinsicID()) {
+    case Intrinsic::vector_reduce_or:
+    case Intrinsic::vector_reduce_and:
+      ModuleHasInterestingIntrinsics = true;
+      return true;
+    default:
+      break;
     }
+  }
+
+  return false;
+}
 
+static bool reduceToAnyAllTrue(Function &F, WebAssemblyTargetMachine &TM,
+                               Module *&CachedModule,
+                               bool &ModuleHasInterestingIntrinsics) {
+  if (!TM.getSubtarget<WebAssemblySubtarget>(F).hasSIMD128())
     return false;
-  }
 
-  bool runOnFunction(Function &F) override {
-    if (!TM.getSubtarget<WebAssemblySubtarget>(F).hasSIMD128())
-      return false;
+  if (!hasInterestingIntrinsics(*F.getParent(), CachedModule,
+                                ModuleHasInterestingIntrinsics))
+    return false;
 
-    if (!hasInterestingIntrinsics(*F.getParent()))
-      return false;
+  bool Changed = false;
 
-    bool Changed = false;
+  for (auto &BB : F) {
+    for (auto It = BB.begin(), E = BB.end(); It != E;) {
+      Instruction *I = &*It++;
+      auto *Cmp = dyn_cast<ICmpInst>(I);
+      if (!Cmp || Cmp->getPredicate() != ICmpInst::ICMP_NE)
+        continue;
 
-    for (auto &BB : F) {
-      for (auto It = BB.begin(), E = BB.end(); It != E;) {
-        Instruction *I = &*It++;
-        auto *Cmp = dyn_cast<ICmpInst>(I);
-        if (!Cmp || Cmp->getPredicate() != ICmpInst::ICMP_NE)
-          continue;
+      Value *Reduce = nullptr;
+      if (!match(Cmp, m_ICmp(m_Value(Reduce), m_ZeroInt())))
+        continue;
 
-        Value *Reduce = nullptr;
-        if (!match(Cmp, m_ICmp(m_Value(Reduce), m_ZeroInt())))
-          continue;
+      auto *II = dyn_cast<IntrinsicInst>(Reduce);
+      if (!II || !II->hasOneUse())
+        continue;
 
-        auto *II = dyn_cast<IntrinsicInst>(Reduce);
-        if (!II || !II->hasOneUse())
-          continue;
+      IRBuilder<> B(Cmp);
+      Value *Vec = II->getArgOperand(0);
+      Module *M = F.getParent();
 
-        IRBuilder<> B(Cmp);
-        Value *Vec = II->getArgOperand(0);
-        Module *M = F.getParent();
-
-        auto makeIntrinsic = [&](Intrinsic::ID ID, Value *Arg) {
-          Function *Fn =
-              Intrinsic::getOrInsertDeclaration(M, ID, {Arg->getType()});
-          return B.CreateCall(Fn, {Arg});
-        };
-
-        Value *New = nullptr;
-
-        switch (II->getIntrinsicID()) {
-        case Intrinsic::vector_reduce_or: {
-          // reduce.or(X) != 0  -> anytrue(X)
-          Value *Any = makeIntrinsic(Intrinsic::wasm_anytrue, Vec);
-          New = B.CreateICmpNE(Any, ConstantInt::get(Any->getType(), 0));
-          break;
-        }
-
-        case Intrinsic::vector_reduce_and: {
-          // reduce.and(zext (icmp ne X, zeroinitializer)) != 0  -> alltrue(X)
-
-          // Match: zext (icmp ne X, 0) from <N x i1> to <N x iX>
-          CmpPredicate Pred;
-          Value *LHS = nullptr;
-          if (!match(Vec, m_ZExt(m_c_ICmp(Pred, m_Value(LHS), m_Zero()))))
-            continue;
-          if (Pred != ICmpInst::ICMP_NE)
-            continue;
-
-          Value *All = makeIntrinsic(Intrinsic::wasm_alltrue, LHS);
-          New = B.CreateICmpNE(All, ConstantInt::get(All->getType(), 0));
-          break;
-        }
-
-        default:
-          continue;
-        }
+      auto makeIntrinsic = [&](Intrinsic::ID ID, Value *Arg) {
+        Function *Fn =
+            Intrinsic::getOrInsertDeclaration(M, ID, {Arg->getType()});
+        return B.CreateCall(Fn, {Arg});
+      };
+
+      Value *New = nullptr;
 
-        Cmp->replaceAllUsesWith(New);
-        Cmp->eraseFromParent();
+      switch (II->getIntrinsicID()) {
+      case Intrinsic::vector_reduce_or: {
+        // reduce.or(X) != 0  -> anytrue(X)
+        Value *Any = makeIntrinsic(Intrinsic::wasm_anytrue, Vec);
+        New = B.CreateICmpNE(Any, ConstantInt::get(Any->getType(), 0));
+        break;
+      }
 
-        if (II->use_empty())
-          II->eraseFromParent();
+      case Intrinsic::vector_reduce_and: {
+        // reduce.and(zext (icmp ne X, zeroinitializer)) != 0  -> alltrue(X)
 
-        Changed = true;
+        // Match: zext (icmp ne X, 0) from <N x i1> to <N x iX>
+        CmpPredicate Pred;
+        Value *LHS = nullptr;
+        if (!match(Vec, m_ZExt(m_c_ICmp(Pred, m_Value(LHS), m_Zero()))))
+          continue;
+        if (Pred != ICmpInst::ICMP_NE)
+          continue;
+
+        Value *All = makeIntrinsic(Intrinsic::wasm_alltrue, LHS);
+        New = B.CreateICmpNE(All, ConstantInt::get(All->getType(), 0));
+        break;
       }
-    }
 
-    return Changed;
+      default:
+        continue;
+      }
+
+      Cmp->replaceAllUsesWith(New);
+      Cmp->eraseFromParent();
+
+      if (II->use_empty())
+        II->eraseFromParent();
+
+      Changed = true;
+    }
   }
-};
-} // end anonymous namespace
 
-char WebAssemblyReduceToAnyAllTrue::ID = 0;
+  return Changed;
+}
+
+bool WebAssemblyReduceToAnyAllTrueLegacy::runOnFunction(Function &F) {
+  return reduceToAnyAllTrue(F, TM, CachedModule,
+                            ModuleHasInterestingIntrinsics);
+}
+
+PreservedAnalyses
+WebAssemblyReduceToAnyAllTruePass::run(Function &F,
+                                       FunctionAnalysisManager &FAM) {
+  return reduceToAnyAllTrue(F, TM, CachedModule, 
ModuleHasInterestingIntrinsics)
+             ? PreservedAnalyses::none().preserveSet<CFGAnalyses>()
+             : PreservedAnalyses::all();
+}
 
-FunctionPass *
-llvm::createWebAssemblyReduceToAnyAllTrue(WebAssemblyTargetMachine &TM) {
-  return new WebAssemblyReduceToAnyAllTrue(TM);
+FunctionPass *llvm::createWebAssemblyReduceToAnyAllTrueLegacyPass(
+    WebAssemblyTargetMachine &TM) {
+  return new WebAssemblyReduceToAnyAllTrueLegacy(TM);
 }
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp 
b/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
index 1bdb8a5decbe6..ac292f5c665c1 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
@@ -524,7 +524,8 @@ void WebAssemblyPassConfig::addIRPasses() {
   addPass(createIndirectBrExpandPass());
 
   // Try to expand `vecreduce_{and, or}` into `{any, all}_true`.
-  addPass(createWebAssemblyReduceToAnyAllTrue(getWebAssemblyTargetMachine()));
+  addPass(createWebAssemblyReduceToAnyAllTrueLegacyPass(
+      getWebAssemblyTargetMachine()));
 
   TargetPassConfig::addIRPasses();
 }

``````````

</details>


https://github.com/llvm/llvm-project/pull/209043
_______________________________________________
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits

Reply via email to