Skip to content

Commit c31c0ec

Browse files
Ralendermemfrob
authored andcommitted
[AssumeBundles] Enforce constraints on the operand bundle of llvm.assume
Summary: Add verification that operand bundles on an llvm.assume are well formed to the verify pass. Reviewers: jdoerfert Reviewed By: jdoerfert Subscribers: hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D75269
1 parent 4642e68 commit c31c0ec

File tree

6 files changed

+58
-19
lines changed

6 files changed

+58
-19
lines changed

llvm/include/llvm/IR/Attributes.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,10 @@ class Attribute {
116116
/// Return true if and only if the attribute has an Argument.
117117
static bool doesAttrKindHaveArgument(Attribute::AttrKind AttrKind);
118118

119+
/// Return true if the provided string matches the IR name of an attribute.
120+
/// example: "noalias" return true but not "NoAlias"
121+
static bool isExistingAttribute(StringRef Name);
122+
119123
//===--------------------------------------------------------------------===//
120124
// Attribute Accessors
121125
//===--------------------------------------------------------------------===//

llvm/lib/IR/Attributes.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,14 @@ bool Attribute::doesAttrKindHaveArgument(Attribute::AttrKind AttrKind) {
208208
AttrKind == Attribute::DereferenceableOrNull;
209209
}
210210

211+
bool Attribute::isExistingAttribute(StringRef Name) {
212+
return StringSwitch<bool>(Name)
213+
#define GET_ATTR_NAMES
214+
#define ATTRIBUTE_ALL(ENUM_NAME, DISPLAY_NAME) .Case(#DISPLAY_NAME, true)
215+
#include "llvm/IR/Attributes.inc"
216+
.Default(false);
217+
}
218+
211219
//===----------------------------------------------------------------------===//
212220
// Attribute Accessor Methods
213221
//===----------------------------------------------------------------------===//

llvm/lib/IR/KnowledgeRetention.cpp

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -183,25 +183,14 @@ static Value *getValueFromBundleOpInfo(IntrinsicInst &Assume,
183183
return (Assume.op_begin() + BOI.Begin + Idx)->get();
184184
}
185185

186-
#ifndef NDEBUG
187-
188-
static bool isExistingAttribute(StringRef Name) {
189-
return StringSwitch<bool>(Name)
190-
#define GET_ATTR_NAMES
191-
#define ATTRIBUTE_ALL(ENUM_NAME, DISPLAY_NAME) .Case(#DISPLAY_NAME, true)
192-
#include "llvm/IR/Attributes.inc"
193-
.Default(false);
194-
}
195-
196-
#endif
197-
198186
bool llvm::hasAttributeInAssume(CallInst &AssumeCI, Value *IsOn,
199187
StringRef AttrName, uint64_t *ArgVal,
200188
AssumeQuery AQR) {
201189
IntrinsicInst &Assume = cast<IntrinsicInst>(AssumeCI);
202190
assert(Assume.getIntrinsicID() == Intrinsic::assume &&
203191
"this function is intended to be used on llvm.assume");
204-
assert(isExistingAttribute(AttrName) && "this attribute doesn't exist");
192+
assert(Attribute::isExistingAttribute(AttrName) &&
193+
"this attribute doesn't exist");
205194
assert((ArgVal == nullptr || Attribute::doesAttrKindHaveArgument(
206195
Attribute::getAttrKindFromName(AttrName))) &&
207196
"requested value for an attribute that has no argument");
@@ -218,16 +207,12 @@ bool llvm::hasAttributeInAssume(CallInst &AssumeCI, Value *IsOn,
218207
Lookup =
219208
llvm::lower_bound(Assume.bundle_op_infos(), AttrName,
220209
[](const CallBase::BundleOpInfo &BOI, StringRef RHS) {
221-
assert(isExistingAttribute(BOI.Tag->getKey()) &&
222-
"this attribute doesn't exist");
223210
return BOI.Tag->getKey() < RHS;
224211
});
225212
else
226213
Lookup = std::prev(
227214
llvm::upper_bound(Assume.bundle_op_infos(), AttrName,
228215
[](StringRef LHS, const CallBase::BundleOpInfo &BOI) {
229-
assert(isExistingAttribute(BOI.Tag->getKey()) &&
230-
"this attribute doesn't exist");
231216
return LHS < BOI.Tag->getKey();
232217
}));
233218

llvm/lib/IR/Verifier.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4320,6 +4320,29 @@ void Verifier::visitIntrinsicCall(Intrinsic::ID ID, CallBase &Call) {
43204320
switch (ID) {
43214321
default:
43224322
break;
4323+
case Intrinsic::assume: {
4324+
for (auto &Elem : Call.bundle_op_infos()) {
4325+
Assert(Attribute::isExistingAttribute(Elem.Tag->getKey()),
4326+
"tags must be valid attribute names");
4327+
Assert(Elem.End - Elem.Begin <= 2, "to many arguments");
4328+
Attribute::AttrKind Kind =
4329+
Attribute::getAttrKindFromName(Elem.Tag->getKey());
4330+
if (Kind == Attribute::None)
4331+
break;
4332+
if (Attribute::doesAttrKindHaveArgument(Kind)) {
4333+
Assert(Elem.End - Elem.Begin == 2,
4334+
"this attribute should have 2 arguments");
4335+
Assert(isa<ConstantInt>(Call.getOperand(Elem.Begin + 1)),
4336+
"the second argument should be a constant integral value");
4337+
} else if (isFuncOnlyAttr(Kind)) {
4338+
Assert((Elem.End - Elem.Begin) == 0, "this attribute has no argument");
4339+
} else if (!isFuncOrArgAttr(Kind)) {
4340+
Assert((Elem.End - Elem.Begin) == 1,
4341+
"this attribute should have one argument");
4342+
}
4343+
}
4344+
break;
4345+
}
43234346
case Intrinsic::coro_id: {
43244347
auto *InfoArg = Call.getArgOperand(3)->stripPointerCasts();
43254348
if (isa<ConstantPointerNull>(InfoArg))

llvm/test/IR/assume-builder.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2-
; RUN: opt -passes='assume-builder' -S %s | FileCheck %s --check-prefixes=BASIC
3-
; RUN: opt -passes='assume-builder' --assume-preserve-all -S %s | FileCheck %s --check-prefixes=ALL
2+
; RUN: opt -passes='assume-builder,verify' -S %s | FileCheck %s --check-prefixes=BASIC
3+
; RUN: opt -passes='assume-builder,verify' --assume-preserve-all -S %s | FileCheck %s --check-prefixes=ALL
44

55
declare void @func(i32*, i32*)
66
declare void @func_cold(i32*) cold

llvm/test/Verifier/assume-bundles.ll

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
; RUN: not opt -verify < %s 2>&1 | FileCheck %s
2+
3+
declare void @llvm.assume(i1)
4+
5+
define void @func(i32* %P, i32 %P1, i32* %P2, i32* %P3) {
6+
; CHECK: tags must be valid attribute names
7+
call void @llvm.assume(i1 true) ["adazdazd"()]
8+
; CHECK: the second argument should be a constant integral value
9+
call void @llvm.assume(i1 true) ["align"(i32* %P, i32 %P1)]
10+
; CHECK: to many arguments
11+
call void @llvm.assume(i1 true) ["align"(i32* %P, i32 8, i32 8)]
12+
; CHECK: this attribute should have 2 arguments
13+
call void @llvm.assume(i1 true) ["align"(i32* %P)]
14+
; CHECK: this attribute has no argument
15+
call void @llvm.assume(i1 true) ["align"(i32* %P, i32 4), "cold"(i32* %P)]
16+
; CHECK: this attribute should have one argument
17+
call void @llvm.assume(i1 true) ["noalias"()]
18+
ret void
19+
}

0 commit comments

Comments
 (0)