Skip to content

Commit c1342ac

Browse files
TEMP: wip changes
1 parent 7ae1903 commit c1342ac

File tree

7 files changed

+164
-1
lines changed

7 files changed

+164
-1
lines changed

llvm/lib/Analysis/InstructionSimplify.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3693,6 +3693,7 @@ static Value *simplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
36933693
auto RHS_Instr = cast<Instruction>(RHS);
36943694
auto LHS_Instr = cast<Instruction>(LHS);
36953695

3696+
// TODO: look at all usages of MD_range and adapt to look at range attributes on arguments too
36963697
if (Q.IIQ.getMetadata(RHS_Instr, LLVMContext::MD_range) &&
36973698
Q.IIQ.getMetadata(LHS_Instr, LLVMContext::MD_range)) {
36983699
auto RHS_CR = getConstantRangeFromMetadata(

llvm/lib/AsmParser/LLParser.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2806,6 +2806,32 @@ bool LLParser::parseRequiredMetadataAttr(AttrBuilder &B, lltok::Kind AttrToken,
28062806
return error(Lex.getLoc(), "expected '('");
28072807
if (parseMetadata(Meta, nullptr))
28082808
return true;
2809+
// TODO: this doesn't work because RAUW doesn't work.
2810+
//
2811+
// The general sequence of events is:
2812+
// 1. A forward referenced metadata node, like `@foo(i64 range(!0) %a)` is parsed.
2813+
// 2. Because it's forward declared, we insert a temp md node in `LLParser::ForwardRefMDNodes`,
2814+
// and return a pointer to that temp md node.
2815+
// 3. We add the metadata attribute to the function argument, and the attribute is interned
2816+
// (using the temp md node) via `AttributeImpl::Profile` and the `Attribute::get(..., Metadata*)` overload.
2817+
// 4. We later parse the definition of the forward-declared metadata, like `!0 = !{i64 0, i64 1}`,
2818+
// extract the temp md node pointer from `LLParser::ForwardRefMDNodes`, and call RAUW on it.
2819+
// But this doesn't update the attribute, which has already been interned with the temp md node.
2820+
//
2821+
// Solutions (with varying degrees of badness and functionality):
2822+
// 1. Use TrackingMDRef. Although it is intended for this use case, it only allows other metadata nodes as parents
2823+
// (see `using OwnerTy = PointerUnion<MetadataAsValue *, Metadata *>;`), so it won't actually update the attribute.
2824+
// Potentially, this could be expanded to allow attributes as owners, but it seems like attributes themselves don't support RAUW
2825+
// (they're intended to be immutable?), so I'd also have to implement that...
2826+
// 2. Add another temp data structure holding incomplete metadata attributes, similar to `ForwardRefMDNodes`,
2827+
// that contains, e.g. the function, argument index, attribute kind, etc. Then, when we encounter
2828+
// a metadata attribute with forward declared metadata, we defer adding the attribute until we later parse the definition.
2829+
// This is a bit awkward to implement in the parser, because we'd have to pass down the enclosing function,
2830+
// argument index, etc. through a bunch of layers (right now we just pass an AttrBuilder reference).
2831+
// 3. (this solution) Forbid forward declared metadata in metadata attributes. This is only a problem for textual IR, so maybe it's fine?
2832+
if (cast<MDNode>(Meta)->isTemporary())
2833+
return error(Lex.getLoc(), "metadata in metadata attribute "
2834+
"cannot be forward declared");
28092835
if (!EatIfPresent(lltok::rparen))
28102836
return error(Lex.getLoc(), "expected ')'");
28112837

llvm/lib/IR/AttributeImpl.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "llvm/ADT/FoldingSet.h"
2121
#include "llvm/ADT/StringRef.h"
2222
#include "llvm/IR/Attributes.h"
23+
#include "llvm/IR/TrackingMDRef.h"
2324
#include "llvm/Support/TrailingObjects.h"
2425
#include <cassert>
2526
#include <cstddef>
@@ -120,6 +121,9 @@ class AttributeImpl : public FoldingSetNode {
120121
static void Profile(FoldingSetNodeID &ID, Attribute::AttrKind Kind,
121122
Metadata *Meta) {
122123
ID.AddInteger(Kind);
124+
//Meta->dump();
125+
//if (MDNode* MD = cast<MDNode>(Meta))
126+
// assert(MD->isResolved() && "not resolved");
123127
ID.AddPointer(Meta);
124128
}
125129
};
@@ -211,7 +215,9 @@ class TypeAttributeImpl : public EnumAttributeImpl {
211215
};
212216

213217
class MetadataAttributeImpl : public EnumAttributeImpl {
214-
Metadata *Meta;
218+
// TODO maybe?
219+
// TrackingMDRef Meta;
220+
Metadata* Meta;
215221

216222
public:
217223
MetadataAttributeImpl(Attribute::AttrKind Kind, Metadata *Meta)

llvm/lib/IR/Attributes.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -615,7 +615,9 @@ std::string Attribute::getAsString(bool InAttrGrp) const {
615615
bool Attribute::hasParentContext(LLVMContext &C) const {
616616
assert(isValid() && "invalid Attribute doesn't refer to any context");
617617
FoldingSetNodeID ID;
618+
// printf("about to profile for context\n");
618619
pImpl->Profile(ID);
620+
// printf("done profiling for context\n");
619621
void *Unused;
620622
return C.pImpl->AttrsSet.FindNodeOrInsertPos(ID, Unused) == pImpl;
621623
}

llvm/lib/IR/Verifier.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1876,6 +1876,8 @@ void Verifier::verifyParameterAttrs(AttributeSet Attrs, Type *Ty,
18761876

18771877
if (Attrs.hasAttribute(Attribute::Range)) {
18781878
MDNode* Meta = Attrs.getRangeMetadata();
1879+
//Meta->dump();
1880+
//Meta->dumpTree();
18791881
visitRangeMetadata(Meta, Ty);
18801882
}
18811883

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
; RUN: not llvm-as < %s -o /dev/null 2>&1 | FileCheck %s
2+
3+
!2 = !{i8 0}
4+
5+
define i8 @f3(i8 range(!2) %x) {
6+
entry:
7+
ret i8 %x
8+
}
9+
10+
; CHECK: Unfinished range!

llvm/test/Verifier/range-attr.ll

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
; RUN: not llvm-as < %s -o /dev/null 2>&1 | FileCheck %s
2+
3+
define i8 @f2(i8 range(!1) %x) {
4+
entry:
5+
ret i8 %x
6+
}
7+
!1 = !{}
8+
; CHECK: It should have at least one range!
9+
10+
define i8 @f3(i8 range(!2) %x) {
11+
entry:
12+
ret i8 %x
13+
}
14+
!2 = !{i8 0}
15+
; CHECK: Unfinished range!
16+
17+
define i8 @f4(i8 range(!3) %x) {
18+
entry:
19+
ret i8 %x
20+
}
21+
!3 = !{double 0.0, i8 0}
22+
; CHECK: The lower limit must be an integer!
23+
24+
define i8 @f5(i8 range(!4) %x) {
25+
entry:
26+
ret i8 %x
27+
}
28+
!4 = !{i8 0, double 0.0}
29+
; CHECK: The upper limit must be an integer!
30+
31+
define i8 @f6(i8 range(!5) %x) {
32+
entry:
33+
ret i8 %x
34+
}
35+
!5 = !{i32 0, i8 0}
36+
; CHECK: Range types must match instruction type!
37+
; CHECK: i8
38+
39+
define i8 @f7(i8 range(!6) %x) {
40+
entry:
41+
ret i8 %x
42+
}
43+
!6 = !{i8 0, i32 0}
44+
; CHECK: Range types must match instruction type!
45+
; CHECK: i8
46+
47+
define i8 @f8(i8 range(!7) %x) {
48+
entry:
49+
ret i8 %x
50+
}
51+
!7 = !{i32 0, i32 0}
52+
; CHECK: Range types must match instruction type!
53+
; CHECK: i8
54+
55+
define i8 @f9(i8 range(!8) %x) {
56+
entry:
57+
ret i8 %x
58+
}
59+
!8 = !{i8 0, i8 0}
60+
; CHECK: Range must not be empty!
61+
62+
define i8 @f10(i8 range(!9) %x) {
63+
entry:
64+
ret i8 %x
65+
}
66+
!9 = !{i8 0, i8 2, i8 1, i8 3}
67+
; CHECK: Intervals are overlapping
68+
69+
define i8 @f11(i8 range(!10) %x) {
70+
entry:
71+
ret i8 %x
72+
}
73+
!10 = !{i8 0, i8 2, i8 2, i8 3}
74+
; CHECK: Intervals are contiguous
75+
76+
define i8 @f12(i8 range(!11) %x) {
77+
entry:
78+
ret i8 %x
79+
}
80+
!11 = !{i8 1, i8 2, i8 -1, i8 0}
81+
; CHECK: Intervals are not in order
82+
83+
define i8 @f13(i8 range(!12) %x) {
84+
entry:
85+
ret i8 %x
86+
}
87+
!12 = !{i8 1, i8 3, i8 5, i8 1}
88+
; CHECK: Intervals are contiguous
89+
90+
define i8 @f14(i8 range(!13) %x) {
91+
entry:
92+
ret i8 %x
93+
}
94+
!13 = !{i8 1, i8 3, i8 5, i8 2}
95+
; CHECK: Intervals are overlapping
96+
97+
define i8 @f15(i8 range(!14) %x) {
98+
entry:
99+
ret i8 %x
100+
}
101+
!14 = !{i8 10, i8 1, i8 12, i8 13}
102+
; CHECK: Intervals are overlapping
103+
104+
define i8 @f16(i8 range(!16) %x) {
105+
entry:
106+
ret i8 %x
107+
}
108+
!16 = !{i8 1, i8 3, i8 4, i8 5, i8 6, i8 2}
109+
; CHECK: Intervals are overlapping
110+
111+
define i8 @f17(i8 range(!17) %x) {
112+
entry:
113+
ret i8 %x
114+
}
115+
!17 = !{i8 1, i8 3, i8 4, i8 5, i8 6, i8 1}
116+
; CHECK: Intervals are contiguous

0 commit comments

Comments
 (0)