[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).
This commit is contained in:
@@ -440,8 +440,9 @@ public:
|
||||
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 @@ public:
|
||||
|
||||
~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) {
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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() {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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.
|
||||
|
||||
@@ -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 {
|
||||
|
||||
|
||||
@@ -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"}
|
||||
;.
|
||||
@@ -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(
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user