Home | History | Annotate | Download | only in ARM
      1 ; RUN: llc < %s -mtriple=armv6-linux-gnueabi | FileCheck %s -check-prefix=CHECKELF
      2 ; RUN: llc < %s -mtriple=thumbv7-apple-ios5.0 | FileCheck %s -check-prefix=CHECKT2D
      3 
      4 declare i16 @identity16(i16 returned %x)
      5 declare i32 @identity32(i32 returned %x)
      6 declare zeroext i16 @retzext16(i16 returned %x)
      7 declare i16 @paramzext16(i16 zeroext returned %x)
      8 declare zeroext i16 @bothzext16(i16 zeroext returned %x)
      9 
     10 ; The zeroext param attribute below is meant to have no effect
     11 define i16 @test_identity(i16 zeroext %x) {
     12 entry:
     13 ; CHECKELF-LABEL: test_identity:
     14 ; CHECKELF: mov [[SAVEX:r[0-9]+]], r0
     15 ; CHECKELF: bl identity16
     16 ; CHECKELF: uxth r0, r0
     17 ; CHECKELF: bl identity32
     18 ; CHECKELF: mov r0, [[SAVEX]]
     19 ; CHECKT2D-LABEL: test_identity:
     20 ; CHECKT2D: mov [[SAVEX:r[0-9]+]], r0
     21 ; CHECKT2D: bl _identity16
     22 ; CHECKT2D: uxth r0, r0
     23 ; CHECKT2D: bl _identity32
     24 ; CHECKT2D: mov r0, [[SAVEX]]
     25   %call = tail call i16 @identity16(i16 %x)
     26   %b = zext i16 %call to i32
     27   %call2 = tail call i32 @identity32(i32 %b)
     28   ret i16 %x
     29 }
     30 
     31 ; FIXME: This ought not to require register saving but currently does because
     32 ; x is not considered equal to %call (see SelectionDAGBuilder.cpp)
     33 define i16 @test_matched_ret(i16 %x) {
     34 entry:
     35 ; CHECKELF-LABEL: test_matched_ret:
     36 
     37 ; This shouldn't be required
     38 ; CHECKELF: mov [[SAVEX:r[0-9]+]], r0
     39 
     40 ; CHECKELF: bl retzext16
     41 ; CHECKELF-NOT: uxth r0, {{r[0-9]+}}
     42 ; CHECKELF: bl identity32
     43 
     44 ; This shouldn't be required
     45 ; CHECKELF: mov r0, [[SAVEX]]
     46 
     47 ; CHECKT2D-LABEL: test_matched_ret:
     48 
     49 ; This shouldn't be required
     50 ; CHECKT2D: mov [[SAVEX:r[0-9]+]], r0
     51 
     52 ; CHECKT2D: bl _retzext16
     53 ; CHECKT2D-NOT: uxth r0, {{r[0-9]+}}
     54 ; CHECKT2D: bl _identity32
     55 
     56 ; This shouldn't be required
     57 ; CHECKT2D: mov r0, [[SAVEX]]
     58 
     59   %call = tail call i16 @retzext16(i16 %x)
     60   %b = zext i16 %call to i32
     61   %call2 = tail call i32 @identity32(i32 %b)
     62   ret i16 %x
     63 }
     64 
     65 define i16 @test_mismatched_ret(i16 %x) {
     66 entry:
     67 ; CHECKELF-LABEL: test_mismatched_ret:
     68 ; CHECKELF: mov [[SAVEX:r[0-9]+]], r0
     69 ; CHECKELF: bl retzext16
     70 ; CHECKELF: sxth r0, {{r[0-9]+}}
     71 ; CHECKELF: bl identity32
     72 ; CHECKELF: mov r0, [[SAVEX]]
     73 ; CHECKT2D-LABEL: test_mismatched_ret:
     74 ; CHECKT2D: mov [[SAVEX:r[0-9]+]], r0
     75 ; CHECKT2D: bl _retzext16
     76 ; CHECKT2D: sxth r0, {{r[0-9]+}}
     77 ; CHECKT2D: bl _identity32
     78 ; CHECKT2D: mov r0, [[SAVEX]]
     79   %call = tail call i16 @retzext16(i16 %x)
     80   %b = sext i16 %call to i32
     81   %call2 = tail call i32 @identity32(i32 %b)
     82   ret i16 %x
     83 }
     84 
     85 define i16 @test_matched_paramext(i16 %x) {
     86 entry:
     87 ; CHECKELF-LABEL: test_matched_paramext:
     88 ; CHECKELF: uxth r0, r0
     89 ; CHECKELF: bl paramzext16
     90 ; CHECKELF: uxth r0, r0
     91 ; CHECKELF: bl identity32
     92 ; CHECKELF: b paramzext16
     93 ; CHECKT2D-LABEL: test_matched_paramext:
     94 ; CHECKT2D: uxth r0, r0
     95 ; CHECKT2D: bl _paramzext16
     96 ; CHECKT2D: uxth r0, r0
     97 ; CHECKT2D: bl _identity32
     98 ; CHECKT2D: b.w _paramzext16
     99   %call = tail call i16 @paramzext16(i16 %x)
    100   %b = zext i16 %call to i32
    101   %call2 = tail call i32 @identity32(i32 %b)
    102   %call3 = tail call i16 @paramzext16(i16 %call)
    103   ret i16 %call3
    104 }
    105 
    106 ; FIXME: This theoretically ought to optimize to exact same output as the
    107 ; version above, but doesn't currently (see SelectionDAGBuilder.cpp) 
    108 define i16 @test_matched_paramext2(i16 %x) {
    109 entry:
    110 
    111 ; Since there doesn't seem to be an unambiguous optimal selection and
    112 ; scheduling of uxth and mov instructions below in lieu of the 'returned'
    113 ; optimization, don't bother checking: just verify that the calls are made
    114 ; in the correct order as a basic sanity check
    115 
    116 ; CHECKELF-LABEL: test_matched_paramext2:
    117 ; CHECKELF: bl paramzext16
    118 ; CHECKELF: bl identity32
    119 ; CHECKELF: b paramzext16
    120 ; CHECKT2D-LABEL: test_matched_paramext2:
    121 ; CHECKT2D: bl _paramzext16
    122 ; CHECKT2D: bl _identity32
    123 ; CHECKT2D: b.w _paramzext16
    124   %call = tail call i16 @paramzext16(i16 %x)
    125 
    126 ; Should make no difference if %x is used below rather than %call, but it does
    127   %b = zext i16 %x to i32
    128 
    129   %call2 = tail call i32 @identity32(i32 %b)
    130   %call3 = tail call i16 @paramzext16(i16 %call)
    131   ret i16 %call3
    132 }
    133 
    134 define i16 @test_matched_bothext(i16 %x) {
    135 entry:
    136 ; CHECKELF-LABEL: test_matched_bothext:
    137 ; CHECKELF: uxth r0, r0
    138 ; CHECKELF: bl bothzext16
    139 ; CHECKELF-NOT: uxth r0, r0
    140 
    141 ; FIXME: Tail call should be OK here
    142 ; CHECKELF: bl identity32
    143 
    144 ; CHECKT2D-LABEL: test_matched_bothext:
    145 ; CHECKT2D: uxth r0, r0
    146 ; CHECKT2D: bl _bothzext16
    147 ; CHECKT2D-NOT: uxth r0, r0
    148 
    149 ; FIXME: Tail call should be OK here
    150 ; CHECKT2D: bl _identity32
    151 
    152   %call = tail call i16 @bothzext16(i16 %x)
    153   %b = zext i16 %x to i32
    154   %call2 = tail call i32 @identity32(i32 %b)
    155   ret i16 %call
    156 }
    157 
    158 define i16 @test_mismatched_bothext(i16 %x) {
    159 entry:
    160 ; CHECKELF-LABEL: test_mismatched_bothext:
    161 ; CHECKELF: mov [[SAVEX:r[0-9]+]], r0
    162 ; CHECKELF: uxth r0, {{r[0-9]+}}
    163 ; CHECKELF: bl bothzext16
    164 ; CHECKELF: sxth r0, [[SAVEX]]
    165 ; CHECKELF: bl identity32
    166 ; CHECKELF: mov r0, [[SAVEX]]
    167 ; CHECKT2D-LABEL: test_mismatched_bothext:
    168 ; CHECKT2D: mov [[SAVEX:r[0-9]+]], r0
    169 ; CHECKT2D: uxth r0, {{r[0-9]+}}
    170 ; CHECKT2D: bl _bothzext16
    171 ; CHECKT2D: sxth r0, [[SAVEX]]
    172 ; CHECKT2D: bl _identity32
    173 ; CHECKT2D: mov r0, [[SAVEX]]
    174   %call = tail call i16 @bothzext16(i16 %x)
    175   %b = sext i16 %x to i32
    176   %call2 = tail call i32 @identity32(i32 %b)
    177   ret i16 %x
    178 }
    179