Home | History | Annotate | Download | only in ARM
      1 ; RUN: llc < %s -mtriple=armv7 -arm-tail-calls | FileCheck %s
      2 
      3 declare i16 @ret16(i16 returned)
      4 declare i32 @ret32(i32 returned)
      5 
      6 define i32 @test1(i32 %val) {
      7 ; CHECK-LABEL: test1:
      8 ; CHECK: bl {{_?}}ret16
      9   %in = trunc i32 %val to i16
     10   tail call i16 @ret16(i16 returned %in)
     11   ret i32 %val
     12 }
     13 
     14 define i16 @test2(i32 %val) {
     15 ; CHECK-LABEL: test2:
     16 ; CHECK: b {{_?}}ret16
     17   %in = trunc i32 %val to i16
     18   tail call i16 @ret16(i16 returned %in)
     19   ret i16 %in
     20 }
     21 
     22 declare {i32, i8} @take_i32_i8({i32, i8} returned)
     23 define { i8, i8 } @test_nocommon_value({i32, i32} %in) {
     24 ; CHECK-LABEL: test_nocommon_value:
     25 ; CHECK: b {{_?}}take_i32_i8
     26 
     27   %first = extractvalue {i32, i32} %in, 0
     28   %first.trunc = trunc i32 %first to i8
     29 
     30   %second = extractvalue {i32, i32} %in, 1
     31   %second.trunc = trunc i32 %second to i8
     32 
     33   %tmp = insertvalue {i32, i8} undef, i32 %first, 0
     34   %callval = insertvalue {i32, i8} %tmp, i8 %second.trunc, 1
     35   tail call {i32, i8} @take_i32_i8({i32, i8} returned %callval)
     36 
     37   %restmp = insertvalue {i8, i8} undef, i8 %first.trunc, 0
     38   %res = insertvalue {i8, i8} %restmp, i8 %second.trunc, 1
     39   ret {i8, i8} %res
     40 }
     41 
     42 declare {i32, {i32, i32}} @give_i32_i32_i32()
     43 define {{i32, i32}, i32} @test_structs_different_shape() {
     44 ; CHECK-LABEL: test_structs_different_shape:
     45 ; CHECK: b {{_?}}give_i32_i32_i32
     46   %val = tail call {i32, {i32, i32}} @give_i32_i32_i32()
     47 
     48   %first = extractvalue {i32, {i32, i32}} %val, 0
     49   %second = extractvalue {i32, {i32, i32}} %val, 1, 0
     50   %third = extractvalue {i32, {i32, i32}} %val, 1, 1
     51 
     52   %restmp = insertvalue {{i32, i32}, i32} undef, i32 %first, 0, 0
     53   %reseventmper = insertvalue {{i32, i32}, i32} %restmp, i32 %second, 0, 1
     54   %res = insertvalue {{i32, i32}, i32} %reseventmper, i32 %third, 1
     55 
     56   ret {{i32, i32}, i32} %res
     57 }
     58 
     59 define i32 @test_undef_asymmetry() {
     60 ; CHECK: test_undef_asymmetry:
     61 ; CHECK: bl {{_?}}ret32
     62 ; CHECK-NOT: jmp
     63   tail call i32 @ret32(i32 returned undef)
     64   ret i32 2
     65 }
     66 
     67 define {{}, {{}, i32, {}}, [1 x i32]} @evil_empty_aggregates() {
     68 ; CHECK-LABEL: evil_empty_aggregates:
     69 ; CHECK: b {{_?}}give_i32_i32_i32
     70   %agg = tail call {i32, {i32, i32}} @give_i32_i32_i32()
     71 
     72   %first = extractvalue {i32, {i32, i32}} %agg, 0
     73   %second = extractvalue {i32, {i32, i32}} %agg, 1, 0
     74 
     75   %restmp = insertvalue {{}, {{}, i32, {}}, [1 x i32]} undef, i32 %first, 1, 1
     76   %res = insertvalue {{}, {{}, i32, {}}, [1 x i32]} %restmp, i32 %second, 2, 0
     77   ret {{}, {{}, i32, {}}, [1 x i32]} %res
     78 }
     79 
     80 define i32 @structure_is_unimportant() {
     81 ; CHECK-LABEL: structure_is_unimportant:
     82 ; CHECK: b {{_?}}give_i32_i32_i32
     83   %val = tail call {i32, {i32, i32}} @give_i32_i32_i32()
     84 
     85   %res = extractvalue {i32, {i32, i32}} %val, 0
     86   ret i32 %res
     87 }
     88 
     89 declare i64 @give_i64()
     90 define i64 @direct_i64_ok() {
     91 ; CHECK-LABEL: direct_i64_ok:
     92 ; CHECK: b {{_?}}give_i64
     93   %val = tail call i64 @give_i64()
     94   ret i64 %val
     95 }
     96 
     97 declare {i64, i32} @give_i64_i32()
     98 define {i32, i32} @trunc_i64_not_ok() {
     99 ; CHECK-LABEL: trunc_i64_not_ok:
    100 ; CHECK: bl {{_?}}give_i64_i32
    101   %agg = tail call {i64, i32} @give_i64_i32()
    102 
    103   %first = extractvalue {i64, i32} %agg, 0
    104   %second = extractvalue {i64, i32} %agg, 1
    105   %first.trunc = trunc i64 %first to i32
    106 
    107   %tmp = insertvalue {i32, i32} undef, i32 %first.trunc, 0
    108   %ret = insertvalue {i32, i32} %tmp, i32 %second, 1
    109 
    110   ret {i32, i32} %ret
    111 }
    112