forked from OSchip/llvm-project
[Verifier] Verify scoped noalias metadata
Verify that !noalias, !alias.scope and llvm.experimental.noalias.scope arguments have the format specified in https://llvm.org/docs/LangRef.html#noalias-and-alias-scope-metadata. I've fixed up a lot of broken metadata used by tests in advance. Especially using a scope instead of the expected scope list is a commonly made mistake. Differential Revision: https://reviews.llvm.org/D110026
This commit is contained in:
parent
a89bfc6120
commit
8700f2bd36
|
@ -461,6 +461,8 @@ private:
|
|||
void visitDereferenceableMetadata(Instruction &I, MDNode *MD);
|
||||
void visitProfMetadata(Instruction &I, MDNode *MD);
|
||||
void visitAnnotationMetadata(MDNode *Annotation);
|
||||
void visitAliasScopeMetadata(const MDNode *MD);
|
||||
void visitAliasScopeListMetadata(const MDNode *MD);
|
||||
|
||||
template <class Ty> bool isValidMetadataArray(const MDTuple &N);
|
||||
#define HANDLE_SPECIALIZED_MDNODE_LEAF(CLASS) void visit##CLASS(const CLASS &N);
|
||||
|
@ -4343,6 +4345,38 @@ void Verifier::visitAnnotationMetadata(MDNode *Annotation) {
|
|||
Assert(isa<MDString>(Op.get()), "operands must be strings");
|
||||
}
|
||||
|
||||
void Verifier::visitAliasScopeMetadata(const MDNode *MD) {
|
||||
unsigned NumOps = MD->getNumOperands();
|
||||
Assert(NumOps >= 2 && NumOps <= 3, "scope must have two or three operands",
|
||||
MD);
|
||||
Assert(MD->getOperand(0) == MD || isa<MDString>(MD->getOperand(0)),
|
||||
"first scope operand must be self-referential or string", MD);
|
||||
if (NumOps == 3)
|
||||
Assert(isa<MDString>(MD->getOperand(2)),
|
||||
"third scope operand must be string (if used)", MD);
|
||||
|
||||
MDNode *Domain = dyn_cast<MDNode>(MD->getOperand(1));
|
||||
Assert(Domain != nullptr, "second scope operand must be MDNode", MD);
|
||||
|
||||
unsigned NumDomainOps = Domain->getNumOperands();
|
||||
Assert(NumDomainOps >= 1 && NumDomainOps <= 2,
|
||||
"domain must have one or two operands", Domain);
|
||||
Assert(Domain->getOperand(0) == Domain ||
|
||||
isa<MDString>(Domain->getOperand(0)),
|
||||
"first domain operand must be self-referential or string", Domain);
|
||||
if (NumDomainOps == 2)
|
||||
Assert(isa<MDString>(Domain->getOperand(1)),
|
||||
"second domain operand must be string (if used)", Domain);
|
||||
}
|
||||
|
||||
void Verifier::visitAliasScopeListMetadata(const MDNode *MD) {
|
||||
for (const MDOperand &Op : MD->operands()) {
|
||||
const MDNode *OpMD = dyn_cast<MDNode>(Op);
|
||||
Assert(OpMD != nullptr, "scope list must consist of MDNodes", MD);
|
||||
visitAliasScopeMetadata(OpMD);
|
||||
}
|
||||
}
|
||||
|
||||
/// verifyInstruction - Verify that an instruction is well formed.
|
||||
///
|
||||
void Verifier::visitInstruction(Instruction &I) {
|
||||
|
@ -4502,6 +4536,11 @@ void Verifier::visitInstruction(Instruction &I) {
|
|||
if (MDNode *TBAA = I.getMetadata(LLVMContext::MD_tbaa))
|
||||
TBAAVerifyHelper.visitTBAAMetadata(I, TBAA);
|
||||
|
||||
if (MDNode *MD = I.getMetadata(LLVMContext::MD_noalias))
|
||||
visitAliasScopeListMetadata(MD);
|
||||
if (MDNode *MD = I.getMetadata(LLVMContext::MD_alias_scope))
|
||||
visitAliasScopeListMetadata(MD);
|
||||
|
||||
if (MDNode *AlignMD = I.getMetadata(LLVMContext::MD_align)) {
|
||||
Assert(I.getType()->isPointerTy(), "align applies only to pointer types",
|
||||
&I);
|
||||
|
@ -5719,6 +5758,7 @@ void Verifier::verifyNoAliasScopeDecl() {
|
|||
II);
|
||||
Assert(ScopeListMD->getNumOperands() == 1,
|
||||
"!id.scope.list must point to a list with a single scope", II);
|
||||
visitAliasScopeListMetadata(ScopeListMD);
|
||||
}
|
||||
|
||||
// Only check the domination rule when requested. Once all passes have been
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
; RUN: not llvm-as %s -o /dev/null 2>&1 | FileCheck %s
|
||||
|
||||
define void @test(i8* %p) {
|
||||
load i8, i8* %p, !noalias !0
|
||||
load i8, i8* %p, !noalias !1
|
||||
load i8, i8* %p, !noalias !3
|
||||
load i8, i8* %p, !noalias !5
|
||||
load i8, i8* %p, !noalias !7
|
||||
load i8, i8* %p, !noalias !9
|
||||
load i8, i8* %p, !noalias !11
|
||||
load i8, i8* %p, !noalias !14
|
||||
load i8, i8* %p, !alias.scope !17
|
||||
call void @llvm.experimental.noalias.scope.decl(metadata !20)
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @llvm.experimental.noalias.scope.decl(metadata)
|
||||
|
||||
; CHECK: scope list must consist of MDNodes
|
||||
!0 = !{!"str"}
|
||||
|
||||
; CHECK: scope must have two or three operands
|
||||
!1 = !{!2}
|
||||
!2 = !{!2}
|
||||
|
||||
; CHECK: scope must have two or three operands
|
||||
!3 = !{!4}
|
||||
!4 = !{!4, !5, !6, !7}
|
||||
|
||||
; CHECK: first scope operand must be self-referential or string
|
||||
!5 = !{!6}
|
||||
!6 = !{!7, !8}
|
||||
|
||||
; CHECK: third scope operand must be string (if used)
|
||||
!7 = !{!8}
|
||||
!8 = !{!8, !9, !10}
|
||||
|
||||
; CHECK: second scope operand must be MDNode
|
||||
!9 = !{!10}
|
||||
!10 = !{!10, !"str"}
|
||||
|
||||
; CHECK: domain must have one or two operands
|
||||
!11 = !{!12}
|
||||
!12 = !{!12, !13}
|
||||
!13 = !{}
|
||||
|
||||
; CHECK: domain must have one or two operands
|
||||
!14 = !{!15}
|
||||
!15 = !{!15, !16}
|
||||
!16 = !{!17, !18, !19}
|
||||
|
||||
; CHECK: first domain operand must be self-referential or string
|
||||
!17 = !{!18}
|
||||
!18 = !{!18, !19}
|
||||
!19 = !{!20}
|
||||
|
||||
; CHECK: second domain operand must be string (if used)
|
||||
!20 = !{!21}
|
||||
!21 = !{!21, !22}
|
||||
!22 = !{!22, !23}
|
||||
!23 = !{}
|
Loading…
Reference in New Issue