Skip to content

[SandboxVec][BottomUpVec] Add -sbvec-stop-at flag for debugging #129097

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 27, 2025

Conversation

vporpo
Copy link
Contributor

@vporpo vporpo commented Feb 27, 2025

When debugging miscompiles we need a way to force-stop the vectorizer early. This helps figure out which invocation is generating incorrect code.

@llvmbot
Copy link
Member

llvmbot commented Feb 27, 2025

@llvm/pr-subscribers-vectorizers

@llvm/pr-subscribers-llvm-transforms

Author: vporpo (vporpo)

Changes

When debugging miscompiles we need a way to force-stop the vectorizer early. This helps figure out which invocation is generating incorrect code.


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

3 Files Affected:

  • (modified) llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/BottomUpVec.h (+3)
  • (modified) llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/BottomUpVec.cpp (+10)
  • (added) llvm/test/Transforms/SandboxVectorizer/stop_at.ll (+61)
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<Instruction *> DeadInstrCandidates;
   /// Maps scalars to vectors.
   std::unique_ptr<InstrMaps> 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<bool>
                           "emit new instructions (*very* expensive)."));
 #endif // NDEBUG
 
+static constexpr const unsigned long StopAtDisabled =
+    std::numeric_limits<unsigned long>::max();
+static cl::opt<unsigned long>
+    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<Value *, 4> getOperand(ArrayRef<Value *> Bndl,
@@ -456,6 +463,9 @@ Value *BottomUpVec::emitVectors() {
 
 bool BottomUpVec::tryVectorize(ArrayRef<Value *> 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..cf276a6e39e37
--- /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="bottom-up-vec<>" --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="bottom-up-vec<>" --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="bottom-up-vec<>" --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
+}

When debugging miscompiles we need a way to force-stop the vectorizer early.
This helps figure out which invocation is generating incorrect code.
@vporpo vporpo merged commit adf0abf into llvm:main Feb 27, 2025
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants