[llvm] r249856 - Add verification for align, dereferenceable, dereferenceable_or_null load metadata
Artur Pilipenko via llvm-commits
llvm-commits at lists.llvm.org
Fri Oct 9 10:41:29 PDT 2015
Author: apilipenko
Date: Fri Oct 9 12:41:29 2015
New Revision: 249856
URL: http://llvm.org/viewvc/llvm-project?rev=249856&view=rev
Log:
Add verification for align, dereferenceable, dereferenceable_or_null load metadata
Reviewed By: reames
Differential Revision: http://reviews.llvm.org/D13428
Added:
llvm/trunk/test/Verifier/align-md.ll
llvm/trunk/test/Verifier/dereferenceable-md.ll
Modified:
llvm/trunk/lib/IR/Verifier.cpp
Modified: llvm/trunk/lib/IR/Verifier.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Verifier.cpp?rev=249856&r1=249855&r2=249856&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Verifier.cpp (original)
+++ llvm/trunk/lib/IR/Verifier.cpp Fri Oct 9 12:41:29 2015
@@ -306,6 +306,7 @@ private:
void visitFunction(const Function &F);
void visitBasicBlock(BasicBlock &BB);
void visitRangeMetadata(Instruction& I, MDNode* Range, Type* Ty);
+ void visitDereferenceableMetadata(Instruction& I, MDNode* MD);
template <class Ty> bool isValidMetadataArray(const MDTuple &N);
#define HANDLE_SPECIALIZED_MDNODE_LEAF(CLASS) void visit##CLASS(const CLASS &N);
@@ -3072,6 +3073,19 @@ void Verifier::verifyDominatesUse(Instru
"Instruction does not dominate all uses!", Op, &I);
}
+void Verifier::visitDereferenceableMetadata(Instruction& I, MDNode* MD) {
+ Assert(I.getType()->isPointerTy(), "dereferenceable, dereferenceable_or_null "
+ "apply only to pointer types", &I);
+ Assert(isa<LoadInst>(I),
+ "dereferenceable, dereferenceable_or_null apply only to load"
+ " instructions, use attributes for calls or invokes", &I);
+ Assert(MD->getNumOperands() == 1, "dereferenceable, dereferenceable_or_null "
+ "take one operand!", &I);
+ ConstantInt *CI = mdconst::dyn_extract<ConstantInt>(MD->getOperand(0));
+ Assert(CI && CI->getType()->isIntegerTy(64), "dereferenceable, "
+ "dereferenceable_or_null metadata value must be an i64!", &I);
+}
+
/// verifyInstruction - Verify that an instruction is well formed.
///
void Verifier::visitInstruction(Instruction &I) {
@@ -3208,6 +3222,28 @@ void Verifier::visitInstruction(Instruct
&I);
}
+ if (MDNode *MD = I.getMetadata(LLVMContext::MD_dereferenceable))
+ visitDereferenceableMetadata(I, MD);
+
+ if (MDNode *MD = I.getMetadata(LLVMContext::MD_dereferenceable_or_null))
+ visitDereferenceableMetadata(I, MD);
+
+ if (MDNode *AlignMD = I.getMetadata(LLVMContext::MD_align)) {
+ Assert(I.getType()->isPointerTy(), "align applies only to pointer types",
+ &I);
+ Assert(isa<LoadInst>(I), "align applies only to load instructions, "
+ "use attributes for calls or invokes", &I);
+ Assert(AlignMD->getNumOperands() == 1, "align takes one operand!", &I);
+ ConstantInt *CI = mdconst::dyn_extract<ConstantInt>(AlignMD->getOperand(0));
+ Assert(CI && CI->getType()->isIntegerTy(64),
+ "align metadata value must be an i64!", &I);
+ uint64_t Align = CI->getZExtValue();
+ Assert(isPowerOf2_64(Align),
+ "align metadata value must be a power of 2!", &I);
+ Assert(Align <= Value::MaximumAlignment,
+ "alignment is larger that implementation defined limit", &I);
+ }
+
if (MDNode *N = I.getDebugLoc().getAsMDNode()) {
Assert(isa<DILocation>(N), "invalid !dbg metadata attachment", &I, N);
visitMDNode(*N);
Added: llvm/trunk/test/Verifier/align-md.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Verifier/align-md.ll?rev=249856&view=auto
==============================================================================
--- llvm/trunk/test/Verifier/align-md.ll (added)
+++ llvm/trunk/test/Verifier/align-md.ll Fri Oct 9 12:41:29 2015
@@ -0,0 +1,59 @@
+; RUN: not llvm-as < %s -o /dev/null 2>&1 | FileCheck %s
+
+declare i8* @foo()
+
+define void @f1() {
+entry:
+ call i8* @foo(), !align !{i64 2}
+ ret void
+}
+; CHECK: align applies only to load instructions
+; CHECK-NEXT: call i8* @foo()
+
+define i8 @f2(i8* %x) {
+entry:
+ %y = load i8, i8* %x, !align !{i64 2}
+ ret i8 %y
+}
+; CHECK: align applies only to pointer types
+; CHECK-NEXT: load i8, i8* %x
+
+define i8* @f3(i8** %x) {
+entry:
+ %y = load i8*, i8** %x, !align !{}
+ ret i8* %y
+}
+; CHECK: align takes one operand
+; CHECK-NEXT: load i8*, i8** %x
+
+define i8* @f4(i8** %x) {
+entry:
+ %y = load i8*, i8** %x, !align !{!"str"}
+ ret i8* %y
+}
+; CHECK: align metadata value must be an i64!
+; CHECK-NEXT: load i8*, i8** %x
+
+define i8* @f5(i8** %x) {
+entry:
+ %y = load i8*, i8** %x, !align !{i32 2}
+ ret i8* %y
+}
+; CHECK: align metadata value must be an i64!
+; CHECK-NEXT: load i8*, i8** %x
+
+define i8* @f6(i8** %x) {
+entry:
+ %y = load i8*, i8** %x, !align !{i64 3}
+ ret i8* %y
+}
+; CHECK: align metadata value must be a power of 2!
+; CHECK-NEXT: load i8*, i8** %x
+
+define i8* @f7(i8** %x) {
+entry:
+ %y = load i8*, i8** %x, !align !{i64 1073741824}
+ ret i8* %y
+}
+; CHECK: alignment is larger that implementation defined limit
+; CHECK-NEXT: load i8*, i8** %x
\ No newline at end of file
Added: llvm/trunk/test/Verifier/dereferenceable-md.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Verifier/dereferenceable-md.ll?rev=249856&view=auto
==============================================================================
--- llvm/trunk/test/Verifier/dereferenceable-md.ll (added)
+++ llvm/trunk/test/Verifier/dereferenceable-md.ll Fri Oct 9 12:41:29 2015
@@ -0,0 +1,86 @@
+; RUN: not llvm-as < %s -o /dev/null 2>&1 | FileCheck %s
+
+declare i8* @foo()
+
+define void @f1() {
+entry:
+ call i8* @foo(), !dereferenceable !{i64 2}
+ ret void
+}
+; CHECK: dereferenceable, dereferenceable_or_null apply only to load instructions, use attributes for calls or invokes
+; CHECK-NEXT: call i8* @foo()
+
+define void @f2() {
+entry:
+ call i8* @foo(), !dereferenceable_or_null !{i64 2}
+ ret void
+}
+; CHECK: dereferenceable, dereferenceable_or_null apply only to load instructions, use attributes for calls or invokes
+; CHECK-NEXT: call i8* @foo()
+
+define i8 @f3(i8* %x) {
+entry:
+ %y = load i8, i8* %x, !dereferenceable !{i64 2}
+ ret i8 %y
+}
+; CHECK: dereferenceable, dereferenceable_or_null apply only to pointer types
+; CHECK-NEXT: load i8, i8* %x
+
+define i8 @f4(i8* %x) {
+entry:
+ %y = load i8, i8* %x, !dereferenceable_or_null !{i64 2}
+ ret i8 %y
+}
+; CHECK: dereferenceable, dereferenceable_or_null apply only to pointer types
+; CHECK-NEXT: load i8, i8* %x
+
+define i8* @f5(i8** %x) {
+entry:
+ %y = load i8*, i8** %x, !dereferenceable !{}
+ ret i8* %y
+}
+; CHECK: dereferenceable, dereferenceable_or_null take one operand
+; CHECK-NEXT: load i8*, i8** %x
+
+
+define i8* @f6(i8** %x) {
+entry:
+ %y = load i8*, i8** %x, !dereferenceable_or_null !{}
+ ret i8* %y
+}
+; CHECK: dereferenceable, dereferenceable_or_null take one operand
+; CHECK-NEXT: load i8*, i8** %x
+
+define i8* @f7(i8** %x) {
+entry:
+ %y = load i8*, i8** %x, !dereferenceable !{!"str"}
+ ret i8* %y
+}
+; CHECK: dereferenceable, dereferenceable_or_null metadata value must be an i64!
+; CHECK-NEXT: load i8*, i8** %x
+
+
+define i8* @f8(i8** %x) {
+entry:
+ %y = load i8*, i8** %x, !dereferenceable_or_null !{!"str"}
+ ret i8* %y
+}
+; CHECK: dereferenceable, dereferenceable_or_null metadata value must be an i64!
+; CHECK-NEXT: load i8*, i8** %x
+
+define i8* @f9(i8** %x) {
+entry:
+ %y = load i8*, i8** %x, !dereferenceable !{i32 2}
+ ret i8* %y
+}
+; CHECK: dereferenceable, dereferenceable_or_null metadata value must be an i64!
+; CHECK-NEXT: load i8*, i8** %x
+
+
+define i8* @f10(i8** %x) {
+entry:
+ %y = load i8*, i8** %x, !dereferenceable_or_null !{i32 2}
+ ret i8* %y
+}
+; CHECK: dereferenceable, dereferenceable_or_null metadata value must be an i64!
+; CHECK-NEXT: load i8*, i8** %x
\ No newline at end of file
More information about the llvm-commits
mailing list