Skip to content

Commit 4c4669a

Browse files
committed
Extend verify pass to cover new metadata
1 parent 7b27203 commit 4c4669a

File tree

6 files changed

+80
-6
lines changed

6 files changed

+80
-6
lines changed

llvm/docs/LangRef.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7950,8 +7950,8 @@ loop distribution pass. See
79507950

79517951
This metadata records an estimated trip count for the loop. The first operand
79527952
is the string ``llvm.loop.estimated_trip_count``. The second operand is an
7953-
integer specifying the count, which might be omitted for the reasons described
7954-
below. For example:
7953+
integer constant of type ``i32`` or smaller specifying the count, which might be
7954+
omitted for the reasons described below. For example:
79557955

79567956
.. code-block:: llvm
79577957

llvm/include/llvm/IR/Metadata.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -911,8 +911,8 @@ class MDOperand {
911911

912912
// Check if MDOperand is of type MDString and equals `Str`.
913913
bool equalsStr(StringRef Str) const {
914-
return isa<MDString>(this->get()) &&
915-
cast<MDString>(this->get())->getString() == Str;
914+
return isa_and_nonnull<MDString>(get()) &&
915+
cast<MDString>(get())->getString() == Str;
916916
}
917917

918918
~MDOperand() { untrack(); }

llvm/include/llvm/Transforms/Utils/LoopUtils.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ typedef std::pair<const RuntimeCheckingPtrGroup *,
5252
template <typename T, unsigned N> class SmallSetVector;
5353
template <typename T, unsigned N> class SmallPriorityWorklist;
5454

55+
const char *const LLVMLoopEstimatedTripCount = "llvm.loop.estimated_trip_count";
56+
5557
LLVM_ABI BasicBlock *InsertPreheaderForLoop(Loop *L, DominatorTree *DT,
5658
LoopInfo *LI,
5759
MemorySSAUpdater *MSSAU,

llvm/lib/IR/Verifier.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@
121121
#include "llvm/Support/MathExtras.h"
122122
#include "llvm/Support/ModRef.h"
123123
#include "llvm/Support/raw_ostream.h"
124+
#include "llvm/Transforms/Utils/LoopUtils.h"
124125
#include <algorithm>
125126
#include <cassert>
126127
#include <cstdint>
@@ -1071,6 +1072,21 @@ void Verifier::visitMDNode(const MDNode &MD, AreDebugLocsAllowed AllowLocs) {
10711072
}
10721073
}
10731074

1075+
// Check llvm.loop.estimated_trip_count.
1076+
if (MD.getNumOperands() > 0 &&
1077+
MD.getOperand(0).equalsStr(LLVMLoopEstimatedTripCount)) {
1078+
Check(MD.getNumOperands() == 1 || MD.getNumOperands() == 2,
1079+
"Expected one or two operands", &MD);
1080+
if (MD.getNumOperands() == 2) {
1081+
auto *Count = dyn_cast_or_null<ConstantAsMetadata>(MD.getOperand(1));
1082+
Check(Count && Count->getType()->isIntegerTy() &&
1083+
cast<IntegerType>(Count->getType())->getBitWidth() <= 32,
1084+
"Expected optional second operand to be an integer constant of "
1085+
"type i32 or smaller",
1086+
&MD);
1087+
}
1088+
}
1089+
10741090
// Check these last, so we diagnose problems in operands first.
10751091
Check(!MD.isTemporary(), "Expected no forward declarations!", &MD);
10761092
Check(MD.isResolved(), "All nodes should be resolved!", &MD);

llvm/lib/Transforms/Utils/LoopUtils.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,6 @@ using namespace llvm::PatternMatch;
5454

5555
static const char *LLVMLoopDisableNonforced = "llvm.loop.disable_nonforced";
5656
static const char *LLVMLoopDisableLICM = "llvm.licm.disable";
57-
static const char *LLVMLoopEstimatedTripCount =
58-
"llvm.loop.estimated_trip_count";
5957

6058
bool llvm::formDedicatedExitBlocks(Loop *L, DominatorTree *DT, LoopInfo *LI,
6159
MemorySSAUpdater *MSSAU,
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
; Test "llvm.loop.estimated_trip_count" validation
2+
3+
; DEFINE: %{RUN} = opt -passes=verify %t -disable-output 2>&1 | \
4+
; DEFINE: FileCheck %s -allow-empty -check-prefix
5+
6+
define void @test() {
7+
entry:
8+
br label %body
9+
body:
10+
br i1 0, label %body, label %exit, !llvm.loop !0
11+
exit:
12+
ret void
13+
}
14+
!0 = distinct !{!0, !1}
15+
16+
; GOOD-NOT: {{.}}
17+
18+
; BAD-VALUE: Expected optional second operand to be an integer constant of type i32 or smaller
19+
; BAD-VALUE-NEXT: !1 = !{!"llvm.loop.estimated_trip_count",
20+
21+
; TOO-MANY: Expected one or two operands
22+
; TOO-MANY-NEXT: !1 = !{!"llvm.loop.estimated_trip_count", i32 5, i32 5}
23+
24+
; No value.
25+
; RUN: cp %s %t
26+
; RUN: echo '!1 = !{!"llvm.loop.estimated_trip_count"}' >> %t
27+
; RUN: %{RUN} GOOD
28+
29+
; i16 value.
30+
; RUN: cp %s %t
31+
; RUN: echo '!1 = !{!"llvm.loop.estimated_trip_count", i16 5}' >> %t
32+
; RUN: %{RUN} GOOD
33+
34+
; i32 value.
35+
; RUN: cp %s %t
36+
; RUN: echo '!1 = !{!"llvm.loop.estimated_trip_count", i32 5}' >> %t
37+
; RUN: %{RUN} GOOD
38+
39+
; i64 value.
40+
; RUN: cp %s %t
41+
; RUN: echo '!1 = !{!"llvm.loop.estimated_trip_count", i64 5}' >> %t
42+
; RUN: not %{RUN} BAD-VALUE
43+
44+
; MDString value.
45+
; RUN: cp %s %t
46+
; RUN: echo '!1 = !{!"llvm.loop.estimated_trip_count", !"5"}' >> %t
47+
; RUN: not %{RUN} BAD-VALUE
48+
49+
; MDNode value.
50+
; RUN: cp %s %t
51+
; RUN: echo '!1 = !{!"llvm.loop.estimated_trip_count", !2}' >> %t
52+
; RUN: echo '!2 = !{i32 5}' >> %t
53+
; RUN: not %{RUN} BAD-VALUE
54+
55+
; Too many values.
56+
; RUN: cp %s %t
57+
; RUN: echo '!1 = !{!"llvm.loop.estimated_trip_count", i32 5, i32 5}' >> %t
58+
; RUN: not %{RUN} TOO-MANY

0 commit comments

Comments
 (0)