Home | History | Annotate | Download | only in llvm2ice_tests
      1 ; Test of multiple indirect calls to the same target.  Each call
      2 ; should be to the same operand, whether it's in a register or on the
      3 ; stack.
      4 
      5 ; RUN: %if --need=target_X8632 --command %p2i --filetype=obj --disassemble \
      6 ; RUN:   --target x8632 -i %s --args -O2 \
      7 ; RUN:   | %if --need=target_X8632 --command FileCheck %s
      8 ; RUN: %if --need=allow_dump --need=target_X8632 --command %p2i --filetype=asm \
      9 ; RUN:     --assemble --disassemble -i %s --args -O2 \
     10 ; RUN:   | %if --need=allow_dump --need=target_X8632 --command FileCheck %s
     11 ; RUN: %if --need=target_X8632 --command %p2i --filetype=obj --disassemble \
     12 ; RUN:   --target x8632 -i %s --args -Om1 \
     13 ; RUN:   | %if --need=target_X8632 --command FileCheck --check-prefix=OPTM1 %s
     14 
     15 ; RUN: %if --need=target_X8664 --command %p2i --filetype=obj --disassemble \
     16 ; RUN:   --target x8664 -i %s --args -O2 \
     17 ; RUN:   | %if --need=target_X8664 --command FileCheck --check-prefix X8664 %s
     18 ; RUN: %if --need=allow_dump --need=target_X8664 --command %p2i --filetype=asm \
     19 ; RUN:     --assemble --disassemble --target x8664 -i %s --args -O2 \
     20 ; RUN:   | %if --need=allow_dump --need=target_X8664 \
     21 ; RUN:     --command FileCheck --check-prefix=X8664 %s
     22 ; RUN: %if --need=target_X8664 --command %p2i --filetype=obj --disassemble \
     23 ; RUN:   --target x8664 -i %s --args -Om1 \
     24 ; RUN:   | %if --need=target_X8664 \
     25 ; RUN:     --command FileCheck --check-prefix=X8664-OPTM1 %s
     26 
     27 ; RUN: %if --need=target_ARM32 \
     28 ; RUN:   --command %p2i --filetype=obj \
     29 ; RUN:   --disassemble --target arm32 -i %s --args -O2 \
     30 ; RUN:   | %if --need=target_ARM32 \
     31 ; RUN:   --command FileCheck --check-prefix ARM32 %s
     32 ; RUN: %if --need=target_ARM32 \
     33 ; RUN:   --command %p2i --filetype=obj \
     34 ; RUN:   --disassemble --target arm32 -i %s --args -Om1 \
     35 ; RUN:   | %if --need=target_ARM32_dump \
     36 ; RUN:   --command FileCheck --check-prefix ARM32 %s
     37 
     38 ; RUN: %if --need=target_MIPS32 --need=allow_dump \
     39 ; RUN:   --command %p2i --filetype=asm --assemble --disassemble --target \
     40 ; RUN:   mips32 -i %s --args -O2 -allow-externally-defined-symbols \
     41 ; RUN:   | %if --need=target_MIPS32 --need=allow_dump \
     42 ; RUN:   --command FileCheck --check-prefix MIPS32 %s
     43 
     44 @__init_array_start = internal constant [0 x i8] zeroinitializer, align 4
     45 @__fini_array_start = internal constant [0 x i8] zeroinitializer, align 4
     46 @__tls_template_start = internal constant [0 x i8] zeroinitializer, align 8
     47 @__tls_template_alignment = internal constant [4 x i8] c"\01\00\00\00", align 4
     48 
     49 define internal void @CallIndirect(i32 %f) {
     50 entry:
     51   %__1 = inttoptr i32 %f to void ()*
     52   call void %__1()
     53   call void %__1()
     54   call void %__1()
     55   call void %__1()
     56   call void %__1()
     57   call void %__1()
     58   ret void
     59 }
     60 ; CHECK-LABEL: CallIndirect
     61 ; Use the first call as a barrier in case the register allocator decides to use
     62 ; a scratch register for it but a common preserved register for the rest.
     63 ; CHECK: call
     64 ; CHECK: call [[REGISTER:[a-z]+]]
     65 ; CHECK: call [[REGISTER]]
     66 ; CHECK: call [[REGISTER]]
     67 ; CHECK: call [[REGISTER]]
     68 ; CHECK: call [[REGISTER]]
     69 ;
     70 ; OPTM1-LABEL: CallIndirect
     71 ; OPTM1: call [[TARGET:.+]]
     72 ; OPTM1: call [[TARGET]]
     73 ; OPTM1: call [[TARGET]]
     74 ; OPTM1: call [[TARGET]]
     75 ; OPTM1: call [[TARGET]]
     76 ;
     77 ; X8664-LABEL: CallIndirect
     78 ; Use the first call as a barrier so we skip the movs in the function prolog.
     79 ; X8664: call r{{..}}
     80 ; X8664: mov e[[REG:..]],
     81 ; X8664-NEXT: call r[[REG]]
     82 ; X8664: mov e[[REG:..]],
     83 ; X8664-NEXT: call r[[REG]]
     84 ; X8664: mov e[[REG:..]],
     85 ; X8664-NEXT: call r[[REG]]
     86 ; X8664: call r{{..}}
     87 ;
     88 ; X8664-OPTM1-LABEL: CallIndirect
     89 ; X8664-OPTM1: mov e[[REG:..]],DWORD PTR
     90 ; X8664-OPTM1: call r[[REG]]
     91 ; X8664-OPTM1: mov e[[REG:..]],DWORD PTR
     92 ; X8664-OPTM1: call r[[REG]]
     93 ; X8664-OPTM1: mov e[[REG:..]],DWORD PTR
     94 ; X8664-OPTM1: call r[[REG]]
     95 ; X8664-OPTM1: mov e[[REG:..]],DWORD PTR
     96 ; X8664-OPTM1: call r[[REG]]
     97 ; X8664-OPTM1: mov e[[REG:..]],DWORD PTR
     98 ; X8664-OPTM1: call r[[REG]]
     99 ;
    100 ; ARM32-LABEL: CallIndirect
    101 ; ARM32: blx [[REGISTER:r.*]]
    102 ; ARM32: blx [[REGISTER]]
    103 ; ARM32: blx [[REGISTER]]
    104 ; ARM32: blx [[REGISTER]]
    105 ; ARM32: blx [[REGISTER]]
    106 
    107 ; MIPS32-LABEL: CallIndirect
    108 ; MIPS32: jalr	[[REGISTER:.*]]
    109 ; MIPS32: jalr	[[REGISTER]]
    110 ; MIPS32: jalr	[[REGISTER]]
    111 ; MIPS32: jalr	[[REGISTER]]
    112 
    113 @fp_v = internal global [4 x i8] zeroinitializer, align 4
    114 
    115 define internal void @CallIndirectGlobal() {
    116 entry:
    117   %fp_ptr_i32 = bitcast [4 x i8]* @fp_v to i32*
    118   %fp_ptr = load i32, i32* %fp_ptr_i32, align 1
    119   %fp = inttoptr i32 %fp_ptr to void ()*
    120   call void %fp()
    121   call void %fp()
    122   call void %fp()
    123   call void %fp()
    124   ret void
    125 }
    126 ; CHECK-LABEL: CallIndirectGlobal
    127 ; Allow the first call to be to a different register because of simple
    128 ; availability optimization.
    129 ; CHECK: call
    130 ; CHECK: call [[REGISTER:[a-z]+]]
    131 ; CHECK: call [[REGISTER]]
    132 ; CHECK: call [[REGISTER]]
    133 ;
    134 ; OPTM1-LABEL: CallIndirectGlobal
    135 ; OPTM1: call [[TARGET:.+]]
    136 ; OPTM1: call [[TARGET]]
    137 ; OPTM1: call [[TARGET]]
    138 ; OPTM1: call [[TARGET]]
    139 ;
    140 ; X8664-LABEL: CallIndirectGlobal
    141 ; X8664: call r[[REG]]
    142 ; X8664: mov e[[REG:..]]
    143 ; X8664-NEXT: call r[[REG]]
    144 ; X8664: mov e[[REG:..]]
    145 ; X8664-NEXT: call r[[REG]]
    146 ; X8664: call r{{..}}
    147 ;
    148 ; X8664-OPTM1-LABEL: CallIndirectGlobal
    149 ; X8664-OPTM1: mov e[[REG:..]],DWORD PTR
    150 ; X8664-OPTM1: call r[[REG]]
    151 ; X8664-OPTM1: mov e[[REG:..]],DWORD PTR
    152 ; X8664-OPTM1: call r[[REG]]
    153 ; X8664-OPTM1: mov e[[REG:..]],DWORD PTR
    154 ; X8664-OPTM1: call r[[REG]]
    155 ; X8664-OPTM1: mov e[[REG:..]],DWORD PTR
    156 ; X8664-OPTM1: call r[[REG]]
    157 ;
    158 ; ARM32-LABEL: CallIndirectGlobal
    159 ; ARM32: blx {{r.*}}
    160 ; ARM32: blx [[REGISTER:r[0-9]*]]
    161 ; ARM32: blx [[REGISTER]]
    162 ; ARM32: blx [[REGISTER]]
    163 
    164 ; MIPS32-LABEL: CallIndirectGlobal
    165 ; MIPS32: jalr	[[REGISTER:.*]]
    166 ; MIPS32: jalr	[[REGISTER]]
    167 ; MIPS32: jalr	[[REGISTER]]
    168 ; MIPS32: jalr	[[REGISTER]]
    169 
    170 ; Calling an absolute address is used for non-IRT PNaCl pexes to directly
    171 ; access syscall trampolines. This is not really an indirect call, but
    172 ; there is a cast from int to pointer first.
    173 define internal void @CallConst() {
    174 entry:
    175   %__1 = inttoptr i32 66496 to void ()*
    176   call void %__1()
    177   call void %__1()
    178   call void %__1()
    179   ret void
    180 }
    181 
    182 ; CHECK-LABEL: CallConst
    183 ; CHECK: e8 bc 03 01 00 call {{[0-9a-f]+}} {{.*}} R_386_PC32 *ABS*
    184 ; CHECK: e8 bc 03 01 00 call {{[0-9a-f]+}} {{.*}} R_386_PC32 *ABS*
    185 ; CHECK: e8 bc 03 01 00 call {{[0-9a-f]+}} {{.*}} R_386_PC32 *ABS*
    186 ;
    187 ; OPTM1-LABEL: CallConst
    188 ; OPTM1: e8 bc 03 01 00 call {{[0-9a-f]+}} {{.*}} R_386_PC32 *ABS*
    189 ; OPTM1: e8 bc 03 01 00 call {{[0-9a-f]+}} {{.*}} R_386_PC32 *ABS*
    190 ; OPTM1: e8 bc 03 01 00 call {{[0-9a-f]+}} {{.*}} R_386_PC32 *ABS*
    191 ;
    192 ; X8664-LABEL: CallConst
    193 ; TODO(jpp): fix absolute call emission.
    194 ; These are broken: the emitted code should be
    195 ;    e8 00 00 00 00 call {{.*}} *ABS*+0x103bc
    196 ;
    197 ; X8664-OPTM1-LABEL: CallConst
    198 ; TODO(jpp): fix absolute call emission.
    199 ; These are broken: the emitted code should be
    200 ;    e8 00 00 00 00 call {{.*}} *ABS*+0x103bc
    201 ;
    202 ; ARM32-LABEL: CallConst
    203 ; ARM32: movw [[REGISTER:r.*]], #960
    204 ; ARM32: movt [[REGISTER]], #1
    205 ; ARM32: blx [[REGISTER]]
    206 ; The legalization of the constant could be shared, but it isn't.
    207 ; ARM32: movw [[REGISTER:r.*]], #960
    208 ; ARM32: blx [[REGISTER]]
    209 ; ARM32: blx [[REGISTER]]
    210