Skip to content

Commit 5ec75c6

Browse files
committed
[ConstantRangeTest] Print detailed information on failure (NFC)
When the optimality check fails, print the inputs, the computed range and the better range that was found. This makes it much simpler to identify the cause of the failure. Make sure that full ranges (which, unlikely all the other cases, have multiple ways to construct them that all result in the same range) only print one message by handling them separately.
1 parent 28d9953 commit 5ec75c6

File tree

1 file changed

+27
-14
lines changed

1 file changed

+27
-14
lines changed

llvm/unittests/IR/ConstantRangeTest.cpp

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -94,28 +94,37 @@ bool PreferSmallestNonFullSigned(const ConstantRange &CR1,
9494
return PreferSmallestSigned(CR1, CR2);
9595
}
9696

97+
98+
9799
// Check whether constant range CR is an optimal approximation of the set
98100
// Elems under the given PreferenceFn. The preference function should return
99101
// true if the first range argument is strictly preferred to the second one.
100102
static void TestRange(const ConstantRange &CR, const SmallBitVector &Elems,
101-
PreferFn PreferenceFn) {
103+
PreferFn PreferenceFn, ArrayRef<ConstantRange> Inputs) {
102104
unsigned BitWidth = CR.getBitWidth();
103105

104106
// Check conservative correctness.
105107
for (unsigned Elem : Elems.set_bits()) {
106108
EXPECT_TRUE(CR.contains(APInt(BitWidth, Elem)));
107109
}
108110

109-
// Make sure we have at least two elements for the code below.
111+
// Make sure we have at least one element for the code below.
110112
if (Elems.none()) {
111113
EXPECT_TRUE(CR.isEmptySet());
112114
return;
113115
}
114116

115-
if (Elems.count() == 1) {
116-
EXPECT_TRUE(CR.isSingleElement());
117-
return;
118-
}
117+
auto NotPreferred = [&](const ConstantRange &PossibleCR) {
118+
if (!PreferenceFn(PossibleCR, CR))
119+
return testing::AssertionSuccess();
120+
121+
testing::AssertionResult Result = testing::AssertionFailure();
122+
Result << "Inputs = ";
123+
for (const ConstantRange &Input : Inputs)
124+
Result << Input << ", ";
125+
Result << "CR = " << CR << ", BetterCR = " << PossibleCR;
126+
return Result;
127+
};
119128

120129
// Look at all pairs of adjacent elements and the slack-free ranges
121130
// [Elem, PrevElem] they imply. Check that none of the ranges are strictly
@@ -130,12 +139,16 @@ static void TestRange(const ConstantRange &CR, const SmallBitVector &Elems,
130139
ConstantRange PossibleCR =
131140
ConstantRange::getNonEmpty(APInt(BitWidth, Elem),
132141
APInt(BitWidth, PrevElem) + 1);
133-
// There should be no range that is preferred over CR.
134-
EXPECT_FALSE(PreferenceFn(PossibleCR, CR))
135-
<< "CR = " << CR << ", BetterCR = " << PossibleCR;
142+
// We get a full range any time PrevElem and Elem are adjacent. Avoid
143+
// repeated checks by skipping here, and explicitly checking below instead.
144+
if (!PossibleCR.isFullSet()) {
145+
EXPECT_TRUE(NotPreferred(PossibleCR));
146+
}
136147

137148
PrevElem = Elem;
138149
} while (Elem != FirstElem);
150+
151+
EXPECT_TRUE(NotPreferred(ConstantRange::getFull(BitWidth)));
139152
}
140153

141154
using UnaryRangeFn = llvm::function_ref<ConstantRange(const ConstantRange &)>;
@@ -150,7 +163,7 @@ static void TestUnaryOpExhaustive(UnaryRangeFn RangeFn, UnaryIntFn IntFn,
150163
if (Optional<APInt> ResultN = IntFn(N))
151164
Elems.set(ResultN->getZExtValue());
152165
});
153-
TestRange(RangeFn(CR), Elems, PreferenceFn);
166+
TestRange(RangeFn(CR), Elems, PreferenceFn, {CR});
154167
});
155168
}
156169

@@ -171,7 +184,7 @@ static void TestBinaryOpExhaustive(BinaryRangeFn RangeFn, BinaryIntFn IntFn,
171184
Elems.set(ResultN->getZExtValue());
172185
});
173186
});
174-
TestRange(RangeFn(CR1, CR2), Elems, PreferenceFn);
187+
TestRange(RangeFn(CR1, CR2), Elems, PreferenceFn, {CR1, CR2});
175188
});
176189
}
177190

@@ -543,13 +556,13 @@ void testBinarySetOperationExhaustive(Fn1 OpFn, Fn2 InResultFn) {
543556
Elems.set(Num.getZExtValue());
544557

545558
ConstantRange SmallestCR = OpFn(CR1, CR2, ConstantRange::Smallest);
546-
TestRange(SmallestCR, Elems, PreferSmallest);
559+
TestRange(SmallestCR, Elems, PreferSmallest, {CR1, CR2});
547560

548561
ConstantRange UnsignedCR = OpFn(CR1, CR2, ConstantRange::Unsigned);
549-
TestRange(UnsignedCR, Elems, PreferSmallestNonFullUnsigned);
562+
TestRange(UnsignedCR, Elems, PreferSmallestNonFullUnsigned, {CR1, CR2});
550563

551564
ConstantRange SignedCR = OpFn(CR1, CR2, ConstantRange::Signed);
552-
TestRange(SignedCR, Elems, PreferSmallestNonFullSigned);
565+
TestRange(SignedCR, Elems, PreferSmallestNonFullSigned, {CR1, CR2});
553566
});
554567
}
555568

0 commit comments

Comments
 (0)