From 198c8849f0c18d00d6f81e55d569db3627fcef99 Mon Sep 17 00:00:00 2001 From: Vasileios Porpodas Date: Tue, 11 Feb 2025 09:20:30 -0800 Subject: [PATCH] [SandboxVec][BottomUpVec] Add -sbvec-stop-at flag for debugging When debugging miscompiles we need a way to force-stop the vectorizer early. This helps figure out which invocation is generating incorrect code. --- .../SandboxVectorizer/Passes/BottomUpVec.h | 3 + .../SandboxVectorizer/Passes/BottomUpVec.cpp | 10 +++ .../Transforms/SandboxVectorizer/stop_at.ll | 61 +++++++++++++++++++ 3 files changed, 74 insertions(+) create mode 100644 llvm/test/Transforms/SandboxVectorizer/stop_at.ll diff --git a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/BottomUpVec.h b/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/BottomUpVec.h index b28e9948d6f55..2359d54213ef6 100644 --- a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/BottomUpVec.h +++ b/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/BottomUpVec.h @@ -39,6 +39,9 @@ class BottomUpVec final : public RegionPass { DenseSet DeadInstrCandidates; /// Maps scalars to vectors. std::unique_ptr IMaps; + /// Counter used for force-stopping the vectorizer after this many + /// invocations. Used for debugging miscompiles. + unsigned long BottomUpInvocationCnt = 0; /// Creates and returns a vector instruction that replaces the instructions in /// \p Bndl. \p Operands are the already vectorized operands. diff --git a/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/BottomUpVec.cpp b/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/BottomUpVec.cpp index 14438181f2602..16eff012c187a 100644 --- a/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/BottomUpVec.cpp +++ b/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/BottomUpVec.cpp @@ -25,6 +25,13 @@ static cl::opt "emit new instructions (*very* expensive).")); #endif // NDEBUG +static constexpr const unsigned long StopAtDisabled = + std::numeric_limits::max(); +static cl::opt + StopAt("sbvec-stop-at", cl::init(StopAtDisabled), cl::Hidden, + cl::desc("Vectorize if the invocation count is < than this. 0 " + "disables vectorization.")); + namespace sandboxir { static SmallVector getOperand(ArrayRef Bndl, @@ -456,6 +463,9 @@ Value *BottomUpVec::emitVectors() { bool BottomUpVec::tryVectorize(ArrayRef Bndl) { Change = false; + if (LLVM_UNLIKELY(BottomUpInvocationCnt++ >= StopAt && + StopAt != StopAtDisabled)) + return false; DeadInstrCandidates.clear(); Legality->clear(); Actions.clear(); diff --git a/llvm/test/Transforms/SandboxVectorizer/stop_at.ll b/llvm/test/Transforms/SandboxVectorizer/stop_at.ll new file mode 100644 index 0000000000000..f37b9f1fd7587 --- /dev/null +++ b/llvm/test/Transforms/SandboxVectorizer/stop_at.ll @@ -0,0 +1,61 @@ +; 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="seed-collection" --sbvec-stop-at=0 %s -S | FileCheck %s --check-prefix=STOPAT0 +; RUN: opt -passes=sandbox-vectorizer -sbvec-vec-reg-bits=1024 -sbvec-allow-non-pow2 -sbvec-passes="seed-collection" --sbvec-stop-at=1 %s -S | FileCheck %s --check-prefix=STOPAT1 +; RUN: opt -passes=sandbox-vectorizer -sbvec-vec-reg-bits=1024 -sbvec-allow-non-pow2 -sbvec-passes="seed-collection" --sbvec-stop-at=2 %s -S | FileCheck %s --check-prefix=STOPAT2 + +define void @widen(ptr %ptrA, ptr %ptrB) { +; STOPAT0-LABEL: define void @widen( +; STOPAT0-SAME: ptr [[PTRA:%.*]], ptr [[PTRB:%.*]]) { +; STOPAT0-NEXT: [[PTRA0:%.*]] = getelementptr float, ptr [[PTRA]], i32 0 +; STOPAT0-NEXT: [[PTRA1:%.*]] = getelementptr float, ptr [[PTRA]], i32 1 +; STOPAT0-NEXT: [[LDA0:%.*]] = load float, ptr [[PTRA0]], align 4 +; STOPAT0-NEXT: [[LDA1:%.*]] = load float, ptr [[PTRA1]], align 4 +; STOPAT0-NEXT: store float [[LDA0]], ptr [[PTRA0]], align 4 +; STOPAT0-NEXT: store float [[LDA1]], ptr [[PTRA1]], align 4 +; STOPAT0-NEXT: [[PTRB0:%.*]] = getelementptr float, ptr [[PTRB]], i32 0 +; STOPAT0-NEXT: [[PTRB1:%.*]] = getelementptr float, ptr [[PTRB]], i32 1 +; STOPAT0-NEXT: [[LDB0:%.*]] = load float, ptr [[PTRB0]], align 4 +; STOPAT0-NEXT: [[LDB1:%.*]] = load float, ptr [[PTRB1]], align 4 +; STOPAT0-NEXT: store float [[LDB0]], ptr [[PTRB0]], align 4 +; STOPAT0-NEXT: store float [[LDB1]], ptr [[PTRB1]], align 4 +; STOPAT0-NEXT: ret void +; +; STOPAT1-LABEL: define void @widen( +; STOPAT1-SAME: ptr [[PTRA:%.*]], ptr [[PTRB:%.*]]) { +; STOPAT1-NEXT: [[PTRA0:%.*]] = getelementptr float, ptr [[PTRA]], i32 0 +; STOPAT1-NEXT: [[VECL:%.*]] = load <2 x float>, ptr [[PTRA0]], align 4 +; STOPAT1-NEXT: store <2 x float> [[VECL]], ptr [[PTRA0]], align 4 +; STOPAT1-NEXT: [[PTRB0:%.*]] = getelementptr float, ptr [[PTRB]], i32 0 +; STOPAT1-NEXT: [[PTRB1:%.*]] = getelementptr float, ptr [[PTRB]], i32 1 +; STOPAT1-NEXT: [[LDB0:%.*]] = load float, ptr [[PTRB0]], align 4 +; STOPAT1-NEXT: [[LDB1:%.*]] = load float, ptr [[PTRB1]], align 4 +; STOPAT1-NEXT: store float [[LDB0]], ptr [[PTRB0]], align 4 +; STOPAT1-NEXT: store float [[LDB1]], ptr [[PTRB1]], align 4 +; STOPAT1-NEXT: ret void +; +; STOPAT2-LABEL: define void @widen( +; STOPAT2-SAME: ptr [[PTRA:%.*]], ptr [[PTRB:%.*]]) { +; STOPAT2-NEXT: [[PTRA0:%.*]] = getelementptr float, ptr [[PTRA]], i32 0 +; STOPAT2-NEXT: [[VECL:%.*]] = load <2 x float>, ptr [[PTRA0]], align 4 +; STOPAT2-NEXT: store <2 x float> [[VECL]], ptr [[PTRA0]], align 4 +; STOPAT2-NEXT: [[PTRB0:%.*]] = getelementptr float, ptr [[PTRB]], i32 0 +; STOPAT2-NEXT: [[VECL1:%.*]] = load <2 x float>, ptr [[PTRB0]], align 4 +; STOPAT2-NEXT: store <2 x float> [[VECL1]], ptr [[PTRB0]], align 4 +; STOPAT2-NEXT: ret void +; + %ptrA0 = getelementptr float, ptr %ptrA, i32 0 + %ptrA1 = getelementptr float, ptr %ptrA, i32 1 + %ldA0 = load float, ptr %ptrA0 + %ldA1 = load float, ptr %ptrA1 + store float %ldA0, ptr %ptrA0 + store float %ldA1, ptr %ptrA1 + + %ptrB0 = getelementptr float, ptr %ptrB, i32 0 + %ptrB1 = getelementptr float, ptr %ptrB, i32 1 + %ldB0 = load float, ptr %ptrB0 + %ldB1 = load float, ptr %ptrB1 + store float %ldB0, ptr %ptrB0 + store float %ldB1, ptr %ptrB1 + + ret void +}