Home | History | Annotate | Download | only in ARM
      1 ; RUN: llc -mtriple=armv7k-apple-ios8.0 -mcpu=cortex-a7 -verify-machineinstrs < %s | FileCheck %s
      2 ; RUN: llc -mtriple=armv7k-apple-ios8.0 -mcpu=cortex-a7 -verify-machineinstrs < %s -O0 | FileCheck --check-prefix=CHECK-O0 %s
      3 
      4 ; RUN: llc -mtriple=armv7-apple-ios -verify-machineinstrs < %s | FileCheck %s
      5 ; RUN: llc -mtriple=armv7-apple-ios -verify-machineinstrs < %s -O0 | FileCheck --check-prefix=CHECK-O0 %s
      6 
      7 ; Test how llvm handles return type of {i16, i8}. The return value will be
      8 ; passed in %r0 and %r1.
      9 ; CHECK-LABEL: test:
     10 ; CHECK: bl {{.*}}gen
     11 ; CHECK: sxth {{.*}}, r0
     12 ; CHECK: sxtab r0, {{.*}}, r1
     13 ; CHECK-O0-LABEL: test:
     14 ; CHECK-O0: bl {{.*}}gen
     15 ; CHECK-O0: sxth r0, r0
     16 ; CHECK-O0: sxtb r1, r1
     17 ; CHECK-O0: add r0, r0, r1
     18 define i16 @test(i32 %key) {
     19 entry:
     20   %key.addr = alloca i32, align 4
     21   store i32 %key, i32* %key.addr, align 4
     22   %0 = load i32, i32* %key.addr, align 4
     23   %call = call swiftcc { i16, i8 } @gen(i32 %0)
     24   %v3 = extractvalue { i16, i8 } %call, 0
     25   %v1 = sext i16 %v3 to i32
     26   %v5 = extractvalue { i16, i8 } %call, 1
     27   %v2 = sext i8 %v5 to i32
     28   %add = add nsw i32 %v1, %v2
     29   %conv = trunc i32 %add to i16
     30   ret i16 %conv
     31 }
     32 
     33 declare swiftcc { i16, i8 } @gen(i32)
     34 
     35 ; We can't pass every return value in register, instead, pass everything in
     36 ; memroy.
     37 ; The caller provides space for the return value and passes the address in %r0.
     38 ; The first input argument will be in %r1.
     39 ; CHECK-LABEL: test2:
     40 ; CHECK: mov r1, r0
     41 ; CHECK: mov r0, sp
     42 ; CHECK: bl {{.*}}gen2
     43 ; CHECK-DAG: add
     44 ; CHECK-DAG: ldr {{.*}}, [sp, #16]
     45 ; CHECK-DAG: add
     46 ; CHECK-DAG: add
     47 ; CHECK-DAG: add
     48 ; CHECK-O0-LABEL: test2:
     49 ; CHECK-O0: str r0
     50 ; CHECK-O0: mov r0, sp
     51 ; CHECK-O0: bl {{.*}}gen2
     52 ; CHECK-O0-DAG: ldr {{.*}}, [sp]
     53 ; CHECK-O0-DAG: ldr {{.*}}, [sp, #4]
     54 ; CHECK-O0-DAG: ldr {{.*}}, [sp, #8]
     55 ; CHECK-O0-DAG: ldr {{.*}}, [sp, #12]
     56 ; CHECK-O0-DAG: ldr {{.*}}, [sp, #16]
     57 ; CHECK-O0-DAG: add
     58 ; CHECK-O0-DAG: add
     59 ; CHECK-O0-DAG: add
     60 ; CHECK-O0-DAG: add
     61 define i32 @test2(i32 %key) #0 {
     62 entry:
     63   %key.addr = alloca i32, align 4
     64   store i32 %key, i32* %key.addr, align 4
     65   %0 = load i32, i32* %key.addr, align 4
     66   %call = call swiftcc { i32, i32, i32, i32, i32 } @gen2(i32 %0)
     67 
     68   %v3 = extractvalue { i32, i32, i32, i32, i32 } %call, 0
     69   %v5 = extractvalue { i32, i32, i32, i32, i32 } %call, 1
     70   %v6 = extractvalue { i32, i32, i32, i32, i32 } %call, 2
     71   %v7 = extractvalue { i32, i32, i32, i32, i32 } %call, 3
     72   %v8 = extractvalue { i32, i32, i32, i32, i32 } %call, 4
     73 
     74   %add = add nsw i32 %v3, %v5
     75   %add1 = add nsw i32 %add, %v6
     76   %add2 = add nsw i32 %add1, %v7
     77   %add3 = add nsw i32 %add2, %v8
     78   ret i32 %add3
     79 }
     80 
     81 ; The address of the return value is passed in %r0.
     82 ; CHECK-LABEL: gen2:
     83 ; CHECK-DAG: str r1, [r0]
     84 ; CHECK-DAG: str r1, [r0, #4]
     85 ; CHECK-DAG: str r1, [r0, #8]
     86 ; CHECK-DAG: str r1, [r0, #12]
     87 ; CHECK-DAG: str r1, [r0, #16]
     88 ; CHECK-O0-LABEL: gen2:
     89 ; CHECK-O0-DAG: str r1, [r0]
     90 ; CHECK-O0-DAG: str r1, [r0, #4]
     91 ; CHECK-O0-DAG: str r1, [r0, #8]
     92 ; CHECK-O0-DAG: str r1, [r0, #12]
     93 ; CHECK-O0-DAG: str r1, [r0, #16]
     94 define swiftcc { i32, i32, i32, i32, i32 } @gen2(i32 %key) {
     95   %Y = insertvalue { i32, i32, i32, i32, i32 } undef, i32 %key, 0
     96   %Z = insertvalue { i32, i32, i32, i32, i32 } %Y, i32 %key, 1
     97   %Z2 = insertvalue { i32, i32, i32, i32, i32 } %Z, i32 %key, 2
     98   %Z3 = insertvalue { i32, i32, i32, i32, i32 } %Z2, i32 %key, 3
     99   %Z4 = insertvalue { i32, i32, i32, i32, i32 } %Z3, i32 %key, 4
    100   ret { i32, i32, i32, i32, i32 } %Z4
    101 }
    102 
    103 ; The return value {i32, i32, i32, i32} will be returned via registers %r0, %r1,
    104 ; %r2, %r3.
    105 ; CHECK-LABEL: test3:
    106 ; CHECK: bl {{.*}}gen3
    107 ; CHECK: add r0, r0, r1
    108 ; CHECK: add r0, r0, r2
    109 ; CHECK: add r0, r0, r3
    110 ; CHECK-O0-LABEL: test3:
    111 ; CHECK-O0: bl {{.*}}gen3
    112 ; CHECK-O0: add r0, r0, r1
    113 ; CHECK-O0: add r0, r0, r2
    114 ; CHECK-O0: add r0, r0, r3
    115 define i32 @test3(i32 %key) #0 {
    116 entry:
    117   %key.addr = alloca i32, align 4
    118   store i32 %key, i32* %key.addr, align 4
    119   %0 = load i32, i32* %key.addr, align 4
    120   %call = call swiftcc { i32, i32, i32, i32 } @gen3(i32 %0)
    121 
    122   %v3 = extractvalue { i32, i32, i32, i32 } %call, 0
    123   %v5 = extractvalue { i32, i32, i32, i32 } %call, 1
    124   %v6 = extractvalue { i32, i32, i32, i32 } %call, 2
    125   %v7 = extractvalue { i32, i32, i32, i32 } %call, 3
    126 
    127   %add = add nsw i32 %v3, %v5
    128   %add1 = add nsw i32 %add, %v6
    129   %add2 = add nsw i32 %add1, %v7
    130   ret i32 %add2
    131 }
    132 
    133 declare swiftcc { i32, i32, i32, i32 } @gen3(i32 %key)
    134