llvm.org GIT mirror llvm / 39dd328
First part of PR12251. Add documentation and verifier support for the range metadata. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@153359 91177308-0d34-0410-b5e6-96231b3b80d8 Rafael Espindola 8 years ago
6 changed file(s) with 165 addition(s) and 1 deletion(s). Raw diff Collapse all Expand all
103103
104104
  • 'tbaa' Metadata
  • 105105
  • 'fpaccuracy' Metadata
  • 106
  • 'range' Metadata
  • 106107
    107108
    108109
    30273028
    30283029
    30293030
    3031
    3032

    3033 'range' Metadata
    3034
    3035
    3036
    3037

    range metadata may be attached only to loads of integer types. It

    3038 expresses the possible ranges the loaded value is in. The ranges are
    3039 represented with a flattened list of integers. The loaded value is known to
    3040 be in the union of the ranges defined by each consecutive pair. Each pair
    3041 has the following properties:

    3042
    3043
  • The type must match the type loaded by the instruction.
  • 3044
  • The pair a,b represents the range [a,b).
  • 3045
  • Both a and b are constants.
  • 3046
  • The range is allowed to wrap.
  • 3047
  • The range should not represent the full or empty set. That is,
  • 3048 a!=b.
    3049
    3050
    3051

    Examples:

    3052
    3053
    
                      
                    
    3054 %a = load i8* %x, align 1, !range !0 ; Can only be 0 or 1
    3055 %b = load i8* %y, align 1, !range !1 ; Can only be 255 (-1), 0 or 1
    3056 %c = load i8* %z, align 1, !range !2 ; Can only be 0, 1, 3, 4 or 5
    3057 ...
    3058 !0 = metadata !{ i8 0, i8 2 }
    3059 !1 = metadata !{ i8 255, i8 2 }
    3060 !2 = metadata !{ i8 0, i8 2, i8 3, i8 6 }
    3061
    3062
    3063
    30303064
    30313065
    30323066
    4141 MD_dbg = 0, // "dbg"
    4242 MD_tbaa = 1, // "tbaa"
    4343 MD_prof = 2, // "prof"
    44 MD_fpaccuracy = 3 // "fpaccuracy"
    44 MD_fpaccuracy = 3, // "fpaccuracy"
    45 MD_range = 4 // "range"
    4546 };
    4647
    4748 /// getMDKindID - Return a unique non-zero ID for the specified metadata kind.
    4747 unsigned FPAccuracyID = getMDKindID("fpaccuracy");
    4848 assert(FPAccuracyID == MD_fpaccuracy && "fpaccuracy kind id drifted");
    4949 (void)FPAccuracyID;
    50
    51 // Create the 'range' metadata kind.
    52 unsigned RangeID = getMDKindID("range");
    53 assert(RangeID == MD_range && "range kind id drifted");
    54 (void)RangeID;
    5055 }
    5156 LLVMContext::~LLVMContext() { delete pImpl; }
    5257
    5050 #include "llvm/DerivedTypes.h"
    5151 #include "llvm/InlineAsm.h"
    5252 #include "llvm/IntrinsicInst.h"
    53 #include "llvm/LLVMContext.h"
    5354 #include "llvm/Metadata.h"
    5455 #include "llvm/Module.h"
    5556 #include "llvm/Pass.h"
    13681369 Assert1(LI.getSynchScope() == CrossThread,
    13691370 "Non-atomic load cannot have SynchronizationScope specified", &LI);
    13701371 }
    1372
    1373 if (MDNode *Range = LI.getMetadata(LLVMContext::MD_range)) {
    1374 unsigned NumOperands = Range->getNumOperands();
    1375 Assert1(NumOperands % 2 == 0, "Unfinished range!", Range);
    1376 unsigned NumRanges = NumOperands / 2;
    1377 Assert1(NumRanges >= 1, "It should have at least one range!", Range);
    1378 for (unsigned i = 0; i < NumRanges; ++i) {
    1379 ConstantInt *Low = dyn_cast(Range->getOperand(2*i));
    1380 Assert1(Low, "The lower limit must be an integer!", Low);
    1381 ConstantInt *High = dyn_cast(Range->getOperand(2*i + 1));
    1382 Assert1(High, "The upper limit must be an integer!", High);
    1383 Assert1(High->getType() == Low->getType() &&
    1384 High->getType() == ElTy, "Range types must match load type!",
    1385 &LI);
    1386 Assert1(High->getValue() != Low->getValue(), "Range must not be empty!",
    1387 Range);
    1388 }
    1389 }
    1390
    13711391 visitInstruction(LI);
    13721392 }
    13731393
    16401660 "Cannot take the address of an inline asm!", &I);
    16411661 }
    16421662 }
    1663
    1664 MDNode *MD = I.getMetadata(LLVMContext::MD_range);
    1665 Assert1(!MD || isa(I), "Ranges are only for loads!", &I);
    1666
    16431667 InstsInThisBlock.insert(&I);
    16441668 }
    16451669
    0 ; RUN: not llvm-as < %s -o /dev/null |& FileCheck %s
    1
    2 define void @f1(i8* %x) {
    3 entry:
    4 store i8 0, i8* %x, align 1, !range !0
    5 ret void
    6 }
    7 !0 = metadata !{i8 0, i8 1}
    8 ; CHECK: Ranges are only for loads!
    9 ; CHECK-NEXT: store i8 0, i8* %x, align 1, !range !0
    10
    11 define i8 @f2(i8* %x) {
    12 entry:
    13 %y = load i8* %x, align 1, !range !1
    14 ret i8 %y
    15 }
    16 !1 = metadata !{}
    17 ; CHECK: It should have at least one range!
    18 ; CHECK-NEXT: metadata
    19
    20 define i8 @f3(i8* %x) {
    21 entry:
    22 %y = load i8* %x, align 1, !range !2
    23 ret i8 %y
    24 }
    25 !2 = metadata !{i8 0}
    26 ; CHECK: Unfinished range!
    27
    28 define i8 @f4(i8* %x) {
    29 entry:
    30 %y = load i8* %x, align 1, !range !3
    31 ret i8 %y
    32 }
    33 !3 = metadata !{double 0.0, i8 0}
    34 ; CHECK: The lower limit must be an integer!
    35
    36 define i8 @f5(i8* %x) {
    37 entry:
    38 %y = load i8* %x, align 1, !range !4
    39 ret i8 %y
    40 }
    41 !4 = metadata !{i8 0, double 0.0}
    42 ; CHECK: The upper limit must be an integer!
    43
    44 define i8 @f6(i8* %x) {
    45 entry:
    46 %y = load i8* %x, align 1, !range !5
    47 ret i8 %y
    48 }
    49 !5 = metadata !{i32 0, i8 0}
    50 ; CHECK: Range types must match load type!
    51 ; CHECK: %y = load
    52
    53 define i8 @f7(i8* %x) {
    54 entry:
    55 %y = load i8* %x, align 1, !range !6
    56 ret i8 %y
    57 }
    58 !6 = metadata !{i8 0, i32 0}
    59 ; CHECK: Range types must match load type!
    60 ; CHECK: %y = load
    61
    62 define i8 @f8(i8* %x) {
    63 entry:
    64 %y = load i8* %x, align 1, !range !7
    65 ret i8 %y
    66 }
    67 !7 = metadata !{i32 0, i32 0}
    68 ; CHECK: Range types must match load type!
    69 ; CHECK: %y = load
    70
    71 define i8 @f9(i8* %x) {
    72 entry:
    73 %y = load i8* %x, align 1, !range !8
    74 ret i8 %y
    75 }
    76 !8 = metadata !{i8 0, i8 0}
    77 ; CHECK: Range must not be empty!
    0 ; RUN: llvm-as < %s -o /dev/null
    1
    2 define i8 @f1(i8* %x) {
    3 entry:
    4 %y = load i8* %x, align 1, !range !0
    5 ret i8 %y
    6 }
    7 !0 = metadata !{i8 0, i8 1}
    8
    9 define i8 @f2(i8* %x) {
    10 entry:
    11 %y = load i8* %x, align 1, !range !1
    12 ret i8 %y
    13 }
    14 !1 = metadata !{i8 255, i8 1}
    15
    16 define i8 @f3(i8* %x) {
    17 entry:
    18 %y = load i8* %x, align 1, !range !2
    19 ret i8 %y
    20 }
    21 !2 = metadata !{i8 1, i8 3, i8 5, i8 42}