Home | History | Annotate | Download | only in X86
      1 ; RUN: llc -O3 -mtriple=x86_64-apple-macosx -enable-implicit-null-checks < %s | FileCheck %s
      2 
      3 ; RUN: llc < %s -mtriple=x86_64-apple-macosx -enable-implicit-null-checks \
      4 ; RUN:    | llvm-mc -triple x86_64-apple-macosx -filetype=obj -o - \
      5 ; RUN:    | llvm-objdump -triple x86_64-apple-macosx -fault-map-section - \
      6 ; RUN:    | FileCheck %s -check-prefix OBJDUMP
      7 
      8 ; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -enable-implicit-null-checks \
      9 ; RUN:    | llvm-mc -triple x86_64-unknown-linux-gnu -filetype=obj -o - \
     10 ; RUN:    | llvm-objdump -triple x86_64-unknown-linux-gnu -fault-map-section - \
     11 ; RUN:    | FileCheck %s -check-prefix OBJDUMP
     12 
     13 define i32 @imp_null_check_load(i32* %x) {
     14 ; CHECK-LABEL: _imp_null_check_load:
     15 ; CHECK: Ltmp1:
     16 ; CHECK: movl (%rdi), %eax
     17 ; CHECK: retq
     18 ; CHECK: Ltmp0:
     19 ; CHECK: movl $42, %eax
     20 ; CHECK: retq
     21 
     22  entry:
     23   %c = icmp eq i32* %x, null
     24   br i1 %c, label %is_null, label %not_null, !make.implicit !0
     25 
     26  is_null:
     27   ret i32 42
     28 
     29  not_null:
     30   %t = load i32, i32* %x
     31   ret i32 %t
     32 }
     33 
     34 define i32 @imp_null_check_gep_load(i32* %x) {
     35 ; CHECK-LABEL: _imp_null_check_gep_load:
     36 ; CHECK: Ltmp3:
     37 ; CHECK: movl 128(%rdi), %eax
     38 ; CHECK: retq
     39 ; CHECK: Ltmp2:
     40 ; CHECK: movl $42, %eax
     41 ; CHECK: retq
     42 
     43  entry:
     44   %c = icmp eq i32* %x, null
     45   br i1 %c, label %is_null, label %not_null, !make.implicit !0
     46 
     47  is_null:
     48   ret i32 42
     49 
     50  not_null:
     51   %x.gep = getelementptr i32, i32* %x, i32 32
     52   %t = load i32, i32* %x.gep
     53   ret i32 %t
     54 }
     55 
     56 define i32 @imp_null_check_add_result(i32* %x, i32 %p) {
     57 ; CHECK-LABEL: _imp_null_check_add_result:
     58 ; CHECK: Ltmp5:
     59 ; CHECK: addl (%rdi), %esi
     60 ; CHECK: movl %esi, %eax
     61 ; CHECK: retq
     62 ; CHECK: Ltmp4:
     63 ; CHECK: movl $42, %eax
     64 ; CHECK: retq
     65 
     66  entry:
     67   %c = icmp eq i32* %x, null
     68   br i1 %c, label %is_null, label %not_null, !make.implicit !0
     69 
     70  is_null:
     71   ret i32 42
     72 
     73  not_null:
     74   %t = load i32, i32* %x
     75   %p1 = add i32 %t, %p
     76   ret i32 %p1
     77 }
     78 
     79 define i32 @imp_null_check_hoist_over_unrelated_load(i32* %x, i32* %y, i32* %z) {
     80 ; CHECK-LABEL: _imp_null_check_hoist_over_unrelated_load:
     81 ; CHECK: Ltmp7:
     82 ; CHECK: movl (%rdi), %eax
     83 ; CHECK: movl (%rsi), %ecx
     84 ; CHECK: movl %ecx, (%rdx)
     85 ; CHECK: retq
     86 ; CHECK: Ltmp6:
     87 ; CHECK: movl	$42, %eax
     88 ; CHECK: retq
     89 
     90  entry:
     91   %c = icmp eq i32* %x, null
     92   br i1 %c, label %is_null, label %not_null, !make.implicit !0
     93 
     94  is_null:
     95   ret i32 42
     96 
     97  not_null:
     98   %t0 = load i32, i32* %y
     99   %t1 = load i32, i32* %x
    100   store i32 %t0, i32* %z
    101   ret i32 %t1
    102 }
    103 
    104 define i32 @imp_null_check_via_mem_comparision(i32* %x, i32 %val) {
    105 ; CHECK-LABEL: _imp_null_check_via_mem_comparision
    106 ; CHECK: Ltmp9:
    107 ; CHECK: cmpl   %esi, 4(%rdi)
    108 ; CHECK: jge    LBB4_2
    109 ; CHECK: movl   $100, %eax
    110 ; CHECK: retq
    111 ; CHECK: Ltmp8:
    112 ; CHECK: movl   $42, %eax
    113 ; CHECK: retq
    114 ; CHECK: LBB4_2:
    115 ; CHECK: movl   $200, %eax
    116 ; CHECK: retq
    117 
    118  entry:
    119   %c = icmp eq i32* %x, null
    120   br i1 %c, label %is_null, label %not_null, !make.implicit !0
    121 
    122  is_null:
    123   ret i32 42
    124 
    125  not_null:
    126   %x.loc = getelementptr i32, i32* %x, i32 1
    127   %t = load i32, i32* %x.loc
    128   %m = icmp slt i32 %t, %val
    129   br i1 %m, label %ret_100, label %ret_200
    130 
    131  ret_100:
    132   ret i32 100
    133 
    134  ret_200:
    135   ret i32 200
    136 }
    137 
    138 !0 = !{}
    139 
    140 ; CHECK-LABEL: __LLVM_FaultMaps:
    141 
    142 ; Version:
    143 ; CHECK-NEXT: .byte 1
    144 
    145 ; Reserved x2
    146 ; CHECK-NEXT: .byte 0
    147 ; CHECK-NEXT: .short 0
    148 
    149 ; # functions:
    150 ; CHECK-NEXT: .long 5
    151 
    152 ; FunctionAddr:
    153 ; CHECK-NEXT: .quad _imp_null_check_add_result
    154 ; NumFaultingPCs
    155 ; CHECK-NEXT: .long 1
    156 ; Reserved:
    157 ; CHECK-NEXT: .long 0
    158 ; Fault[0].Type:
    159 ; CHECK-NEXT: .long 1
    160 ; Fault[0].FaultOffset:
    161 ; CHECK-NEXT: .long Ltmp5-_imp_null_check_add_result
    162 ; Fault[0].HandlerOffset:
    163 ; CHECK-NEXT: .long Ltmp4-_imp_null_check_add_result
    164 
    165 ; FunctionAddr:
    166 ; CHECK-NEXT: .quad _imp_null_check_gep_load
    167 ; NumFaultingPCs
    168 ; CHECK-NEXT: .long 1
    169 ; Reserved:
    170 ; CHECK-NEXT: .long 0
    171 ; Fault[0].Type:
    172 ; CHECK-NEXT: .long 1
    173 ; Fault[0].FaultOffset:
    174 ; CHECK-NEXT: .long Ltmp3-_imp_null_check_gep_load
    175 ; Fault[0].HandlerOffset:
    176 ; CHECK-NEXT: .long Ltmp2-_imp_null_check_gep_load
    177 
    178 ; FunctionAddr:
    179 ; CHECK-NEXT: .quad _imp_null_check_hoist_over_unrelated_load
    180 ; NumFaultingPCs
    181 ; CHECK-NEXT: .long 1
    182 ; Reserved:
    183 ; CHECK-NEXT: .long 0
    184 ; Fault[0].Type:
    185 ; CHECK-NEXT: .long 1
    186 ; Fault[0].FaultOffset:
    187 ; CHECK-NEXT: .long Ltmp7-_imp_null_check_hoist_over_unrelated_load
    188 ; Fault[0].HandlerOffset:
    189 ; CHECK-NEXT: .long Ltmp6-_imp_null_check_hoist_over_unrelated_load
    190 
    191 ; FunctionAddr:
    192 ; CHECK-NEXT: .quad _imp_null_check_load
    193 ; NumFaultingPCs
    194 ; CHECK-NEXT: .long 1
    195 ; Reserved:
    196 ; CHECK-NEXT: .long 0
    197 ; Fault[0].Type:
    198 ; CHECK-NEXT: .long 1
    199 ; Fault[0].FaultOffset:
    200 ; CHECK-NEXT: .long Ltmp1-_imp_null_check_load
    201 ; Fault[0].HandlerOffset:
    202 ; CHECK-NEXT: .long Ltmp0-_imp_null_check_load
    203 
    204 ; FunctionAddr:
    205 ; CHECK-NEXT: .quad     _imp_null_check_via_mem_comparision
    206 ; NumFaultingPCs
    207 ; CHECK-NEXT: .long   1
    208 ; Reserved:
    209 ; CHECK-NEXT: .long   0
    210 ; Fault[0].Type:
    211 ; CHECK-NEXT: .long   1
    212 ; Fault[0].FaultOffset:
    213 ; CHECK-NEXT: .long   Ltmp9-_imp_null_check_via_mem_comparision
    214 ; Fault[0].HandlerOffset:
    215 ; CHECK-NEXT: .long   Ltmp8-_imp_null_check_via_mem_comparision
    216 
    217 ; OBJDUMP: FaultMap table:
    218 ; OBJDUMP-NEXT: Version: 0x1
    219 ; OBJDUMP-NEXT: NumFunctions: 5
    220 ; OBJDUMP-NEXT: FunctionAddress: 0x000000, NumFaultingPCs: 1
    221 ; OBJDUMP-NEXT: Fault kind: FaultingLoad, faulting PC offset: 0, handling PC offset: 5
    222 ; OBJDUMP-NEXT: FunctionAddress: 0x000000, NumFaultingPCs: 1
    223 ; OBJDUMP-NEXT: Fault kind: FaultingLoad, faulting PC offset: 0, handling PC offset: 7
    224 ; OBJDUMP-NEXT: FunctionAddress: 0x000000, NumFaultingPCs: 1
    225 ; OBJDUMP-NEXT: Fault kind: FaultingLoad, faulting PC offset: 0, handling PC offset: 7
    226 ; OBJDUMP-NEXT: FunctionAddress: 0x000000, NumFaultingPCs: 1
    227 ; OBJDUMP-NEXT: Fault kind: FaultingLoad, faulting PC offset: 0, handling PC offset: 3
    228