Home | History | Annotate | Download | only in llvm2ice_tests
      1 ; This file checks that Subzero generates code in accordance with the
      2 ; calling convention for integers.
      3 
      4 ; RUN: %if --need=target_X8632 --command %p2i --filetype=obj --disassemble \
      5 ; RUN:   --target x8632 -i %s --args -O2 -allow-externally-defined-symbols \
      6 ; RUN:   | %if --need=target_X8632 --command FileCheck %s
      7 
      8 ; RUN: %if --need=target_ARM32 \
      9 ; RUN:   --command %p2i --filetype=obj \
     10 ; RUN:   --disassemble --target arm32 -i %s --args -O2 \
     11 ; RUN:   -allow-externally-defined-symbols \
     12 ; RUN:   | %if --need=target_ARM32 \
     13 ; RUN:   --command FileCheck --check-prefix ARM32 %s
     14 
     15 ; TODO: Switch to --filetype=obj when possible.
     16 ; RUN: %if --need=target_MIPS32 --need=allow_dump \
     17 ; RUN:   --command %p2i --filetype=asm --assemble \
     18 ; RUN:   --disassemble --target mips32 -i %s --args -O2 \
     19 ; RUN:   -allow-externally-defined-symbols \
     20 ; RUN:   | %if --need=target_MIPS32 --need=allow_dump \
     21 ; RUN:   --command FileCheck --check-prefix MIPS32 %s
     22 
     23 ; For x86-32, integer arguments use the stack.
     24 ; For ARM32, integer arguments can be r0-r3. i64 arguments occupy two
     25 ; adjacent 32-bit registers, and require the first to be an even register.
     26 
     27 
     28 ; i32
     29 
     30 define internal i32 @test_returning32_arg0(i32 %arg0, i32 %arg1, i32 %arg2, i32 %arg3, i32 %arg4, i32 %arg5, i32 %arg6, i32 %arg7) {
     31 entry:
     32   ret i32 %arg0
     33 }
     34 ; CHECK-LABEL: test_returning32_arg0
     35 ; CHECK-NEXT: mov eax,{{.*}} [esp+0x4]
     36 ; CHECK-NEXT: ret
     37 ; ARM32-LABEL: test_returning32_arg0
     38 ; ARM32-NEXT: bx lr
     39 ; MIPS32-LABEL: test_returning32_arg0
     40 ; MIPS32: move v0,a0
     41 ; MIPS32-NEXT: jr       ra
     42 
     43 define internal i32 @test_returning32_arg1(i32 %arg0, i32 %arg1, i32 %arg2, i32 %arg3, i32 %arg4, i32 %arg5, i32 %arg6, i32 %arg7) {
     44 entry:
     45   ret i32 %arg1
     46 }
     47 ; CHECK-LABEL: test_returning32_arg1
     48 ; CHECK-NEXT: mov eax,{{.*}} [esp+0x8]
     49 ; CHECK-NEXT: ret
     50 ; ARM32-LABEL: test_returning32_arg1
     51 ; ARM32-NEXT: mov r0, r1
     52 ; ARM32-NEXT: bx lr
     53 ; MIPS32-LABEL: test_returning32_arg1
     54 ; MIPS32: move v0,a1
     55 ; MIPS32-NEXT: jr       ra
     56 
     57 define internal i32 @test_returning32_arg2(i32 %arg0, i32 %arg1, i32 %arg2, i32 %arg3, i32 %arg4, i32 %arg5, i32 %arg6, i32 %arg7) {
     58 entry:
     59   ret i32 %arg2
     60 }
     61 ; CHECK-LABEL: test_returning32_arg2
     62 ; CHECK-NEXT: mov eax,{{.*}} [esp+0xc]
     63 ; CHECK-NEXT: ret
     64 ; ARM32-LABEL: test_returning32_arg2
     65 ; ARM32-NEXT: mov r0, r2
     66 ; ARM32-NEXT: bx lr
     67 ; MIPS32-LABEL: test_returning32_arg2
     68 ; MIPS32: move v0,a2
     69 ; MIPS32-NEXT: jr       ra
     70 
     71 
     72 define internal i32 @test_returning32_arg3(i32 %arg0, i32 %arg1, i32 %arg2, i32 %arg3, i32 %arg4, i32 %arg5, i32 %arg6, i32 %arg7) {
     73 entry:
     74   ret i32 %arg3
     75 }
     76 ; CHECK-LABEL: test_returning32_arg3
     77 ; CHECK-NEXT: mov eax,{{.*}} [esp+0x10]
     78 ; CHECK-NEXT: ret
     79 ; ARM32-LABEL: test_returning32_arg3
     80 ; ARM32-NEXT: mov r0, r3
     81 ; ARM32-NEXT: bx lr
     82 
     83 
     84 define internal i32 @test_returning32_arg4(i32 %arg0, i32 %arg1, i32 %arg2, i32 %arg3, i32 %arg4, i32 %arg5, i32 %arg6, i32 %arg7) {
     85 entry:
     86   ret i32 %arg4
     87 }
     88 ; CHECK-LABEL: test_returning32_arg4
     89 ; CHECK-NEXT: mov eax,{{.*}} [esp+0x14]
     90 ; CHECK-NEXT: ret
     91 ; ARM32-LABEL: test_returning32_arg4
     92 ; ARM32-NEXT: ldr r0, [sp]
     93 ; ARM32-NEXT: bx lr
     94 
     95 
     96 define internal i32 @test_returning32_arg5(i32 %arg0, i32 %arg1, i32 %arg2, i32 %arg3, i32 %arg4, i32 %arg5, i32 %arg6, i32 %arg7) {
     97 entry:
     98   ret i32 %arg5
     99 }
    100 ; CHECK-LABEL: test_returning32_arg5
    101 ; CHECK-NEXT: mov eax,{{.*}} [esp+0x18]
    102 ; CHECK-NEXT: ret
    103 ; ARM32-LABEL: test_returning32_arg5
    104 ; ARM32-NEXT: ldr r0, [sp, #4]
    105 ; ARM32-NEXT: bx lr
    106 
    107 ; i64
    108 
    109 define internal i64 @test_returning64_arg0(i64 %arg0, i64 %arg1, i64 %arg2, i64 %arg3) {
    110 entry:
    111   ret i64 %arg0
    112 }
    113 ; CHECK-LABEL: test_returning64_arg0
    114 ; CHECK-NEXT: mov {{.*}} [esp+0x4]
    115 ; CHECK-NEXT: mov {{.*}} [esp+0x8]
    116 ; CHECK: ret
    117 ; ARM32-LABEL: test_returning64_arg0
    118 ; ARM32-NEXT: bx lr
    119 ; MIPS32-LABEL: test_returning64_arg0
    120 ; MIPS32-NEXT: move v0,a0
    121 ; MIPS32-NEXT: move v1,a1
    122 
    123 
    124 define internal i64 @test_returning64_arg1(i64 %arg0, i64 %arg1, i64 %arg2, i64 %arg3) {
    125 entry:
    126   ret i64 %arg1
    127 }
    128 ; CHECK-LABEL: test_returning64_arg1
    129 ; CHECK-NEXT: mov {{.*}} [esp+0xc]
    130 ; CHECK-NEXT: mov {{.*}} [esp+0x10]
    131 ; CHECK: ret
    132 ; ARM32-LABEL: test_returning64_arg1
    133 ; ARM32-NEXT: mov r0, r2
    134 ; ARM32-NEXT: mov r1, r3
    135 ; ARM32-NEXT: bx lr
    136 ; MIPS32-LABEL: test_returning64_arg1
    137 ; MIPS32-NEXT: move v0,a2
    138 ; MIPS32-NEXT: move v1,a3
    139 
    140 define internal i64 @test_returning64_arg2(i64 %arg0, i64 %arg1, i64 %arg2, i64 %arg3) {
    141 entry:
    142   ret i64 %arg2
    143 }
    144 ; CHECK-LABEL: test_returning64_arg2
    145 ; CHECK-NEXT: mov {{.*}} [esp+0x14]
    146 ; CHECK-NEXT: mov {{.*}} [esp+0x18]
    147 ; CHECK: ret
    148 ; ARM32-LABEL: test_returning64_arg2
    149 ; This could have been a ldm sp, {r0, r1}, but we don't do the ldm optimization.
    150 ; ARM32-NEXT: ldr r0, [sp]
    151 ; ARM32-NEXT: ldr r1, [sp, #4]
    152 ; ARM32-NEXT: bx lr
    153 
    154 define internal i64 @test_returning64_arg3(i64 %arg0, i64 %arg1, i64 %arg2, i64 %arg3) {
    155 entry:
    156   ret i64 %arg3
    157 }
    158 ; CHECK-LABEL: test_returning64_arg3
    159 ; CHECK-NEXT: mov {{.*}} [esp+0x1c]
    160 ; CHECK-NEXT: mov {{.*}} [esp+0x20]
    161 ; CHECK: ret
    162 ; ARM32-LABEL: test_returning64_arg3
    163 ; ARM32-NEXT: ldr r0, [sp, #8]
    164 ; ARM32-NEXT: ldr r1, [sp, #12]
    165 ; ARM32-NEXT: bx lr
    166 
    167 
    168 ; Test that on ARM, the i64 arguments start with an even register.
    169 
    170 define internal i64 @test_returning64_even_arg1(i32 %arg0, i64 %arg1, i64 %arg2) {
    171 entry:
    172   ret i64 %arg1
    173 }
    174 ; Not padded out x86-32.
    175 ; CHECK-LABEL: test_returning64_even_arg1
    176 ; CHECK-NEXT: mov {{.*}} [esp+0x8]
    177 ; CHECK-NEXT: mov {{.*}} [esp+0xc]
    178 ; CHECK: ret
    179 ; ARM32-LABEL: test_returning64_even_arg1
    180 ; ARM32-NEXT: mov r0, r2
    181 ; ARM32-NEXT: mov r1, r3
    182 ; ARM32-NEXT: bx lr
    183 
    184 define internal i64 @test_returning64_even_arg1b(i32 %arg0, i32 %arg0b, i64 %arg1, i64 %arg2) {
    185 entry:
    186   ret i64 %arg1
    187 }
    188 ; CHECK-LABEL: test_returning64_even_arg1b
    189 ; CHECK-NEXT: mov {{.*}} [esp+0xc]
    190 ; CHECK-NEXT: mov {{.*}} [esp+0x10]
    191 ; CHECK: ret
    192 ; ARM32-LABEL: test_returning64_even_arg1b
    193 ; ARM32-NEXT: mov r0, r2
    194 ; ARM32-NEXT: mov r1, r3
    195 ; ARM32-NEXT: bx lr
    196 
    197 define internal i64 @test_returning64_even_arg2(i64 %arg0, i32 %arg1, i64 %arg2) {
    198 entry:
    199   ret i64 %arg2
    200 }
    201 ; Not padded out on x86-32.
    202 ; CHECK-LABEL: test_returning64_even_arg2
    203 ; CHECK-NEXT: mov {{.*}} [esp+0x10]
    204 ; CHECK-NEXT: mov {{.*}} [esp+0x14]
    205 ; CHECK: ret
    206 ; ARM32-LABEL: test_returning64_even_arg2
    207 ; ARM32-DAG: ldr r0, [sp]
    208 ; ARM32-DAG: ldr r1, [sp, #4]
    209 ; ARM32-NEXT: bx lr
    210 
    211 define internal i64 @test_returning64_even_arg2b(i64 %arg0, i32 %arg1, i32 %arg1b, i64 %arg2) {
    212 entry:
    213   ret i64 %arg2
    214 }
    215 ; CHECK-LABEL: test_returning64_even_arg2b
    216 ; CHECK-NEXT: mov {{.*}} [esp+0x14]
    217 ; CHECK-NEXT: mov {{.*}} [esp+0x18]
    218 ; CHECK: ret
    219 ; ARM32-LABEL: test_returning64_even_arg2b
    220 ; ARM32-NEXT: ldr r0, [sp]
    221 ; ARM32-NEXT: ldr r1, [sp, #4]
    222 ; ARM32-NEXT: bx lr
    223 
    224 define internal i32 @test_returning32_even_arg2(i64 %arg0, i32 %arg1, i32 %arg2) {
    225 entry:
    226   ret i32 %arg2
    227 }
    228 ; CHECK-LABEL: test_returning32_even_arg2
    229 ; CHECK-NEXT: mov {{.*}} [esp+0x10]
    230 ; CHECK-NEXT: ret
    231 ; ARM32-LABEL: test_returning32_even_arg2
    232 ; ARM32-NEXT: mov r0, r3
    233 ; ARM32-NEXT: bx lr
    234 
    235 define internal i32 @test_returning32_even_arg2b(i32 %arg0, i32 %arg1, i32 %arg2, i64 %arg3) {
    236 entry:
    237   ret i32 %arg2
    238 }
    239 ; CHECK-LABEL: test_returning32_even_arg2b
    240 ; CHECK-NEXT: mov {{.*}} [esp+0xc]
    241 ; CHECK-NEXT: ret
    242 ; ARM32-LABEL: test_returning32_even_arg2b
    243 ; ARM32-NEXT: mov r0, r2
    244 ; ARM32-NEXT: bx lr
    245 
    246 ; The i64 won't fit in a pair of register, and consumes the last register so a
    247 ; following i32 can't use that free register.
    248 define internal i32 @test_returning32_even_arg4(i32 %arg0, i32 %arg1, i32 %arg2, i64 %arg3, i32 %arg4) {
    249 entry:
    250   ret i32 %arg4
    251 }
    252 ; CHECK-LABEL: test_returning32_even_arg4
    253 ; CHECK-NEXT: mov {{.*}} [esp+0x18]
    254 ; CHECK-NEXT: ret
    255 ; ARM32-LABEL: test_returning32_even_arg4
    256 ; ARM32-NEXT: ldr r0, [sp, #8]
    257 ; ARM32-NEXT: bx lr
    258 
    259 ; Test interleaving float/double and integer (different register streams on ARM).
    260 ; TODO(jvoung): Test once the S/D/Q regs are modeled.
    261 
    262 ; Test that integers are passed correctly as arguments to a function.
    263 
    264 declare void @IntArgs(i32, i32, i32, i32, i32, i32)
    265 
    266 declare void @killRegisters()
    267 
    268 define internal void @test_passing_integers(i32 %arg0, i32 %arg1, i32 %arg2, i32 %arg3, i32 %arg4, i32 %arg5, i32 %arg6) {
    269   call void @killRegisters()
    270   call void @IntArgs(i32 %arg6, i32 %arg5, i32 %arg4, i32 %arg3, i32 %arg2, i32 %arg1)
    271   ret void
    272 }
    273 
    274 ; CHECK-LABEL: test_passing_integers
    275 ; CHECK-DAG: mov [[REG1:e.*]],DWORD PTR [esp+0x44]
    276 ; CHECK-DAG: mov [[REG2:e.*]],DWORD PTR [esp+0x48]
    277 ; CHECK-DAG: mov [[REG3:e.*]],DWORD PTR [esp+0x4c]
    278 ; CHECK-DAG: mov [[REG4:e.*]],DWORD PTR [esp+0x50]
    279 ; CHECK: mov DWORD PTR [esp]
    280 ; CHECK: mov DWORD PTR [esp+0x4]
    281 ; CHECK-DAG: mov DWORD PTR [esp+0x8],[[REG4]]
    282 ; CHECK-DAG: mov DWORD PTR [esp+0xc],[[REG3]]
    283 ; CHECK-DAG: mov DWORD PTR [esp+0x10],[[REG2]]
    284 ; CHECK-DAG: mov DWORD PTR [esp+0x14],[[REG1]]
    285 ; CHECK: call
    286 
    287 ; ARM32-LABEL: test_passing_integers
    288 ; ARM32-DAG: mov [[REG1:.*]], r1
    289 ; ARM32-DAG: mov [[REG2:.*]], r2
    290 ; ARM32-DAG: mov [[REG3:.*]], r3
    291 ; ARM32: str [[REG2]], [sp]
    292 ; ARM32: str [[REG1]], [sp, #4]
    293 ; ARM32-DAG: mov r0
    294 ; ARM32-DAG: mov r1
    295 ; ARM32-DAG: mov r2
    296 ; ARM32-DAG: mov r3, [[REG3]]
    297 ; ARM32: bl
    298