Index: docs/LangRef.rst =================================================================== --- docs/LangRef.rst +++ docs/LangRef.rst @@ -8619,7 +8619,7 @@ The number of bytes known to be dereferenceable is specified by the integer value in the metadata node. This is analogous to the ''dereferenceable'' attribute on parameters and return values. This metadata can only be applied -to loads of a pointer type. +to a pointer type. The optional ``!dereferenceable_or_null`` metadata must reference a single metadata name ```` corresponding to a metadata node with one @@ -8629,7 +8629,7 @@ The number of bytes known to be dereferenceable is specified by the integer value in the metadata node. This is analogous to the ''dereferenceable_or_null'' attribute on parameters and return values. This metadata can only be applied -to loads of a pointer type. +to a pointer type. The optional ``!align`` metadata must reference a single metadata name ```` corresponding to a metadata node with one ``i64`` entry. @@ -9626,7 +9626,7 @@ :: - = inttoptr to ; yields ty2 + = inttoptr to [, !dereferenceable !][, !dereferenceable_or_null !` type. +The optional ``!dereferenceable`` metadata must reference a single metadata +name ```` corresponding to a metadata node with one ``i64`` +entry. The existence of the ``!dereferenceable`` metadata on the instruction +tells the optimizer that the value loaded is known to be dereferenceable. +The number of bytes known to be dereferenceable is specified by the integer +value in the metadata node. This is analogous to the ''dereferenceable'' +attribute on parameters and return values. This metadata can only be applied +to a pointer type. + +The optional ``!dereferenceable_or_null`` metadata must reference a single +metadata name ```` corresponding to a metadata node with one +``i64`` entry. The existence of the ``!dereferenceable_or_null`` metadata on the +instruction tells the optimizer that the value loaded is known to be either +dereferenceable or null. +The number of bytes known to be dereferenceable is specified by the integer +value in the metadata node. This is analogous to the ''dereferenceable_or_null'' +attribute on parameters and return values. This metadata can only be applied +to a pointer type. + Semantics: """""""""" Index: lib/IR/Verifier.cpp =================================================================== --- lib/IR/Verifier.cpp +++ lib/IR/Verifier.cpp @@ -3983,9 +3983,9 @@ void Verifier::visitDereferenceableMetadata(Instruction& I, MDNode* MD) { Assert(I.getType()->isPointerTy(), "dereferenceable, dereferenceable_or_null " "apply only to pointer types", &I); - Assert(isa(I), + Assert((isa(I) || isa(I)), "dereferenceable, dereferenceable_or_null apply only to load" - " instructions, use attributes for calls or invokes", &I); + " and inttoptr 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(MD->getOperand(0)); Index: test/Verifier/dereferenceable-md-inttoptr.ll =================================================================== --- /dev/null +++ test/Verifier/dereferenceable-md-inttoptr.ll @@ -0,0 +1,6 @@ +; RUN: llvm-as < %s -o /dev/null + +define i8* @f_0(i8 %val) { + %ptr = inttoptr i8 %val to i8*, !dereferenceable_or_null !{i64 2} + ret i8* %ptr +} Index: test/Verifier/dereferenceable-md.ll =================================================================== --- test/Verifier/dereferenceable-md.ll +++ test/Verifier/dereferenceable-md.ll @@ -7,7 +7,7 @@ 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: dereferenceable, dereferenceable_or_null apply only to load and inttoptr instructions, use attributes for calls or invokes ; CHECK-NEXT: call i8* @foo() define void @f2() { @@ -15,7 +15,7 @@ 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: dereferenceable, dereferenceable_or_null apply only to load and inttoptr instructions, use attributes for calls or invokes ; CHECK-NEXT: call i8* @foo() define i8 @f3(i8* %x) { @@ -83,4 +83,46 @@ 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 +; CHECK-NEXT: load i8*, i8** %x + +define i8* @f_11(i8 %val) { + %ptr = inttoptr i8 %val to i8*, !dereferenceable !{i32 2} + ret i8* %ptr +} +; CHECK: dereferenceable, dereferenceable_or_null metadata value must be an i64! +; CHECK-NEXT: %ptr = inttoptr i8 %val to i8*, !dereferenceable !3 + +define i8* @f_12(i8 %val) { + %ptr = inttoptr i8 %val to i8*, !dereferenceable_or_null !{i32 2} + ret i8* %ptr +} +; CHECK: dereferenceable, dereferenceable_or_null metadata value must be an i64! +; CHECK-NEXT: %ptr = inttoptr i8 %val to i8*, !dereferenceable_or_null !3 + +define i8* @f_13(i8 %val) { + %ptr = inttoptr i8 %val to i8*, !dereferenceable !{} + ret i8* %ptr +} +; CHECK: dereferenceable, dereferenceable_or_null take one operand +; CHECK-NEXT: %ptr = inttoptr i8 %val to i8*, !dereferenceable !1 + +define i8* @f_14(i8 %val) { + %ptr = inttoptr i8 %val to i8*, !dereferenceable_or_null !{} + ret i8* %ptr +} +; CHECK: dereferenceable, dereferenceable_or_null take one operand +; CHECK-NEXT: %ptr = inttoptr i8 %val to i8*, !dereferenceable_or_null !1 + +define i8* @f_15(i8 %val) { + %ptr = inttoptr i8 %val to i8*, !dereferenceable !{!"str"} + ret i8* %ptr +} +; CHECK: dereferenceable, dereferenceable_or_null metadata value must be an i64! +; CHECK-NEXT: %ptr = inttoptr i8 %val to i8*, !dereferenceable !2 + +define i8* @f_16(i8 %val) { + %ptr = inttoptr i8 %val to i8*, !dereferenceable_or_null !{!"str"} + ret i8* %ptr +} +; CHECK: dereferenceable, dereferenceable_or_null metadata value must be an i64! +; CHECK-NEXT: %ptr = inttoptr i8 %val to i8*, !dereferenceable_or_null !2