Skip to content

Commit f77f2b9

Browse files
authored
llvm-reduce: Try to preserve instruction metadata as argument attributes (#133557)
Fixes #131825
1 parent 0248d27 commit f77f2b9

File tree

4 files changed

+125
-1
lines changed

4 files changed

+125
-1
lines changed

llvm/include/llvm/IR/Attributes.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ class ConstantRangeList;
4242
class FoldingSetNodeID;
4343
class Function;
4444
class LLVMContext;
45+
class Instruction;
4546
class Type;
4647
class raw_ostream;
4748
enum FPClassTest : unsigned;
@@ -1285,6 +1286,11 @@ class AttrBuilder {
12851286
/// Add initializes attribute.
12861287
AttrBuilder &addInitializesAttr(const ConstantRangeList &CRL);
12871288

1289+
/// Add 0 or more parameter attributes which are equivalent to metadata
1290+
/// attached to \p I. e.g. !align -> align. This assumes the argument type is
1291+
/// the same as the original instruction and the attribute is compatible.
1292+
AttrBuilder &addFromEquivalentMetadata(const Instruction &I);
1293+
12881294
ArrayRef<Attribute> attrs() const { return Attrs; }
12891295

12901296
bool operator==(const AttrBuilder &B) const;

llvm/lib/IR/Attributes.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2291,6 +2291,38 @@ AttrBuilder &AttrBuilder::addInitializesAttr(const ConstantRangeList &CRL) {
22912291
return addConstantRangeListAttr(Attribute::Initializes, CRL.rangesRef());
22922292
}
22932293

2294+
AttrBuilder &AttrBuilder::addFromEquivalentMetadata(const Instruction &I) {
2295+
if (const MDNode *NonNull = I.getMetadata(LLVMContext::MD_nonnull))
2296+
addAttribute(Attribute::NonNull);
2297+
2298+
if (const MDNode *NoUndef = I.getMetadata(LLVMContext::MD_noundef))
2299+
addAttribute(Attribute::NoUndef);
2300+
2301+
if (const MDNode *Align = I.getMetadata(LLVMContext::MD_align)) {
2302+
ConstantInt *CI = mdconst::extract<ConstantInt>(Align->getOperand(0));
2303+
addAlignmentAttr(CI->getZExtValue());
2304+
}
2305+
2306+
if (const MDNode *Dereferenceable =
2307+
I.getMetadata(LLVMContext::MD_dereferenceable)) {
2308+
ConstantInt *CI =
2309+
mdconst::extract<ConstantInt>(Dereferenceable->getOperand(0));
2310+
addDereferenceableAttr(CI->getZExtValue());
2311+
}
2312+
2313+
if (const MDNode *DereferenceableOrNull =
2314+
I.getMetadata(LLVMContext::MD_dereferenceable_or_null)) {
2315+
ConstantInt *CI =
2316+
mdconst::extract<ConstantInt>(DereferenceableOrNull->getOperand(0));
2317+
addDereferenceableAttr(CI->getZExtValue());
2318+
}
2319+
2320+
if (const MDNode *Range = I.getMetadata(LLVMContext::MD_range))
2321+
addRangeAttr(getConstantRangeFromMetadata(*Range));
2322+
2323+
return *this;
2324+
}
2325+
22942326
AttrBuilder &AttrBuilder::merge(const AttrBuilder &B) {
22952327
// TODO: Could make this O(n) as we're merging two sorted lists.
22962328
for (const auto &I : B.attrs())
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
; Check that equivalent parameter attributes are introduced when
2+
; moving instructions with metadata to arguments.
3+
4+
; RUN: llvm-reduce %s -o %t --abort-on-invalid-reduction --delta-passes=operands-to-args --test FileCheck --test-arg %s --test-arg --check-prefix=INTERESTING --test-arg --input-file
5+
; RUN: FileCheck --input-file %t --check-prefix=REDUCED %s
6+
7+
; INTERESTING-LABEL: define ptr @use_nonnull(
8+
; REDUCED-LABEL: define ptr @use_nonnull(ptr nonnull %nonnull) {
9+
define ptr @use_nonnull() {
10+
%nonnull = load ptr, ptr null, !nonnull !0
11+
ret ptr %nonnull
12+
}
13+
14+
; INTERESTING-LABEL: define void @use_noundef(
15+
; REDUCED-LABEL: define void @use_noundef(ptr noundef %noundef, <2 x ptr> noundef %noundef_vec) {
16+
define void @use_noundef() {
17+
%noundef = load ptr, ptr null, !noundef !0
18+
%noundef_vec = load <2 x ptr>, ptr null, !noundef !0
19+
store ptr %noundef, ptr null
20+
store <2 x ptr> %noundef_vec, ptr null
21+
ret void
22+
}
23+
24+
; INTERESTING-LABEL: define ptr @use_align(
25+
; REDUCED-LABEL: define ptr @use_align(ptr align 16 %align) {
26+
define ptr @use_align() {
27+
%align = load ptr, ptr null, !align !1
28+
ret ptr %align
29+
}
30+
31+
; INTERESTING-LABEL: define ptr @use_dereferenceable(
32+
; REDUCED-LABEL: define ptr @use_dereferenceable(ptr dereferenceable(12345) %deref) {
33+
define ptr @use_dereferenceable() {
34+
%deref = load ptr, ptr null, !dereferenceable !2
35+
ret ptr %deref
36+
}
37+
38+
; INTERESTING-LABEL: define ptr @use_dereferenceable_or_null(
39+
; REDUCED-LABEL: define ptr @use_dereferenceable_or_null(ptr dereferenceable(77777) %deref) {
40+
define ptr @use_dereferenceable_or_null() {
41+
%deref = load ptr, ptr null, !dereferenceable_or_null !3
42+
ret ptr %deref
43+
}
44+
45+
; INTERESTING-LABEL: define void @use_range(
46+
; REDUCED-LABEL: define void @use_range(i32 range(i32 8, 25) %simple_range, i32 range(i32 8, 420) %disjoint_range, i32 range(i32 42, 0) %wrapping_range, <2 x i32> range(i32 8, 25) %vector_range) {
47+
define void @use_range() {
48+
%simple_range = load i32, ptr null, !range !4
49+
%disjoint_range = load i32, ptr null, !range !5
50+
%wrapping_range = load i32, ptr null, !range !6
51+
%vector_range = load <2 x i32>, ptr null, !range !4
52+
store i32 %simple_range, ptr null
53+
store i32 %disjoint_range, ptr null
54+
store i32 %wrapping_range, ptr null
55+
store <2 x i32> %vector_range, ptr null
56+
ret void
57+
}
58+
59+
; INTERESTING-LABEL: define void @use_noundef_range(
60+
; REDUCED-LABEL: define void @use_noundef_range(i32 noundef range(i32 8, 25) %load, <2 x i32> noundef range(i32 8, 25) %load_vec) {
61+
define void @use_noundef_range() {
62+
%load = load i32, ptr null, !range !4, !noundef !0
63+
%load_vec = load <2 x i32>, ptr null, !range !4, !noundef !0
64+
store i32 %load, ptr null
65+
store <2 x i32> %load_vec, ptr null
66+
ret void
67+
}
68+
69+
70+
71+
!0 = !{}
72+
!1 = !{i64 16}
73+
!2 = !{i64 12345}
74+
!3 = !{i64 77777}
75+
!4 = !{i32 8, i32 25}
76+
!5 = !{i32 8, i32 25, i32 69, i32 420}
77+
!6 = !{i32 42, i32 0}

llvm/tools/llvm-reduce/deltas/ReduceOperandsToArgs.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,8 @@ static void substituteOperandWithArgument(Function *OldF,
159159
VMap[&OldArg] = &NewArg; // Add mapping to VMap
160160
}
161161

162+
LLVMContext &Ctx = OldF->getContext();
163+
162164
// Adjust the new parameters.
163165
ValueToValueMapTy OldValMap;
164166
for (auto Z : zip_first(UniqueValues, drop_begin(NewF->args(), ArgOffset))) {
@@ -175,9 +177,16 @@ static void substituteOperandWithArgument(Function *OldF,
175177

176178
// Replace the actual operands.
177179
for (Use *Op : OpsToReplace) {
178-
Value *NewArg = OldValMap.lookup(Op->get());
180+
Argument *NewArg = cast<Argument>(OldValMap.lookup(Op->get()));
179181
auto *NewUser = cast<Instruction>(VMap.lookup(Op->getUser()));
180182

183+
// Try to preserve any information contained metadata annotations as the
184+
// equivalent parameter attributes if possible.
185+
if (auto *MDSrcInst = dyn_cast<Instruction>(Op)) {
186+
AttrBuilder AB(Ctx);
187+
NewArg->addAttrs(AB.addFromEquivalentMetadata(*MDSrcInst));
188+
}
189+
181190
if (PHINode *NewPhi = dyn_cast<PHINode>(NewUser)) {
182191
PHINode *OldPhi = cast<PHINode>(Op->getUser());
183192
BasicBlock *OldBB = OldPhi->getIncomingBlock(*Op);

0 commit comments

Comments
 (0)