[llvm] UTC: support debug output from LDist (PR #93208)
Ramkumar Ramachandra via llvm-commits
llvm-commits at lists.llvm.org
Tue Jun 25 14:15:07 PDT 2024
https://github.com/artagnon updated https://github.com/llvm/llvm-project/pull/93208
>From 7fa14d469a3d4847a10890d988a7dda94ed5fa0e Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <r at artagnon.com>
Date: Thu, 23 May 2024 16:33:20 +0100
Subject: [PATCH] [UTC] support debug output from LDist
Tweak the LoopDistribute debug output to be stable, and extend
update_analyze_test_checks.py trivially to support this output.
---
llvm/lib/Transforms/Scalar/LoopDistribute.cpp | 58 ++++-----
.../Transforms/LoopDistribute/debug-print.ll | 94 ++++++++++++--
.../Inputs/loop-distribute.ll | 27 ++++
.../Inputs/loop-distribute.ll.expected | 118 ++++++++++++++++++
.../loop-distribute.test | 6 +
llvm/utils/UpdateTestChecks/common.py | 6 +-
llvm/utils/update_analyze_test_checks.py | 10 +-
7 files changed, 273 insertions(+), 46 deletions(-)
create mode 100644 llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/loop-distribute.ll
create mode 100644 llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/loop-distribute.ll.expected
create mode 100644 llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/loop-distribute.test
diff --git a/llvm/lib/Transforms/Scalar/LoopDistribute.cpp b/llvm/lib/Transforms/Scalar/LoopDistribute.cpp
index 7a34ec2c008ccc..d2fed11fe509f8 100644
--- a/llvm/lib/Transforms/Scalar/LoopDistribute.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopDistribute.cpp
@@ -26,7 +26,7 @@
#include "llvm/ADT/DepthFirstIterator.h"
#include "llvm/ADT/EquivalenceClasses.h"
#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringRef.h"
@@ -120,7 +120,7 @@ namespace {
/// Maintains the set of instructions of the loop for a partition before
/// cloning. After cloning, it hosts the new loop.
class InstPartition {
- using InstructionSet = SmallPtrSet<Instruction *, 8>;
+ using InstructionSet = SetVector<Instruction *>;
public:
InstPartition(Instruction *I, Loop *L, bool DepCycle = false)
@@ -166,7 +166,7 @@ class InstPartition {
// Insert instructions from the loop that we depend on.
for (Value *V : I->operand_values()) {
auto *I = dyn_cast<Instruction>(V);
- if (I && OrigLoop->contains(I->getParent()) && Set.insert(I).second)
+ if (I && OrigLoop->contains(I->getParent()) && Set.insert(I))
Worklist.push_back(I);
}
}
@@ -231,17 +231,16 @@ class InstPartition {
}
}
- void print() const {
- if (DepCycle)
- dbgs() << " (cycle)\n";
+ void print(raw_ostream &OS) const {
+ OS << (DepCycle ? " (cycle)\n" : "\n");
for (auto *I : Set)
// Prefix with the block name.
- dbgs() << " " << I->getParent()->getName() << ":" << *I << "\n";
+ OS << " " << I->getParent()->getName() << ":" << *I << "\n";
}
- void printBlocks() const {
+ void printBlocks(raw_ostream &OS) const {
for (auto *BB : getDistributedLoop()->getBlocks())
- dbgs() << *BB;
+ OS << *BB;
}
private:
@@ -368,11 +367,11 @@ class InstPartitionContainer {
std::tie(LoadToPart, NewElt) =
LoadToPartition.insert(std::make_pair(Inst, PartI));
if (!NewElt) {
- LLVM_DEBUG(dbgs()
- << "Merging partitions due to this load in multiple "
- << "partitions: " << PartI << ", " << LoadToPart->second
- << "\n"
- << *Inst << "\n");
+ LLVM_DEBUG(
+ dbgs()
+ << "LDist: Merging partitions due to this load in multiple "
+ << "partitions: " << PartI << ", " << LoadToPart->second << "\n"
+ << *Inst << "\n");
auto PartJ = I;
do {
@@ -530,8 +529,8 @@ class InstPartitionContainer {
void print(raw_ostream &OS) const {
unsigned Index = 0;
for (const auto &P : PartitionContainer) {
- OS << "Partition " << Index++ << " (" << &P << "):\n";
- P.print();
+ OS << "LDist: Partition " << Index++ << ":";
+ P.print(OS);
}
}
@@ -545,11 +544,11 @@ class InstPartitionContainer {
}
#endif
- void printBlocks() const {
+ void printBlocks(raw_ostream &OS) const {
unsigned Index = 0;
for (const auto &P : PartitionContainer) {
- dbgs() << "\nPartition " << Index++ << " (" << &P << "):\n";
- P.printBlocks();
+ OS << "LDist: Partition " << Index++ << ":";
+ P.printBlocks(OS);
}
}
@@ -628,7 +627,7 @@ class MemoryInstructionDependences {
const SmallVectorImpl<Dependence> &Dependences) {
Accesses.append(Instructions.begin(), Instructions.end());
- LLVM_DEBUG(dbgs() << "Backward dependences:\n");
+ LLVM_DEBUG(dbgs() << "LDist: Backward dependences:\n");
for (const auto &Dep : Dependences)
if (Dep.isPossiblyBackward()) {
// Note that the designations source and destination follow the program
@@ -738,7 +737,7 @@ class LoopDistributeForLoop {
for (auto *Inst : DefsUsedOutside)
Partitions.addToNewNonCyclicPartition(Inst);
- LLVM_DEBUG(dbgs() << "Seeded partitions:\n" << Partitions);
+ LLVM_DEBUG(dbgs() << "LDist: Seeded partitions:\n" << Partitions);
if (Partitions.getSize() < 2)
return fail("CantIsolateUnsafeDeps",
"cannot isolate unsafe dependencies");
@@ -746,19 +745,19 @@ class LoopDistributeForLoop {
// Run the merge heuristics: Merge non-cyclic adjacent partitions since we
// should be able to vectorize these together.
Partitions.mergeBeforePopulating();
- LLVM_DEBUG(dbgs() << "\nMerged partitions:\n" << Partitions);
+ LLVM_DEBUG(dbgs() << "LDist: Merged partitions:\n" << Partitions);
if (Partitions.getSize() < 2)
return fail("CantIsolateUnsafeDeps",
"cannot isolate unsafe dependencies");
// Now, populate the partitions with non-memory operations.
Partitions.populateUsedSet();
- LLVM_DEBUG(dbgs() << "\nPopulated partitions:\n" << Partitions);
+ LLVM_DEBUG(dbgs() << "LDist: Populated partitions:\n" << Partitions);
// In order to preserve original lexical order for loads, keep them in the
// partition that we set up in the MemoryInstructionDependences loop.
if (Partitions.mergeToAvoidDuplicatedLoads()) {
- LLVM_DEBUG(dbgs() << "\nPartitions merged to ensure unique loads:\n"
+ LLVM_DEBUG(dbgs() << "LDist: Partitions merged to ensure unique loads:\n"
<< Partitions);
if (Partitions.getSize() < 2)
return fail("CantIsolateUnsafeDeps",
@@ -782,7 +781,8 @@ class LoopDistributeForLoop {
if (!IsForced.value_or(false) && hasDisableAllTransformsHint(L))
return fail("HeuristicDisabled", "distribution heuristic disabled");
- LLVM_DEBUG(dbgs() << "\nDistributing loop: " << *L << "\n");
+ LLVM_DEBUG(dbgs() << "LDist: Distributing loop: "
+ << L->getHeader()->getName() << "\n");
// We're done forming the partitions set up the reverse mapping from
// instructions to partitions.
Partitions.setupPartitionIdOnInstructions();
@@ -810,7 +810,7 @@ class LoopDistributeForLoop {
MDNode *OrigLoopID = L->getLoopID();
- LLVM_DEBUG(dbgs() << "\nPointers:\n");
+ LLVM_DEBUG(dbgs() << "LDist: Pointers:\n");
LLVM_DEBUG(LAI->getRuntimePointerChecking()->printChecks(dbgs(), Checks));
LoopVersioning LVer(*LAI, Checks, L, LI, DT, SE);
LVer.versionLoop(DefsUsedOutside);
@@ -833,8 +833,8 @@ class LoopDistributeForLoop {
// Now, we remove the instruction from each loop that don't belong to that
// partition.
Partitions.removeUnusedInsts();
- LLVM_DEBUG(dbgs() << "\nAfter removing unused Instrs:\n");
- LLVM_DEBUG(Partitions.printBlocks());
+ LLVM_DEBUG(dbgs() << "LDist: After removing unused Instrs:\n");
+ LLVM_DEBUG(Partitions.printBlocks(dbgs()));
if (LDistVerify) {
LI->verify(*DT);
@@ -856,7 +856,7 @@ class LoopDistributeForLoop {
LLVMContext &Ctx = F->getContext();
bool Forced = isForced().value_or(false);
- LLVM_DEBUG(dbgs() << "Skipping; " << Message << "\n");
+ LLVM_DEBUG(dbgs() << "LDist: Skipping; " << Message << "\n");
// With Rpass-missed report that distribution failed.
ORE->emit([&]() {
diff --git a/llvm/test/Transforms/LoopDistribute/debug-print.ll b/llvm/test/Transforms/LoopDistribute/debug-print.ll
index 733c33483ecc40..2c3a0116fe1315 100644
--- a/llvm/test/Transforms/LoopDistribute/debug-print.ll
+++ b/llvm/test/Transforms/LoopDistribute/debug-print.ll
@@ -1,20 +1,92 @@
+; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 5
; REQUIRES: asserts
; RUN: opt -passes=loop-distribute -enable-loop-distribute \
; RUN: -debug-only=loop-distribute -disable-output 2>&1 %s | FileCheck %s
define void @f(ptr noalias %a, ptr noalias %b, ptr noalias %c, ptr noalias %d, i64 %stride) {
; CHECK-LABEL: 'f'
-; CHECK: LDist: Found a candidate loop: for.body
-; CHECK: Backward dependences:
-; CHECK-NEXT: Backward:
-; CHECK-NEXT: %load.a = load i32, ptr %gep.a, align 4 ->
-; CHECK-NEXT: store i32 %mul.a, ptr %gep.a.plus4, align 4
-; CHECK: Seeded partitions:
-; CHECK: Partition 0
-; CHECK: Partition 1
-; CHECK: Partition 2
-; CHECK: Partition 3
-; CHECK: Distributing loop
+; CHECK-NEXT: LDist: Found a candidate loop: for.body
+; CHECK-NEXT: LDist: Backward dependences:
+; CHECK-NEXT: Backward:
+; CHECK-NEXT: %load.a = load i32, ptr %gep.a, align 4 ->
+; CHECK-NEXT: store i32 %mul.a, ptr %gep.a.plus4, align 4
+; CHECK-NEXT: LDist: Seeded partitions:
+; CHECK-NEXT: LDist: Partition 0: (cycle)
+; CHECK-NEXT: for.body: %load.a = load i32, ptr %gep.a, align 4
+; CHECK-NEXT: for.body: %load.b = load i32, ptr %gep.b, align 4
+; CHECK-NEXT: for.body: store i32 %mul.a, ptr %gep.a.plus4, align 4
+; CHECK-NEXT: LDist: Partition 1:
+; CHECK-NEXT: for.body: %loadD = load i32, ptr %gep.d, align 4
+; CHECK-NEXT: LDist: Partition 2:
+; CHECK-NEXT: for.body: %load.strided.a = load i32, ptr %gep.strided.a, align 4
+; CHECK-NEXT: LDist: Partition 3:
+; CHECK-NEXT: for.body: store i32 %mul.c, ptr %gep.c, align 4
+; CHECK-NEXT: LDist: Merged partitions:
+; CHECK-NEXT: LDist: Partition 0: (cycle)
+; CHECK-NEXT: for.body: %load.a = load i32, ptr %gep.a, align 4
+; CHECK-NEXT: for.body: %load.b = load i32, ptr %gep.b, align 4
+; CHECK-NEXT: for.body: store i32 %mul.a, ptr %gep.a.plus4, align 4
+; CHECK-NEXT: LDist: Partition 1:
+; CHECK-NEXT: for.body: %loadD = load i32, ptr %gep.d, align 4
+; CHECK-NEXT: for.body: %load.strided.a = load i32, ptr %gep.strided.a, align 4
+; CHECK-NEXT: for.body: store i32 %mul.c, ptr %gep.c, align 4
+; CHECK-NEXT: LDist: Populated partitions:
+; CHECK-NEXT: LDist: Partition 0: (cycle)
+; CHECK-NEXT: for.body: %load.a = load i32, ptr %gep.a, align 4
+; CHECK-NEXT: for.body: %load.b = load i32, ptr %gep.b, align 4
+; CHECK-NEXT: for.body: store i32 %mul.a, ptr %gep.a.plus4, align 4
+; CHECK-NEXT: for.body: br i1 %exitcond, label %exit, label %for.body
+; CHECK-NEXT: for.body: %exitcond = icmp eq i64 %add, 20
+; CHECK-NEXT: for.body: %add = add nuw nsw i64 %ind, 1
+; CHECK-NEXT: for.body: %ind = phi i64 [ 0, %entry ], [ %add, %for.body ]
+; CHECK-NEXT: for.body: %mul.a = mul i32 %load.b, %load.a
+; CHECK-NEXT: for.body: %gep.a.plus4 = getelementptr inbounds i32, ptr %a, i64 %add
+; CHECK-NEXT: for.body: %gep.b = getelementptr inbounds i32, ptr %b, i64 %ind
+; CHECK-NEXT: for.body: %gep.a = getelementptr inbounds i32, ptr %a, i64 %ind
+; CHECK-NEXT: LDist: Partition 1:
+; CHECK-NEXT: for.body: %loadD = load i32, ptr %gep.d, align 4
+; CHECK-NEXT: for.body: %load.strided.a = load i32, ptr %gep.strided.a, align 4
+; CHECK-NEXT: for.body: store i32 %mul.c, ptr %gep.c, align 4
+; CHECK-NEXT: for.body: br i1 %exitcond, label %exit, label %for.body
+; CHECK-NEXT: for.body: %exitcond = icmp eq i64 %add, 20
+; CHECK-NEXT: for.body: %add = add nuw nsw i64 %ind, 1
+; CHECK-NEXT: for.body: %ind = phi i64 [ 0, %entry ], [ %add, %for.body ]
+; CHECK-NEXT: for.body: %mul.c = mul i32 %loadD, %load.strided.a
+; CHECK-NEXT: for.body: %gep.c = getelementptr inbounds i32, ptr %c, i64 %ind
+; CHECK-NEXT: for.body: %gep.strided.a = getelementptr inbounds i32, ptr %a, i64 %mul
+; CHECK-NEXT: for.body: %mul = mul i64 %ind, %stride
+; CHECK-NEXT: for.body: %gep.d = getelementptr inbounds i32, ptr %d, i64 %ind
+; CHECK-NEXT: LDist: Distributing loop: for.body
+; CHECK-NEXT: LDist: Pointers:
+; CHECK-NEXT: LDist: After removing unused Instrs:
+; CHECK-NEXT: LDist: Partition 0:
+; CHECK-NEXT: for.body.ldist1: ; preds = %for.body.ldist1, %for.body.ph.ldist1
+; CHECK-NEXT: %ind.ldist1 = phi i64 [ 0, %for.body.ph.ldist1 ], [ %add.ldist1, %for.body.ldist1 ]
+; CHECK-NEXT: %gep.a.ldist1 = getelementptr inbounds i32, ptr %a, i64 %ind.ldist1
+; CHECK-NEXT: %load.a.ldist1 = load i32, ptr %gep.a.ldist1, align 4
+; CHECK-NEXT: %gep.b.ldist1 = getelementptr inbounds i32, ptr %b, i64 %ind.ldist1
+; CHECK-NEXT: %load.b.ldist1 = load i32, ptr %gep.b.ldist1, align 4
+; CHECK-NEXT: %mul.a.ldist1 = mul i32 %load.b.ldist1, %load.a.ldist1
+; CHECK-NEXT: %add.ldist1 = add nuw nsw i64 %ind.ldist1, 1
+; CHECK-NEXT: %gep.a.plus4.ldist1 = getelementptr inbounds i32, ptr %a, i64 %add.ldist1
+; CHECK-NEXT: store i32 %mul.a.ldist1, ptr %gep.a.plus4.ldist1, align 4
+; CHECK-NEXT: %exitcond.ldist1 = icmp eq i64 %add.ldist1, 20
+; CHECK-NEXT: br i1 %exitcond.ldist1, label %for.body.ph, label %for.body.ldist1
+; CHECK-NEXT: LDist: Partition 1:
+; CHECK-NEXT: for.body: ; preds = %for.body, %for.body.ph
+; CHECK-NEXT: %ind = phi i64 [ 0, %for.body.ph ], [ %add, %for.body ]
+; CHECK-NEXT: %add = add nuw nsw i64 %ind, 1
+; CHECK-NEXT: %gep.d = getelementptr inbounds i32, ptr %d, i64 %ind
+; CHECK-NEXT: %loadD = load i32, ptr %gep.d, align 4
+; CHECK-NEXT: %mul = mul i64 %ind, %stride
+; CHECK-NEXT: %gep.strided.a = getelementptr inbounds i32, ptr %a, i64 %mul
+; CHECK-NEXT: %load.strided.a = load i32, ptr %gep.strided.a, align 4
+; CHECK-NEXT: %mul.c = mul i32 %loadD, %load.strided.a
+; CHECK-NEXT: %gep.c = getelementptr inbounds i32, ptr %c, i64 %ind
+; CHECK-NEXT: store i32 %mul.c, ptr %gep.c, align 4
+; CHECK-NEXT: %exitcond = icmp eq i64 %add, 20
+; CHECK-NEXT: br i1 %exitcond, label %exit.loopexit1, label %for.body
+;
entry:
br label %for.body
diff --git a/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/loop-distribute.ll b/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/loop-distribute.ll
new file mode 100644
index 00000000000000..48f80533c6379b
--- /dev/null
+++ b/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/loop-distribute.ll
@@ -0,0 +1,27 @@
+; RUN: opt -passes=loop-distribute -enable-loop-distribute \
+; RUN: -debug-only=loop-distribute -disable-output 2>&1 %s | FileCheck %s
+
+define void @ldist(i1 %c, ptr %A, ptr %B, ptr %C) {
+entry:
+ br label %for.body
+
+for.body: ; preds = %if.end, %entry
+ %iv = phi i16 [ 0, %entry ], [ %iv.next, %if.end ]
+ %lv = load i16, ptr %A, align 1
+ store i16 %lv, ptr %A, align 1
+ br i1 %c, label %if.then, label %if.end
+
+if.then: ; preds = %for.body
+ %lv2 = load i16, ptr %A, align 1
+ br label %if.end
+
+if.end: ; preds = %if.then, %for.body
+ %c.sink = phi ptr [ %B, %if.then ], [ %C, %for.body ]
+ %lv3 = load i16, ptr %c.sink
+ %iv.next = add nuw nsw i16 %iv, 1
+ %tobool.not = icmp eq i16 %iv.next, 1000
+ br i1 %tobool.not, label %for.end.loopexit, label %for.body
+
+for.end.loopexit: ; preds = %if.end
+ ret void
+}
diff --git a/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/loop-distribute.ll.expected b/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/loop-distribute.ll.expected
new file mode 100644
index 00000000000000..baef851b84ee54
--- /dev/null
+++ b/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/loop-distribute.ll.expected
@@ -0,0 +1,118 @@
+; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py
+; RUN: opt -passes=loop-distribute -enable-loop-distribute \
+; RUN: -debug-only=loop-distribute -disable-output 2>&1 %s | FileCheck %s
+
+define void @ldist(i1 %c, ptr %A, ptr %B, ptr %C) {
+; CHECK-LABEL: 'ldist'
+; CHECK-NEXT: LDist: Found a candidate loop: for.body
+; CHECK-NEXT: LDist: Backward dependences:
+; CHECK-NEXT: Unknown:
+; CHECK-NEXT: %lv = load i16, ptr %A, align 1 ->
+; CHECK-NEXT: store i16 %lv, ptr %A, align 1
+; CHECK-NEXT: Unknown:
+; CHECK-NEXT: store i16 %lv, ptr %A, align 1 ->
+; CHECK-NEXT: %lv2 = load i16, ptr %A, align 1
+; CHECK-NEXT: LDist: Seeded partitions:
+; CHECK-NEXT: LDist: Partition 0: (cycle)
+; CHECK-NEXT: for.body: %lv = load i16, ptr %A, align 1
+; CHECK-NEXT: for.body: store i16 %lv, ptr %A, align 1
+; CHECK-NEXT: if.then: %lv2 = load i16, ptr %A, align 1
+; CHECK-NEXT: LDist: Partition 1:
+; CHECK-NEXT: if.end: %lv3 = load i16, ptr %c.sink, align 2
+; CHECK-NEXT: LDist: Partition 2:
+; CHECK-NEXT: if.end: %lv3 = load i16, ptr %c.sink, align 2
+; CHECK-NEXT: LDist: Merged partitions:
+; CHECK-NEXT: LDist: Partition 0: (cycle)
+; CHECK-NEXT: for.body: %lv = load i16, ptr %A, align 1
+; CHECK-NEXT: for.body: store i16 %lv, ptr %A, align 1
+; CHECK-NEXT: if.then: %lv2 = load i16, ptr %A, align 1
+; CHECK-NEXT: LDist: Partition 1:
+; CHECK-NEXT: if.end: %lv3 = load i16, ptr %c.sink, align 2
+; CHECK-NEXT: LDist: Populated partitions:
+; CHECK-NEXT: LDist: Partition 0: (cycle)
+; CHECK-NEXT: for.body: %lv = load i16, ptr %A, align 1
+; CHECK-NEXT: for.body: store i16 %lv, ptr %A, align 1
+; CHECK-NEXT: if.then: %lv2 = load i16, ptr %A, align 1
+; CHECK-NEXT: for.body: br i1 %c, label %if.then, label %if.end
+; CHECK-NEXT: if.then: br label %if.end
+; CHECK-NEXT: if.end: br i1 %tobool.not, label %for.end.loopexit, label %for.body
+; CHECK-NEXT: if.end: %tobool.not = icmp eq i16 %iv.next, 1000
+; CHECK-NEXT: if.end: %iv.next = add nuw nsw i16 %iv, 1
+; CHECK-NEXT: for.body: %iv = phi i16 [ 0, %entry ], [ %iv.next, %if.end ]
+; CHECK-NEXT: LDist: Partition 1:
+; CHECK-NEXT: if.end: %lv3 = load i16, ptr %c.sink, align 2
+; CHECK-NEXT: for.body: br i1 %c, label %if.then, label %if.end
+; CHECK-NEXT: if.then: br label %if.end
+; CHECK-NEXT: if.end: br i1 %tobool.not, label %for.end.loopexit, label %for.body
+; CHECK-NEXT: if.end: %tobool.not = icmp eq i16 %iv.next, 1000
+; CHECK-NEXT: if.end: %iv.next = add nuw nsw i16 %iv, 1
+; CHECK-NEXT: for.body: %iv = phi i16 [ 0, %entry ], [ %iv.next, %if.end ]
+; CHECK-NEXT: if.end: %c.sink = phi ptr [ %B, %if.then ], [ %C, %for.body ]
+; CHECK-NEXT: LDist: Distributing loop: for.body
+; CHECK-NEXT: LDist: Pointers:
+; CHECK-NEXT: Check 0:
+; CHECK-NEXT: Comparing group ([[GRP1:0x[0-9a-f]+]]):
+; CHECK-NEXT: ptr %A
+; CHECK-NEXT: ptr %A
+; CHECK-NEXT: Against group ([[GRP2:0x[0-9a-f]+]]):
+; CHECK-NEXT: ptr %C
+; CHECK-NEXT: Check 1:
+; CHECK-NEXT: Comparing group ([[GRP1]]):
+; CHECK-NEXT: ptr %A
+; CHECK-NEXT: ptr %A
+; CHECK-NEXT: Against group ([[GRP3:0x[0-9a-f]+]]):
+; CHECK-NEXT: ptr %B
+; CHECK-NEXT: LDist: After removing unused Instrs:
+; CHECK-NEXT: LDist: Partition 0:
+; CHECK-NEXT: for.body.ldist1: ; preds = %if.end.ldist1, %for.body.ph.ldist1
+; CHECK-NEXT: %iv.ldist1 = phi i16 [ 0, %for.body.ph.ldist1 ], [ %iv.next.ldist1, %if.end.ldist1 ]
+; CHECK-NEXT: %lv.ldist1 = load i16, ptr %A, align 1, !alias.scope !0, !noalias !3
+; CHECK-NEXT: store i16 %lv.ldist1, ptr %A, align 1, !alias.scope !0, !noalias !3
+; CHECK-NEXT: br i1 %c, label %if.then.ldist1, label %if.end.ldist1
+; CHECK-EMPTY:
+; CHECK-NEXT: if.then.ldist1: ; preds = %for.body.ldist1
+; CHECK-NEXT: %lv2.ldist1 = load i16, ptr %A, align 1, !alias.scope !0, !noalias !3
+; CHECK-NEXT: br label %if.end.ldist1
+; CHECK-EMPTY:
+; CHECK-NEXT: if.end.ldist1: ; preds = %if.then.ldist1, %for.body.ldist1
+; CHECK-NEXT: %iv.next.ldist1 = add nuw nsw i16 %iv.ldist1, 1
+; CHECK-NEXT: %tobool.not.ldist1 = icmp eq i16 %iv.next.ldist1, 1000
+; CHECK-NEXT: br i1 %tobool.not.ldist1, label %for.body.ph, label %for.body.ldist1
+; CHECK-NEXT: LDist: Partition 1:
+; CHECK-NEXT: for.body: ; preds = %if.end, %for.body.ph
+; CHECK-NEXT: %iv = phi i16 [ 0, %for.body.ph ], [ %iv.next, %if.end ]
+; CHECK-NEXT: br i1 %c, label %if.then, label %if.end
+; CHECK-EMPTY:
+; CHECK-NEXT: if.then: ; preds = %for.body
+; CHECK-NEXT: br label %if.end
+; CHECK-EMPTY:
+; CHECK-NEXT: if.end: ; preds = %if.then, %for.body
+; CHECK-NEXT: %c.sink = phi ptr [ %B, %if.then ], [ %C, %for.body ]
+; CHECK-NEXT: %lv3 = load i16, ptr %c.sink, align 2
+; CHECK-NEXT: %iv.next = add nuw nsw i16 %iv, 1
+; CHECK-NEXT: %tobool.not = icmp eq i16 %iv.next, 1000
+; CHECK-NEXT: br i1 %tobool.not, label %for.end.loopexit.loopexit6, label %for.body
+;
+entry:
+ br label %for.body
+
+for.body: ; preds = %if.end, %entry
+ %iv = phi i16 [ 0, %entry ], [ %iv.next, %if.end ]
+ %lv = load i16, ptr %A, align 1
+ store i16 %lv, ptr %A, align 1
+ br i1 %c, label %if.then, label %if.end
+
+if.then: ; preds = %for.body
+ %lv2 = load i16, ptr %A, align 1
+ br label %if.end
+
+if.end: ; preds = %if.then, %for.body
+ %c.sink = phi ptr [ %B, %if.then ], [ %C, %for.body ]
+ %lv3 = load i16, ptr %c.sink
+ %iv.next = add nuw nsw i16 %iv, 1
+ %tobool.not = icmp eq i16 %iv.next, 1000
+ br i1 %tobool.not, label %for.end.loopexit, label %for.body
+
+for.end.loopexit: ; preds = %if.end
+ ret void
+}
diff --git a/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/loop-distribute.test b/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/loop-distribute.test
new file mode 100644
index 00000000000000..65a44fafc7d5a0
--- /dev/null
+++ b/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/loop-distribute.test
@@ -0,0 +1,6 @@
+## Basic test checking that update_analyze_test_checks.py works correctly
+# RUN: cp -f %S/Inputs/loop-distribute.ll %t.ll && %update_analyze_test_checks %t.ll
+# RUN: diff -u %t.ll %S/Inputs/loop-distribute.ll.expected
+## Check that running the script again does not change the result:
+# RUN: %update_analyze_test_checks %t.ll
+# RUN: diff -u %t.ll %S/Inputs/loop-distribute.ll.expected
diff --git a/llvm/utils/UpdateTestChecks/common.py b/llvm/utils/UpdateTestChecks/common.py
index 85c129488d950e..eb212ed304e9db 100644
--- a/llvm/utils/UpdateTestChecks/common.py
+++ b/llvm/utils/UpdateTestChecks/common.py
@@ -569,7 +569,7 @@ def invoke_tool(exe, cmd_args, ir, preprocess_cmd=None, verbose=False):
flags=(re.X | re.S),
)
-LV_DEBUG_RE = re.compile(
+LOOP_PASS_DEBUG_RE = re.compile(
r"^\s*\'(?P<func>[\w.$-]+?)\'[^\n]*" r"\s*\n(?P<body>.*)$", flags=(re.X | re.S)
)
@@ -973,6 +973,7 @@ class NamelessValue:
name (as in e.g. `@some_global` or `%x`) or just a number (as in e.g. `%12`
or `!4`).
"""
+
def __init__(
self,
check_prefix,
@@ -1635,8 +1636,9 @@ def generalize_check_lines(
regexp = ginfo.get_regexp()
multiple_braces_re = re.compile(r"({{+)|(}}+)")
+
def escape_braces(match_obj):
- return '{{' + re.escape(match_obj.group(0)) + '}}'
+ return "{{" + re.escape(match_obj.group(0)) + "}}"
if ginfo.is_ir():
for i, line in enumerate(lines):
diff --git a/llvm/utils/update_analyze_test_checks.py b/llvm/utils/update_analyze_test_checks.py
index 47506626a0a58b..d356ebead0d81a 100755
--- a/llvm/utils/update_analyze_test_checks.py
+++ b/llvm/utils/update_analyze_test_checks.py
@@ -134,13 +134,15 @@ def main():
raw_tool_output,
prefixes,
)
- elif re.search(r"LV: Checking a loop in ", raw_tool_outputs) is not None:
- # Split analysis outputs by "Printing analysis " declarations.
+ elif (
+ re.search(r"(LV|LDist): Checking a loop in ", raw_tool_outputs)
+ is not None
+ ):
for raw_tool_output in re.split(
- r"LV: Checking a loop in ", raw_tool_outputs
+ r"(LV|LDist): Checking a loop in ", raw_tool_outputs
):
builder.process_run_line(
- common.LV_DEBUG_RE,
+ common.LOOP_PASS_DEBUG_RE,
common.scrub_body,
raw_tool_output,
prefixes,
More information about the llvm-commits
mailing list