Home | History | Annotate | Download | only in SafepointIRVerifier
      1 ; RUN: opt -safepoint-ir-verifier-print-only -verify-safepoint-ir -S %s 2>&1 | FileCheck %s
      2 
      3 define i8 addrspace(1)* @test.not.ok.0(i8 addrspace(1)* %arg) gc "statepoint-example" {
      4 ; CHECK-LABEL: Verifying gc pointers in function: test.not.ok.0
      5  bci_0:
      6   br i1 undef, label %left, label %right
      7 
      8  left:
      9   %safepoint_token = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* undef, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
     10   br label %merge
     11 
     12  right:
     13   br label %merge
     14 
     15  merge:
     16 ; CHECK: Illegal use of unrelocated value found!
     17 ; CHECK-NEXT: Def:   %val = phi i8 addrspace(1)* [ %arg, %left ], [ %arg, %right ]
     18 ; CHECK-NEXT: Use:   ret i8 addrspace(1)* %val
     19   %val = phi i8 addrspace(1)* [ %arg, %left ], [ %arg, %right ]
     20   ret i8 addrspace(1)* %val
     21 }
     22 
     23 define i8 addrspace(1)* @test.not.ok.1(i8 addrspace(1)* %arg) gc "statepoint-example" {
     24 ; CHECK-LABEL: Verifying gc pointers in function: test.not.ok.1
     25  bci_0:
     26   br i1 undef, label %left, label %right
     27 
     28  left:
     29   %safepoint_token = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* undef, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
     30   br label %merge
     31 
     32  right:
     33   br label %merge
     34 
     35  merge:
     36 ; CHECK: Illegal use of unrelocated value found!
     37 ; CHECK-NEXT: Def:   %val = phi i8 addrspace(1)* [ %arg, %left ], [ null, %right ]
     38 ; CHECK-NEXT: Use:   ret i8 addrspace(1)* %val
     39   %val = phi i8 addrspace(1)* [ %arg, %left ], [ null, %right ]
     40   ret i8 addrspace(1)* %val
     41 }
     42 
     43 define i8 addrspace(1)* @test.ok.0(i8 addrspace(1)* %arg) gc "statepoint-example" {
     44 ; CHECK: No illegal uses found by SafepointIRVerifier in: test.ok.0
     45  bci_0:
     46   br i1 undef, label %left, label %right
     47 
     48  left:
     49   %safepoint_token = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* undef, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
     50   br label %merge
     51 
     52  right:
     53   br label %merge
     54 
     55  merge:
     56   %val = phi i8 addrspace(1)* [ null, %left ], [ null, %right]
     57   ret i8 addrspace(1)* %val
     58 }
     59 
     60 define i8 addrspace(1)* @test.ok.1(i8 addrspace(1)* %arg) gc "statepoint-example" {
     61 ; CHECK: No illegal uses found by SafepointIRVerifier in: test.ok.1
     62  bci_0:
     63   br i1 undef, label %left, label %right
     64 
     65  left:
     66   call void @not_statepoint()
     67   br label %merge
     68 
     69  right:
     70   br label %merge
     71 
     72  merge:
     73   %val = phi i8 addrspace(1)* [ %arg, %left ], [ %arg, %right]
     74   ret i8 addrspace(1)* %val
     75 }
     76 
     77 ; It should be allowed to compare poisoned ptr with null.
     78 define void @test.poisoned.cmp.ok(i8 addrspace(1)* %arg) gc "statepoint-example" {
     79 ; CHECK-LABEL: Verifying gc pointers in function: test.poisoned.cmp.ok
     80  bci_0:
     81   br i1 undef, label %left, label %right
     82 
     83  left:
     84   %safepoint_token = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* undef, i32 0, i32 0, i32 0, i32 0, i8 addrspace(1)* %arg , i32 -1, i32 0, i32 0, i32 0)
     85   %arg.relocated = call i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %safepoint_token, i32 7, i32 7) ; arg, arg
     86   br label %merge
     87 
     88  right:
     89   %safepoint_token2 = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* undef, i32 0, i32 0, i32 0, i32 0, i8 addrspace(1)* %arg , i32 -1, i32 0, i32 0, i32 0)
     90   br label %merge
     91 
     92  merge:
     93 ; CHECK: No illegal uses found by SafepointIRVerifier in: test.poisoned.cmp.ok
     94   %val.poisoned = phi i8 addrspace(1)* [ %arg.relocated, %left ], [ %arg, %right ]
     95   %c = icmp eq i8 addrspace(1)* %val.poisoned, null
     96   ret void
     97 }
     98 
     99 ; It is illegal to compare poisoned ptr and relocated.
    100 define void @test.poisoned.cmp.fail.0(i8 addrspace(1)* %arg) gc "statepoint-example" {
    101 ; CHECK-LABEL: Verifying gc pointers in function: test.poisoned.cmp.fail.0
    102  bci_0:
    103   br i1 undef, label %left, label %right
    104 
    105  left:
    106   %safepoint_token = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* undef, i32 0, i32 0, i32 0, i32 0, i8 addrspace(1)* %arg , i32 -1, i32 0, i32 0, i32 0)
    107   %arg.relocated = call i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %safepoint_token, i32 7, i32 7) ; arg, arg
    108   br label %merge
    109 
    110  right:
    111   %safepoint_token2 = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* undef, i32 0, i32 0, i32 0, i32 0, i8 addrspace(1)* %arg , i32 -1, i32 0, i32 0, i32 0)
    112   %arg.relocated2 = call i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %safepoint_token2, i32 7, i32 7) ; arg, arg
    113   br label %merge
    114 
    115  merge:
    116 ; CHECK: Illegal use of unrelocated value found!
    117 ; CHECK-NEXT: Def:   %val.poisoned = phi i8 addrspace(1)* [ %arg.relocated, %left ], [ %arg, %right ]
    118 ; CHECK-NEXT: Use:   %c = icmp eq i8 addrspace(1)* %val.poisoned, %val
    119   %val.poisoned = phi i8 addrspace(1)* [ %arg.relocated, %left ], [ %arg, %right ]
    120   %val = phi i8 addrspace(1)* [ %arg.relocated, %left ], [ %arg.relocated2, %right ]
    121   %c = icmp eq i8 addrspace(1)* %val.poisoned, %val
    122   ret void
    123 }
    124 
    125 ; It is illegal to compare poisoned ptr and unrelocated.
    126 define void @test.poisoned.cmp.fail.1(i8 addrspace(1)* %arg) gc "statepoint-example" {
    127 ; CHECK-LABEL: Verifying gc pointers in function: test.poisoned.cmp.fail.1
    128  bci_0:
    129   br i1 undef, label %left, label %right
    130 
    131  left:
    132   %safepoint_token = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* undef, i32 0, i32 0, i32 0, i32 0, i8 addrspace(1)* %arg , i32 -1, i32 0, i32 0, i32 0)
    133   %arg.relocated = call i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %safepoint_token, i32 7, i32 7) ; arg, arg
    134   br label %merge
    135 
    136  right:
    137   %safepoint_token2 = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* undef, i32 0, i32 0, i32 0, i32 0, i8 addrspace(1)* %arg , i32 -1, i32 0, i32 0, i32 0)
    138   %arg.relocated2 = call i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %safepoint_token2, i32 7, i32 7) ; arg, arg
    139   br label %merge
    140 
    141  merge:
    142 ; CHECK: Illegal use of unrelocated value found!
    143 ; CHECK-NEXT: Def:   %val.poisoned = phi i8 addrspace(1)* [ %arg.relocated, %left ], [ %arg, %right ]
    144 ; CHECK-NEXT: Use:   %c = icmp eq i8 addrspace(1)* %val.poisoned, %arg
    145   %val.poisoned = phi i8 addrspace(1)* [ %arg.relocated, %left ], [ %arg, %right ]
    146   %c = icmp eq i8 addrspace(1)* %val.poisoned, %arg
    147   ret void
    148 }
    149 
    150 ; It should be allowed to compare unrelocated phi with unrelocated value.
    151 define void @test.unrelocated-phi.cmp.ok(i8 addrspace(1)* %arg) gc "statepoint-example" {
    152 ; CHECK-LABEL: Verifying gc pointers in function: test.unrelocated-phi.cmp.ok
    153  bci_0:
    154   br i1 undef, label %left, label %right
    155 
    156  left:
    157   %safepoint_token = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* undef, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
    158   br label %merge
    159 
    160  right:
    161   br label %merge
    162 
    163  merge:
    164 ; CHECK: No illegal uses found by SafepointIRVerifier in: test.unrelocated-phi.cmp.ok
    165   %val.unrelocated = phi i8 addrspace(1)* [ %arg, %left ], [ null, %right ]
    166   %c = icmp eq i8 addrspace(1)* %val.unrelocated, %arg
    167   ret void
    168 }
    169 
    170 declare token @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...)
    171 declare i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token, i32, i32)
    172 declare void @not_statepoint()
    173