Home | History | Annotate | Download | only in CodeGenPrepare
      1 ; RUN: opt -codegenprepare -S < %s | FileCheck %s
      2 
      3 target datalayout = "e-i64:64-f80:128-n8:16:32:64-S128"
      4 target triple = "x86_64-pc-linux-gnu"
      5 
      6 declare zeroext i1 @return_i1()
      7 
      8 define i32 @test_sor_basic(i32* %base) gc "statepoint-example" {
      9 ; CHECK: getelementptr i32, i32* %base, i32 15
     10 ; CHECK: getelementptr i32, i32* %base-new, i32 15
     11 entry:
     12        %ptr = getelementptr i32, i32* %base, i32 15
     13        %tok = call token (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, i32* %base, i32* %ptr)
     14        %base-new = call i32* @llvm.experimental.gc.relocate.p0i32(token %tok, i32 7, i32 7)
     15        %ptr-new = call i32* @llvm.experimental.gc.relocate.p0i32(token %tok, i32 7, i32 8)
     16        %ret = load i32, i32* %ptr-new
     17        ret i32 %ret
     18 }
     19 
     20 define i32 @test_sor_two_derived(i32* %base) gc "statepoint-example" {
     21 ; CHECK: getelementptr i32, i32* %base, i32 15
     22 ; CHECK: getelementptr i32, i32* %base, i32 12
     23 ; CHECK: getelementptr i32, i32* %base-new, i32 12
     24 ; CHECK: getelementptr i32, i32* %base-new, i32 15
     25 entry:
     26        %ptr = getelementptr i32, i32* %base, i32 15
     27        %ptr2 = getelementptr i32, i32* %base, i32 12
     28        %tok = call token (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, i32* %base, i32* %ptr, i32* %ptr2)
     29        %base-new = call i32* @llvm.experimental.gc.relocate.p0i32(token %tok, i32 7, i32 7)
     30        %ptr-new = call i32* @llvm.experimental.gc.relocate.p0i32(token %tok, i32 7, i32 8)
     31        %ptr2-new = call i32* @llvm.experimental.gc.relocate.p0i32(token %tok, i32 7, i32 9)
     32        %ret = load i32, i32* %ptr-new
     33        ret i32 %ret
     34 }
     35 
     36 define i32 @test_sor_ooo(i32* %base) gc "statepoint-example" {
     37 ; CHECK: getelementptr i32, i32* %base, i32 15
     38 ; CHECK: getelementptr i32, i32* %base-new, i32 15
     39 entry:
     40        %ptr = getelementptr i32, i32* %base, i32 15
     41        %tok = call token (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, i32* %base, i32* %ptr)
     42        %ptr-new = call i32* @llvm.experimental.gc.relocate.p0i32(token %tok, i32 7, i32 8)
     43        %base-new = call i32* @llvm.experimental.gc.relocate.p0i32(token %tok, i32 7, i32 7)
     44        %ret = load i32, i32* %ptr-new
     45        ret i32 %ret
     46 }
     47 
     48 define i32 @test_sor_gep_smallint([3 x i32]* %base) gc "statepoint-example" {
     49 ; CHECK: getelementptr [3 x i32], [3 x i32]* %base, i32 0, i32 2
     50 ; CHECK: getelementptr [3 x i32], [3 x i32]* %base-new, i32 0, i32 2
     51 entry:
     52        %ptr = getelementptr [3 x i32], [3 x i32]* %base, i32 0, i32 2
     53        %tok = call token (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, [3 x i32]* %base, i32* %ptr)
     54        %base-new = call [3 x i32]* @llvm.experimental.gc.relocate.p0a3i32(token %tok, i32 7, i32 7)
     55        %ptr-new = call i32* @llvm.experimental.gc.relocate.p0i32(token %tok, i32 7, i32 8)
     56        %ret = load i32, i32* %ptr-new
     57        ret i32 %ret
     58 }
     59 
     60 define i32 @test_sor_gep_largeint([3 x i32]* %base) gc "statepoint-example" {
     61 ; CHECK: getelementptr [3 x i32], [3 x i32]* %base, i32 0, i32 21
     62 ; CHECK-NOT: getelementptr [3 x i32], [3 x i32]* %base-new, i32 0, i32 21
     63 entry:
     64        %ptr = getelementptr [3 x i32], [3 x i32]* %base, i32 0, i32 21
     65        %tok = call token (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, [3 x i32]* %base, i32* %ptr)
     66        %base-new = call [3 x i32]* @llvm.experimental.gc.relocate.p0a3i32(token %tok, i32 7, i32 7)
     67        %ptr-new = call i32* @llvm.experimental.gc.relocate.p0i32(token %tok, i32 7, i32 8)
     68        %ret = load i32, i32* %ptr-new
     69        ret i32 %ret
     70 }
     71 
     72 define i32 @test_sor_noop(i32* %base) gc "statepoint-example" {
     73 ; CHECK: getelementptr i32, i32* %base, i32 15
     74 ; CHECK: call i32* @llvm.experimental.gc.relocate.p0i32(token %tok, i32 7, i32 8)
     75 ; CHECK: call i32* @llvm.experimental.gc.relocate.p0i32(token %tok, i32 7, i32 9)
     76 entry:
     77        %ptr = getelementptr i32, i32* %base, i32 15
     78        %ptr2 = getelementptr i32, i32* %base, i32 12
     79        %tok = call token (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, i32* %base, i32* %ptr, i32* %ptr2)
     80        %ptr-new = call i32* @llvm.experimental.gc.relocate.p0i32(token %tok, i32 7, i32 8)
     81        %ptr2-new = call i32* @llvm.experimental.gc.relocate.p0i32(token %tok, i32 7, i32 9)
     82        %ret = load i32, i32* %ptr-new
     83        ret i32 %ret
     84 }
     85 
     86 define i32 @test_sor_basic_wrong_order(i32* %base) gc "statepoint-example" {
     87 ; CHECK-LABEL: @test_sor_basic_wrong_order
     88 ; Here we have base relocate inserted after derived. Make sure that we don't
     89 ; produce uses of the relocated base pointer before it's definition.
     90 entry:
     91        %ptr = getelementptr i32, i32* %base, i32 15
     92        ; CHECK: getelementptr i32, i32* %base, i32 15
     93        %tok = call token (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, i32* %base, i32* %ptr)
     94        %ptr-new = call i32* @llvm.experimental.gc.relocate.p0i32(token %tok, i32 7, i32 8)
     95        %base-new = call i32* @llvm.experimental.gc.relocate.p0i32(token %tok, i32 7, i32 7)
     96        ; CHECK: %base-new = call i32* @llvm.experimental.gc.relocate.p0i32(token %tok, i32 7, i32 7)
     97        ; CHECK-NEXT: getelementptr i32, i32* %base-new, i32 15
     98        %ret = load i32, i32* %ptr-new
     99        ret i32 %ret
    100 }
    101 
    102 define i32 @test_sor_noop_cross_bb(i1 %external-cond, i32* %base) gc "statepoint-example" {
    103 ; CHECK-LABEL: @test_sor_noop_cross_bb
    104 ; Here base relocate doesn't dominate derived relocate. Make sure that we don't
    105 ; produce undefined use of the relocated base pointer.
    106 entry:
    107        %ptr = getelementptr i32, i32* %base, i32 15
    108        ; CHECK: getelementptr i32, i32* %base, i32 15
    109        %tok = call token (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, i32* %base, i32* %ptr)
    110        br i1 %external-cond, label %left, label %right
    111 
    112 left:
    113        %ptr-new = call i32* @llvm.experimental.gc.relocate.p0i32(token %tok, i32 7, i32 8)
    114        ; CHECK: call i32* @llvm.experimental.gc.relocate.p0i32(token %tok, i32 7, i32 8)
    115        %ret-new = load i32, i32* %ptr-new
    116        ret i32 %ret-new
    117 
    118 right:
    119        %ptr-base = call i32* @llvm.experimental.gc.relocate.p0i32(token %tok, i32 7, i32 7)
    120        ; CHECK: call i32* @llvm.experimental.gc.relocate.p0i32(token %tok, i32 7, i32 7)
    121        %ret-base = load i32, i32* %ptr-base
    122        ret i32 %ret-base
    123 }
    124 
    125 declare token @llvm.experimental.gc.statepoint.p0f_i1f(i64, i32, i1 ()*, i32, i32, ...)
    126 declare i32* @llvm.experimental.gc.relocate.p0i32(token, i32, i32)
    127 declare [3 x i32]* @llvm.experimental.gc.relocate.p0a3i32(token, i32, i32)
    128