[llvm] 69b8cf4 - [SandboxVec][BottomUpVec] Add cost estimation and tr-accept-or-revert pass (#126325)

via llvm-commits llvm-commits at lists.llvm.org
Sat Feb 8 08:34:22 PST 2025


Author: vporpo
Date: 2025-02-08T08:34:18-08:00
New Revision: 69b8cf4f0621b359b487ad41887c20984be53a34

URL: https://github.com/llvm/llvm-project/commit/69b8cf4f0621b359b487ad41887c20984be53a34
DIFF: https://github.com/llvm/llvm-project/commit/69b8cf4f0621b359b487ad41887c20984be53a34.diff

LOG: [SandboxVec][BottomUpVec] Add cost estimation and tr-accept-or-revert pass (#126325)

The TransactionAcceptOrRevert pass is the final pass in the Sandbox
Vectorizer's default pass pipeline. It's job is to check the cost
before/after vectorization and accept or revert the IR to its original
state.

Since we are now starting the transaction in BottomUpVec, tests that run
a custom pipeline need to accept the transaction. This is done with the
help of the TransactionAlwaysAccept pass (tr-accept).

Added: 
    llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/TransactionAcceptOrRevert.h
    llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/TransactionAlwaysAccept.h
    llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/TransactionAcceptOrRevert.cpp
    llvm/test/Transforms/SandboxVectorizer/X86/simple_cost_test.ll

Modified: 
    llvm/include/llvm/SandboxIR/Tracker.h
    llvm/lib/SandboxIR/Tracker.cpp
    llvm/lib/Transforms/Vectorize/CMakeLists.txt
    llvm/lib/Transforms/Vectorize/SandboxVectorizer/DependencyGraph.cpp
    llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/BottomUpVec.cpp
    llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/PassRegistry.def
    llvm/lib/Transforms/Vectorize/SandboxVectorizer/SandboxVectorizer.cpp
    llvm/lib/Transforms/Vectorize/SandboxVectorizer/SandboxVectorizerPassBuilder.cpp
    llvm/test/Transforms/SandboxVectorizer/bottomup_basic.ll
    llvm/test/Transforms/SandboxVectorizer/bottomup_seed_slice.ll
    llvm/test/Transforms/SandboxVectorizer/bottomup_seed_slice_pow2.ll
    llvm/test/Transforms/SandboxVectorizer/cross_bbs.ll
    llvm/test/Transforms/SandboxVectorizer/default_pass_pipeline.ll
    llvm/test/Transforms/SandboxVectorizer/pack.ll
    llvm/test/Transforms/SandboxVectorizer/repeated_instrs.ll
    llvm/test/Transforms/SandboxVectorizer/scheduler.ll
    llvm/test/Transforms/SandboxVectorizer/special_opcodes.ll
    llvm/unittests/SandboxIR/TrackerTest.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/SandboxIR/Tracker.h b/llvm/include/llvm/SandboxIR/Tracker.h
index 9a031f327083740..f7b469965eae876 100644
--- a/llvm/include/llvm/SandboxIR/Tracker.h
+++ b/llvm/include/llvm/SandboxIR/Tracker.h
@@ -440,8 +440,9 @@ class ShuffleVectorSetMask final : public IRChangeBase {
 class Tracker {
 public:
   enum class TrackerState {
-    Disabled, ///> Tracking is disabled
-    Record,   ///> Tracking changes
+    Disabled,  ///> Tracking is disabled
+    Record,    ///> Tracking changes
+    Reverting, ///> Reverting changes
   };
 
 private:
@@ -473,6 +474,8 @@ class Tracker {
 
   ~Tracker();
   Context &getContext() const { return Ctx; }
+  /// \Returns true if there are no changes tracked.
+  bool empty() const { return Changes.empty(); }
   /// Record \p Change and take ownership. This is the main function used to
   /// track Sandbox IR changes.
   void track(std::unique_ptr<IRChangeBase> &&Change) {

diff  --git a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/TransactionAcceptOrRevert.h b/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/TransactionAcceptOrRevert.h
new file mode 100644
index 000000000000000..fce9cc0c1bde778
--- /dev/null
+++ b/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/TransactionAcceptOrRevert.h
@@ -0,0 +1,30 @@
+//===- TransactionAcceptOrRevert.h ------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This is a region pass that checks the region cost before/after vectorization
+// and accepts the state of Sandbox IR if the cost is better, or otherwise
+// reverts it.
+//
+
+#ifndef LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_PASSES_TRANSACTIONACCEPTORREVERT_H
+#define LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_PASSES_TRANSACTIONACCEPTORREVERT_H
+
+#include "llvm/SandboxIR/Pass.h"
+#include "llvm/SandboxIR/Region.h"
+
+namespace llvm::sandboxir {
+
+class TransactionAcceptOrRevert : public RegionPass {
+public:
+  TransactionAcceptOrRevert() : RegionPass("tr-accept-or-revert") {}
+  bool runOnRegion(Region &Rgn, const Analyses &A) final;
+};
+
+} // namespace llvm::sandboxir
+
+#endif // LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_PASSES_TRANSACTIONACCEPTORREVERT_H

diff  --git a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/TransactionAlwaysAccept.h b/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/TransactionAlwaysAccept.h
new file mode 100644
index 000000000000000..ed6cf1bf7cf51e5
--- /dev/null
+++ b/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/TransactionAlwaysAccept.h
@@ -0,0 +1,34 @@
+//===- TransactionAlwaysAccept.h --------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This is a region pass that always accepts the transaction without checking
+// its cost. This is mainly used as a final pass in lit tests.
+//
+
+#ifndef LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_PASSES_TRANSACTIONALWAYSACCEPT_H
+#define LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_PASSES_TRANSACTIONALWAYSACCEPT_H
+
+#include "llvm/SandboxIR/Pass.h"
+#include "llvm/SandboxIR/Region.h"
+
+namespace llvm::sandboxir {
+
+class TransactionAlwaysAccept : public RegionPass {
+public:
+  TransactionAlwaysAccept() : RegionPass("tr-accept") {}
+  bool runOnRegion(Region &Rgn, const Analyses &A) final {
+    auto &Tracker = Rgn.getContext().getTracker();
+    bool HasChanges = !Tracker.empty();
+    Tracker.accept();
+    return HasChanges;
+  }
+};
+
+} // namespace llvm::sandboxir
+
+#endif // LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_PASSES_TRANSACTIONALWAYSACCEPT_H

diff  --git a/llvm/lib/SandboxIR/Tracker.cpp b/llvm/lib/SandboxIR/Tracker.cpp
index 5fa9f181055ca2f..4fa9e11ae0d4eae 100644
--- a/llvm/lib/SandboxIR/Tracker.cpp
+++ b/llvm/lib/SandboxIR/Tracker.cpp
@@ -347,13 +347,14 @@ void Tracker::save() {
 
 void Tracker::revert() {
   assert(State == TrackerState::Record && "Forgot to save()!");
-  State = TrackerState::Disabled;
+  State = TrackerState::Reverting;
   for (auto &Change : reverse(Changes))
     Change->revert(*this);
   Changes.clear();
 #if !defined(NDEBUG) && defined(EXPENSIVE_CHECKS)
   SnapshotChecker.expectNoDiff();
 #endif
+  State = TrackerState::Disabled;
 }
 
 void Tracker::accept() {

diff  --git a/llvm/lib/Transforms/Vectorize/CMakeLists.txt b/llvm/lib/Transforms/Vectorize/CMakeLists.txt
index e5fabd318b82cc7..872e055294d5574 100644
--- a/llvm/lib/Transforms/Vectorize/CMakeLists.txt
+++ b/llvm/lib/Transforms/Vectorize/CMakeLists.txt
@@ -9,6 +9,7 @@ add_llvm_component_library(LLVMVectorize
   SandboxVectorizer/Legality.cpp
   SandboxVectorizer/Passes/BottomUpVec.cpp
   SandboxVectorizer/Passes/RegionsFromMetadata.cpp
+  SandboxVectorizer/Passes/TransactionAcceptOrRevert.cpp
   SandboxVectorizer/SandboxVectorizer.cpp
   SandboxVectorizer/SandboxVectorizerPassBuilder.cpp
   SandboxVectorizer/Scheduler.cpp

diff  --git a/llvm/lib/Transforms/Vectorize/SandboxVectorizer/DependencyGraph.cpp b/llvm/lib/Transforms/Vectorize/SandboxVectorizer/DependencyGraph.cpp
index 2680667afc4de29..06a5e3bed7f0311 100644
--- a/llvm/lib/Transforms/Vectorize/SandboxVectorizer/DependencyGraph.cpp
+++ b/llvm/lib/Transforms/Vectorize/SandboxVectorizer/DependencyGraph.cpp
@@ -368,6 +368,9 @@ MemDGNode *DependencyGraph::getMemDGNodeAfter(DGNode *N, bool IncludingN,
 }
 
 void DependencyGraph::notifyCreateInstr(Instruction *I) {
+  if (Ctx->getTracker().getState() == Tracker::TrackerState::Reverting)
+    // We don't maintain the DAG while reverting.
+    return;
   // Nothing to do if the node is not in the focus range of the DAG.
   if (!(DAGInterval.contains(I) || DAGInterval.touches(I)))
     return;
@@ -405,6 +408,9 @@ void DependencyGraph::notifyCreateInstr(Instruction *I) {
 }
 
 void DependencyGraph::notifyMoveInstr(Instruction *I, const BBIterator &To) {
+  if (Ctx->getTracker().getState() == Tracker::TrackerState::Reverting)
+    // We don't maintain the DAG while reverting.
+    return;
   // NOTE: This function runs before `I` moves to its new destination.
   BasicBlock *BB = To.getNodeParent();
   assert(!(To != BB->end() && &*To == I->getNextNode()) &&
@@ -472,6 +478,9 @@ void DependencyGraph::notifyMoveInstr(Instruction *I, const BBIterator &To) {
 }
 
 void DependencyGraph::notifyEraseInstr(Instruction *I) {
+  if (Ctx->getTracker().getState() == Tracker::TrackerState::Reverting)
+    // We don't maintain the DAG while reverting.
+    return;
   // Update the MemDGNode chain if this is a memory node.
   if (auto *MemN = dyn_cast_or_null<MemDGNode>(getNodeOrNull(I))) {
     auto *PrevMemN = getMemDGNodeBefore(MemN, /*IncludingN=*/false);

diff  --git a/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/BottomUpVec.cpp b/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/BottomUpVec.cpp
index 6f65657d297906b..507d16324012700 100644
--- a/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/BottomUpVec.cpp
+++ b/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/BottomUpVec.cpp
@@ -12,6 +12,7 @@
 #include "llvm/SandboxIR/Function.h"
 #include "llvm/SandboxIR/Instruction.h"
 #include "llvm/SandboxIR/Module.h"
+#include "llvm/SandboxIR/Region.h"
 #include "llvm/SandboxIR/Utils.h"
 #include "llvm/Transforms/Vectorize/SandboxVectorizer/SandboxVectorizerPassBuilder.h"
 #include "llvm/Transforms/Vectorize/SandboxVectorizer/SeedCollector.h"
@@ -448,13 +449,24 @@ bool BottomUpVec::runOnFunction(Function &F, const Analyses &A) {
 
           assert(SeedSlice.size() >= 2 && "Should have been rejected!");
 
-          // TODO: If vectorization succeeds, run the RegionPassManager on the
-          // resulting region.
-
           // TODO: Refactor to remove the unnecessary copy to SeedSliceVals.
           SmallVector<Value *> SeedSliceVals(SeedSlice.begin(),
                                              SeedSlice.end());
-          Change |= tryVectorize(SeedSliceVals);
+          // Create an empty region. Instructions get added to the region
+          // automatically by the callbacks.
+          auto &Ctx = F.getContext();
+          Region Rgn(Ctx, A.getTTI());
+          // Save the state of the IR before we make any changes. The
+          // transaction gets accepted/reverted by the tr-accept-or-revert pass.
+          Ctx.save();
+          // Try to vectorize starting from the seed slice. The returned value
+          // is true if we found vectorizable code and generated some vector
+          // code for it. It does not mean that the code is profitable.
+          bool VecSuccess = tryVectorize(SeedSliceVals);
+          if (VecSuccess)
+            // WARNING: All passes should return false, except those that
+            // accept/revert the state.
+            Change |= RPM.runOnRegion(Rgn, A);
         }
       }
     }

diff  --git a/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/PassRegistry.def b/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/PassRegistry.def
index 0dc72842f1abe0e..f3aa12729860ff6 100644
--- a/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/PassRegistry.def
+++ b/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/PassRegistry.def
@@ -19,6 +19,8 @@
 
 REGION_PASS("null", ::llvm::sandboxir::NullPass)
 REGION_PASS("print-instruction-count", ::llvm::sandboxir::PrintInstructionCount)
+REGION_PASS("tr-accept", ::llvm::sandboxir::TransactionAlwaysAccept)
+REGION_PASS("tr-accept-or-revert", ::llvm::sandboxir::TransactionAcceptOrRevert)
 
 #undef REGION_PASS
 

diff  --git a/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/TransactionAcceptOrRevert.cpp b/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/TransactionAcceptOrRevert.cpp
new file mode 100644
index 000000000000000..874390ba2daaebf
--- /dev/null
+++ b/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/TransactionAcceptOrRevert.cpp
@@ -0,0 +1,37 @@
+//===- TransactionAcceptOrRevert.cpp - Check cost and accept/revert region ===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Transforms/Vectorize/SandboxVectorizer/Passes/TransactionAcceptOrRevert.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/InstructionCost.h"
+
+namespace llvm {
+
+static cl::opt<int> CostThreshold("sbvec-cost-threshold", cl::init(0),
+                                  cl::Hidden,
+                                  cl::desc("Vectorization cost threshold."));
+
+namespace sandboxir {
+
+bool TransactionAcceptOrRevert::runOnRegion(Region &Rgn, const Analyses &A) {
+  const auto &SB = Rgn.getScoreboard();
+  InstructionCost CostAfterMinusBefore = SB.getAfterCost() - SB.getBeforeCost();
+  // TODO: Print costs / write to remarks.
+  auto &Tracker = Rgn.getContext().getTracker();
+  if (CostAfterMinusBefore < -CostThreshold) {
+    bool HasChanges = !Tracker.empty();
+    Tracker.accept();
+    return HasChanges;
+  }
+  // Revert the IR.
+  Rgn.getContext().getTracker().revert();
+  return false;
+}
+
+} // namespace sandboxir
+} // namespace llvm

diff  --git a/llvm/lib/Transforms/Vectorize/SandboxVectorizer/SandboxVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SandboxVectorizer/SandboxVectorizer.cpp
index 798a0ad915375bc..b233d35212f9471 100644
--- a/llvm/lib/Transforms/Vectorize/SandboxVectorizer/SandboxVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SandboxVectorizer/SandboxVectorizer.cpp
@@ -31,9 +31,10 @@ static cl::opt<std::string> UserDefinedPassPipeline(
 
 SandboxVectorizerPass::SandboxVectorizerPass() : FPM("fpm") {
   if (UserDefinedPassPipeline == DefaultPipelineMagicStr) {
-    // TODO: Add region passes to the default pipeline.
+    // TODO: Add passes to the default pipeline. It currently contains:
+    //       - the bottom-up-vectorizer pass
     FPM.setPassPipeline(
-        "bottom-up-vec<>",
+        "bottom-up-vec<tr-accept-or-revert>",
         sandboxir::SandboxVectorizerPassBuilder::createFunctionPass);
   } else {
     // Create the user-defined pipeline.

diff  --git a/llvm/lib/Transforms/Vectorize/SandboxVectorizer/SandboxVectorizerPassBuilder.cpp b/llvm/lib/Transforms/Vectorize/SandboxVectorizer/SandboxVectorizerPassBuilder.cpp
index 5ecf7b2ed0d258e..0c1ab55e91a5cfc 100644
--- a/llvm/lib/Transforms/Vectorize/SandboxVectorizer/SandboxVectorizerPassBuilder.cpp
+++ b/llvm/lib/Transforms/Vectorize/SandboxVectorizer/SandboxVectorizerPassBuilder.cpp
@@ -4,6 +4,8 @@
 #include "llvm/Transforms/Vectorize/SandboxVectorizer/Passes/NullPass.h"
 #include "llvm/Transforms/Vectorize/SandboxVectorizer/Passes/PrintInstructionCount.h"
 #include "llvm/Transforms/Vectorize/SandboxVectorizer/Passes/RegionsFromMetadata.h"
+#include "llvm/Transforms/Vectorize/SandboxVectorizer/Passes/TransactionAcceptOrRevert.h"
+#include "llvm/Transforms/Vectorize/SandboxVectorizer/Passes/TransactionAlwaysAccept.h"
 
 namespace llvm::sandboxir {
 

diff  --git a/llvm/test/Transforms/SandboxVectorizer/X86/simple_cost_test.ll b/llvm/test/Transforms/SandboxVectorizer/X86/simple_cost_test.ll
new file mode 100644
index 000000000000000..f1df52bd88ad70f
--- /dev/null
+++ b/llvm/test/Transforms/SandboxVectorizer/X86/simple_cost_test.ll
@@ -0,0 +1,91 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt -passes=sandbox-vectorizer -mtriple=x86_64-- -mattr=+sse4.1 %s -S -sbvec-cost-threshold=0 | FileCheck %s --check-prefix=THRESHOLD_0
+; RUN: opt -passes=sandbox-vectorizer -mtriple=x86_64-- -mattr=+sse4.1 %s -S -sbvec-cost-threshold=99 | FileCheck %s --check-prefix=THRESHOLD_99
+
+define void @simple_cost_test(ptr %ptr) {
+; THRESHOLD_0-LABEL: define void @simple_cost_test(
+; THRESHOLD_0-SAME: ptr [[PTR:%.*]]) #[[ATTR0:[0-9]+]] {
+; THRESHOLD_0-NEXT:    [[PTR0:%.*]] = getelementptr double, ptr [[PTR]], i32 0
+; THRESHOLD_0-NEXT:    [[VECL:%.*]] = load <2 x double>, ptr [[PTR0]], align 8, !sandboxvec [[META0:![0-9]+]]
+; THRESHOLD_0-NEXT:    store <2 x double> [[VECL]], ptr [[PTR0]], align 8, !sandboxvec [[META0]]
+; THRESHOLD_0-NEXT:    ret void
+;
+; THRESHOLD_99-LABEL: define void @simple_cost_test(
+; THRESHOLD_99-SAME: ptr [[PTR:%.*]]) #[[ATTR0:[0-9]+]] {
+; THRESHOLD_99-NEXT:    [[PTR0:%.*]] = getelementptr double, ptr [[PTR]], i32 0
+; THRESHOLD_99-NEXT:    [[PTR1:%.*]] = getelementptr double, ptr [[PTR]], i32 1, !sandboxvec [[META0:![0-9]+]]
+; THRESHOLD_99-NEXT:    [[LD0:%.*]] = load double, ptr [[PTR0]], align 8, !sandboxvec [[META0]]
+; THRESHOLD_99-NEXT:    [[LD1:%.*]] = load double, ptr [[PTR1]], align 8, !sandboxvec [[META0]]
+; THRESHOLD_99-NEXT:    store double [[LD0]], ptr [[PTR0]], align 8, !sandboxvec [[META0]]
+; THRESHOLD_99-NEXT:    store double [[LD1]], ptr [[PTR1]], align 8, !sandboxvec [[META0]]
+; THRESHOLD_99-NEXT:    ret void
+;
+  %ptr0 = getelementptr double, ptr %ptr, i32 0
+  %ptr1 = getelementptr double, ptr %ptr, i32 1
+  %ld0 = load double, ptr %ptr0
+  %ld1 = load double, ptr %ptr1
+  store double %ld0, ptr %ptr0
+  store double %ld1, ptr %ptr1
+  ret void
+}
+
+define void @pack_cost_test_(ptr %ptr) {
+; THRESHOLD_0-LABEL: define void @pack_cost_test_(
+; THRESHOLD_0-SAME: ptr [[PTR:%.*]]) #[[ATTR0]] {
+; THRESHOLD_0-NEXT:    [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
+; THRESHOLD_0-NEXT:    [[PTR1:%.*]] = getelementptr float, ptr [[PTR]], i32 1
+; THRESHOLD_0-NEXT:    [[LD0:%.*]] = load float, ptr [[PTR0]], align 4
+; THRESHOLD_0-NEXT:    [[LD1:%.*]] = load float, ptr [[PTR1]], align 4
+; THRESHOLD_0-NEXT:    [[PACK4:%.*]] = insertelement <4 x float> poison, float [[LD0]], i32 0, !sandboxvec [[META1:![0-9]+]]
+; THRESHOLD_0-NEXT:    [[PACK5:%.*]] = insertelement <4 x float> [[PACK4]], float [[LD1]], i32 1, !sandboxvec [[META1]]
+; THRESHOLD_0-NEXT:    [[PACK6:%.*]] = insertelement <4 x float> [[PACK5]], float [[LD0]], i32 2, !sandboxvec [[META1]]
+; THRESHOLD_0-NEXT:    [[PACK7:%.*]] = insertelement <4 x float> [[PACK6]], float [[LD1]], i32 3, !sandboxvec [[META1]]
+; THRESHOLD_0-NEXT:    [[PACK:%.*]] = insertelement <4 x float> poison, float [[LD0]], i32 0, !sandboxvec [[META1]]
+; THRESHOLD_0-NEXT:    [[PACK1:%.*]] = insertelement <4 x float> [[PACK]], float [[LD1]], i32 1, !sandboxvec [[META1]]
+; THRESHOLD_0-NEXT:    [[PACK2:%.*]] = insertelement <4 x float> [[PACK1]], float [[LD0]], i32 2, !sandboxvec [[META1]]
+; THRESHOLD_0-NEXT:    [[PACK3:%.*]] = insertelement <4 x float> [[PACK2]], float [[LD1]], i32 3, !sandboxvec [[META1]]
+; THRESHOLD_0-NEXT:    [[VEC:%.*]] = fmul <4 x float> [[PACK3]], [[PACK7]], !sandboxvec [[META1]]
+; THRESHOLD_0-NEXT:    store <4 x float> [[VEC]], ptr [[PTR0]], align 4, !sandboxvec [[META1]]
+; THRESHOLD_0-NEXT:    ret void
+;
+; THRESHOLD_99-LABEL: define void @pack_cost_test_(
+; THRESHOLD_99-SAME: ptr [[PTR:%.*]]) #[[ATTR0]] {
+; THRESHOLD_99-NEXT:    [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
+; THRESHOLD_99-NEXT:    [[PTR1:%.*]] = getelementptr float, ptr [[PTR]], i32 1
+; THRESHOLD_99-NEXT:    [[PTR2:%.*]] = getelementptr float, ptr [[PTR]], i32 2, !sandboxvec [[META1:![0-9]+]]
+; THRESHOLD_99-NEXT:    [[PTR3:%.*]] = getelementptr float, ptr [[PTR]], i32 3, !sandboxvec [[META1]]
+; THRESHOLD_99-NEXT:    [[LD0:%.*]] = load float, ptr [[PTR0]], align 4
+; THRESHOLD_99-NEXT:    [[LD1:%.*]] = load float, ptr [[PTR1]], align 4
+; THRESHOLD_99-NEXT:    [[MUL0:%.*]] = fmul float [[LD0]], [[LD0]], !sandboxvec [[META1]]
+; THRESHOLD_99-NEXT:    [[MUL1:%.*]] = fmul float [[LD1]], [[LD1]], !sandboxvec [[META1]]
+; THRESHOLD_99-NEXT:    [[MUL2:%.*]] = fmul float [[LD0]], [[LD0]], !sandboxvec [[META1]]
+; THRESHOLD_99-NEXT:    [[MUL3:%.*]] = fmul float [[LD1]], [[LD1]], !sandboxvec [[META1]]
+; THRESHOLD_99-NEXT:    store float [[MUL0]], ptr [[PTR0]], align 4, !sandboxvec [[META1]]
+; THRESHOLD_99-NEXT:    store float [[MUL1]], ptr [[PTR1]], align 4, !sandboxvec [[META1]]
+; THRESHOLD_99-NEXT:    store float [[MUL2]], ptr [[PTR2]], align 4, !sandboxvec [[META1]]
+; THRESHOLD_99-NEXT:    store float [[MUL3]], ptr [[PTR3]], align 4, !sandboxvec [[META1]]
+; THRESHOLD_99-NEXT:    ret void
+;
+  %ptr0 = getelementptr float, ptr %ptr, i32 0
+  %ptr1 = getelementptr float, ptr %ptr, i32 1
+  %ptr2 = getelementptr float, ptr %ptr, i32 2
+  %ptr3 = getelementptr float, ptr %ptr, i32 3
+  %ld0 = load float, ptr %ptr0
+  %ld1 = load float, ptr %ptr1
+  %mul0 = fmul float %ld0, %ld0
+  %mul1 = fmul float %ld1, %ld1
+  %mul2 = fmul float %ld0, %ld0
+  %mul3 = fmul float %ld1, %ld1
+  store float %mul0, ptr %ptr0
+  store float %mul1, ptr %ptr1
+  store float %mul2, ptr %ptr2
+  store float %mul3, ptr %ptr3
+  ret void
+}
+;.
+; THRESHOLD_0: [[META0]] = distinct !{!"sandboxregion"}
+; THRESHOLD_0: [[META1]] = distinct !{!"sandboxregion"}
+;.
+; THRESHOLD_99: [[META0]] = distinct !{!"sandboxregion"}
+; THRESHOLD_99: [[META1]] = distinct !{!"sandboxregion"}
+;.

diff  --git a/llvm/test/Transforms/SandboxVectorizer/bottomup_basic.ll b/llvm/test/Transforms/SandboxVectorizer/bottomup_basic.ll
index ee5a3a514b3c58e..ee8592c04b62c0a 100644
--- a/llvm/test/Transforms/SandboxVectorizer/bottomup_basic.ll
+++ b/llvm/test/Transforms/SandboxVectorizer/bottomup_basic.ll
@@ -1,5 +1,5 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
-; RUN: opt -passes=sandbox-vectorizer -sbvec-vec-reg-bits=1024 -sbvec-allow-non-pow2 -sbvec-passes="bottom-up-vec<>" %s -S | FileCheck %s
+; RUN: opt -passes=sandbox-vectorizer -sbvec-vec-reg-bits=1024 -sbvec-allow-non-pow2 -sbvec-passes="bottom-up-vec<tr-accept>" %s -S | FileCheck %s
 
 define void @store_load(ptr %ptr) {
 ; CHECK-LABEL: define void @store_load(

diff  --git a/llvm/test/Transforms/SandboxVectorizer/bottomup_seed_slice.ll b/llvm/test/Transforms/SandboxVectorizer/bottomup_seed_slice.ll
index 8459c3addaa83f1..202b5a6fbd6c968 100644
--- a/llvm/test/Transforms/SandboxVectorizer/bottomup_seed_slice.ll
+++ b/llvm/test/Transforms/SandboxVectorizer/bottomup_seed_slice.ll
@@ -1,5 +1,5 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
-; RUN: opt -passes=sandbox-vectorizer -sbvec-vec-reg-bits=1024 -sbvec-allow-non-pow2 -sbvec-passes="bottom-up-vec<>" %s -S | FileCheck %s
+; RUN: opt -passes=sandbox-vectorizer -sbvec-vec-reg-bits=1024 -sbvec-allow-non-pow2 -sbvec-passes="bottom-up-vec<tr-accept>" %s -S | FileCheck %s
 
 
 declare void @foo()

diff  --git a/llvm/test/Transforms/SandboxVectorizer/bottomup_seed_slice_pow2.ll b/llvm/test/Transforms/SandboxVectorizer/bottomup_seed_slice_pow2.ll
index e186d5fa86e4a7f..f1c6e3297d79c7f 100644
--- a/llvm/test/Transforms/SandboxVectorizer/bottomup_seed_slice_pow2.ll
+++ b/llvm/test/Transforms/SandboxVectorizer/bottomup_seed_slice_pow2.ll
@@ -1,6 +1,6 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
-; RUN: opt -passes=sandbox-vectorizer -sbvec-vec-reg-bits=1024 -sbvec-allow-non-pow2=false -sbvec-passes="bottom-up-vec<>" %s -S | FileCheck %s --check-prefix=POW2
-; RUN: opt -passes=sandbox-vectorizer -sbvec-vec-reg-bits=1024 -sbvec-allow-non-pow2=true -sbvec-passes="bottom-up-vec<>" %s -S | FileCheck %s --check-prefix=NON-POW2
+; RUN: opt -passes=sandbox-vectorizer -sbvec-vec-reg-bits=1024 -sbvec-allow-non-pow2=false -sbvec-passes="bottom-up-vec<tr-accept>" %s -S | FileCheck %s --check-prefix=POW2
+; RUN: opt -passes=sandbox-vectorizer -sbvec-vec-reg-bits=1024 -sbvec-allow-non-pow2=true -sbvec-passes="bottom-up-vec<tr-accept>" %s -S | FileCheck %s --check-prefix=NON-POW2
 
 define void @pow2(ptr %ptr, float %val) {
 ; POW2-LABEL: define void @pow2(

diff  --git a/llvm/test/Transforms/SandboxVectorizer/cross_bbs.ll b/llvm/test/Transforms/SandboxVectorizer/cross_bbs.ll
index 6ec31060d7e0fe7..ff1604173c31754 100644
--- a/llvm/test/Transforms/SandboxVectorizer/cross_bbs.ll
+++ b/llvm/test/Transforms/SandboxVectorizer/cross_bbs.ll
@@ -1,5 +1,5 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
-; RUN: opt -passes=sandbox-vectorizer -sbvec-vec-reg-bits=1024 -sbvec-allow-non-pow2 -sbvec-passes="bottom-up-vec<>" %s -S | FileCheck %s
+; RUN: opt -passes=sandbox-vectorizer -sbvec-vec-reg-bits=1024 -sbvec-allow-non-pow2 -sbvec-passes="bottom-up-vec<tr-accept>" %s -S | FileCheck %s
 
 define void @cross_bbs(ptr %ptr) {
 ; CHECK-LABEL: define void @cross_bbs(

diff  --git a/llvm/test/Transforms/SandboxVectorizer/default_pass_pipeline.ll b/llvm/test/Transforms/SandboxVectorizer/default_pass_pipeline.ll
index 1d7be43336c8795..10de4338caf2325 100644
--- a/llvm/test/Transforms/SandboxVectorizer/default_pass_pipeline.ll
+++ b/llvm/test/Transforms/SandboxVectorizer/default_pass_pipeline.ll
@@ -4,8 +4,10 @@
 
 ; This checks the default pass pipeline for the sandbox vectorizer.
 define void @pipeline() {
+; CHECK: fpm
 ; CHECK: bottom-up-vec
 ; CHECK: rpm
+; CHECK: tr-accept-or-revert
 ; CHECK-EMPTY:
   ret void
 }

diff  --git a/llvm/test/Transforms/SandboxVectorizer/pack.ll b/llvm/test/Transforms/SandboxVectorizer/pack.ll
index ec6e61a90c0fb3f..da41036e3a58b76 100644
--- a/llvm/test/Transforms/SandboxVectorizer/pack.ll
+++ b/llvm/test/Transforms/SandboxVectorizer/pack.ll
@@ -1,5 +1,5 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
-; RUN: opt -passes=sandbox-vectorizer -sbvec-vec-reg-bits=1024 -sbvec-allow-non-pow2 -sbvec-passes="bottom-up-vec<>" %s -S | FileCheck %s
+; RUN: opt -passes=sandbox-vectorizer -sbvec-vec-reg-bits=1024 -sbvec-allow-non-pow2 -sbvec-passes="bottom-up-vec<tr-accept>" %s -S | FileCheck %s
 
 define void @pack_constants(ptr %ptr) {
 ; CHECK-LABEL: define void @pack_constants(

diff  --git a/llvm/test/Transforms/SandboxVectorizer/repeated_instrs.ll b/llvm/test/Transforms/SandboxVectorizer/repeated_instrs.ll
index 6026e92ef9a8248..25d9d79154d356d 100644
--- a/llvm/test/Transforms/SandboxVectorizer/repeated_instrs.ll
+++ b/llvm/test/Transforms/SandboxVectorizer/repeated_instrs.ll
@@ -1,5 +1,5 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
-; RUN: opt -passes=sandbox-vectorizer -sbvec-vec-reg-bits=1024 -sbvec-allow-non-pow2 -sbvec-passes="bottom-up-vec<>" %s -S | FileCheck %s
+; RUN: opt -passes=sandbox-vectorizer -sbvec-vec-reg-bits=1024 -sbvec-allow-non-pow2 -sbvec-passes="bottom-up-vec<tr-accept>" %s -S | FileCheck %s
 
 define i32 @repeated_splat(ptr %ptr, i32 %v) #0 {
 ; CHECK-LABEL: define i32 @repeated_splat(

diff  --git a/llvm/test/Transforms/SandboxVectorizer/scheduler.ll b/llvm/test/Transforms/SandboxVectorizer/scheduler.ll
index 847c978aa4912a2..92a78a979192b58 100644
--- a/llvm/test/Transforms/SandboxVectorizer/scheduler.ll
+++ b/llvm/test/Transforms/SandboxVectorizer/scheduler.ll
@@ -1,5 +1,5 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
-; RUN: opt -passes=sandbox-vectorizer -sbvec-vec-reg-bits=1024 -sbvec-allow-non-pow2 -sbvec-passes="bottom-up-vec<>" %s -S | FileCheck %s
+; RUN: opt -passes=sandbox-vectorizer -sbvec-vec-reg-bits=1024 -sbvec-allow-non-pow2 -sbvec-passes="bottom-up-vec<tr-accept>" %s -S | FileCheck %s
 
 ; This used to crash because the newly added pack   instructions would not update
 ; the DAG and scheduler, leading to def-after-use.

diff  --git a/llvm/test/Transforms/SandboxVectorizer/special_opcodes.ll b/llvm/test/Transforms/SandboxVectorizer/special_opcodes.ll
index fe3a2067d481d16..e8fe8b4fa88e3b7 100644
--- a/llvm/test/Transforms/SandboxVectorizer/special_opcodes.ll
+++ b/llvm/test/Transforms/SandboxVectorizer/special_opcodes.ll
@@ -1,5 +1,5 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
-; RUN: opt -passes=sandbox-vectorizer -sbvec-vec-reg-bits=1024 -sbvec-allow-non-pow2 -sbvec-passes="bottom-up-vec<>" %s -S | FileCheck %s
+; RUN: opt -passes=sandbox-vectorizer -sbvec-vec-reg-bits=1024 -sbvec-allow-non-pow2 -sbvec-passes="bottom-up-vec<tr-accept>" %s -S | FileCheck %s
 
 ; This file includes tests for opcodes that need special checks.
 

diff  --git a/llvm/unittests/SandboxIR/TrackerTest.cpp b/llvm/unittests/SandboxIR/TrackerTest.cpp
index 4eedab124bfa047..9c18247b6b96d0e 100644
--- a/llvm/unittests/SandboxIR/TrackerTest.cpp
+++ b/llvm/unittests/SandboxIR/TrackerTest.cpp
@@ -52,6 +52,9 @@ define void @foo(ptr %ptr) {
   auto *F = Ctx.createFunction(&LLVMF);
   auto *BB = &*F->begin();
   auto &Tracker = Ctx.getTracker();
+  // Check empty().
+  EXPECT_TRUE(Ctx.getTracker().empty());
+
   Tracker.save();
   auto It = BB->begin();
   auto *Gep0 = &*It++;
@@ -65,6 +68,9 @@ define void @foo(ptr %ptr) {
   EXPECT_EQ(St->getOperand(1), Gep1);
   EXPECT_EQ(Ld->getOperand(0), Gep1);
 
+  // Check empty().
+  EXPECT_FALSE(Ctx.getTracker().empty());
+
   Ctx.getTracker().revert();
   EXPECT_NE(St->getOperand(0), Ld);
   EXPECT_EQ(St->getOperand(1), Gep0);


        


More information about the llvm-commits mailing list