Home | History | Annotate | Download | only in AArch64
      1 ; RUN: llc -mtriple=aarch64-apple-darwin                             -verify-machineinstrs < %s | FileCheck %s
      2 ; RUN: llc -mtriple=aarch64-apple-darwin -fast-isel -fast-isel-abort=1 -verify-machineinstrs < %s | FileCheck %s
      3 
      4 ; First test the different supported value types for select.
      5 define zeroext i1 @select_i1(i1 zeroext %c, i1 zeroext %a, i1 zeroext %b) {
      6 ; CHECK-LABEL: select_i1
      7 ; CHECK:       {{cmp w0, #0|tst w0, #0x1}}
      8 ; CHECK-NEXT:  csel {{w[0-9]+}}, w1, w2, ne
      9   %1 = select i1 %c, i1 %a, i1 %b
     10   ret i1 %1
     11 }
     12 
     13 define zeroext i8 @select_i8(i1 zeroext %c, i8 zeroext %a, i8 zeroext %b) {
     14 ; CHECK-LABEL: select_i8
     15 ; CHECK:       {{cmp w0, #0|tst w0, #0x1}}
     16 ; CHECK-NEXT:  csel {{w[0-9]+}}, w1, w2, ne
     17   %1 = select i1 %c, i8 %a, i8 %b
     18   ret i8 %1
     19 }
     20 
     21 define zeroext i16 @select_i16(i1 zeroext %c, i16 zeroext %a, i16 zeroext %b) {
     22 ; CHECK-LABEL: select_i16
     23 ; CHECK:       {{cmp w0, #0|tst w0, #0x1}}
     24 ; CHECK-NEXT:  csel {{w[0-9]+}}, w1, w2, ne
     25   %1 = select i1 %c, i16 %a, i16 %b
     26   ret i16 %1
     27 }
     28 
     29 define i32 @select_i32(i1 zeroext %c, i32 %a, i32 %b) {
     30 ; CHECK-LABEL: select_i32
     31 ; CHECK:       {{cmp w0, #0|tst w0, #0x1}}
     32 ; CHECK-NEXT:  csel {{w[0-9]+}}, w1, w2, ne
     33   %1 = select i1 %c, i32 %a, i32 %b
     34   ret i32 %1
     35 }
     36 
     37 define i64 @select_i64(i1 zeroext %c, i64 %a, i64 %b) {
     38 ; CHECK-LABEL: select_i64
     39 ; CHECK:       {{cmp w0, #0|tst w0, #0x1}}
     40 ; CHECK-NEXT:  csel {{x[0-9]+}}, x1, x2, ne
     41   %1 = select i1 %c, i64 %a, i64 %b
     42   ret i64 %1
     43 }
     44 
     45 define float @select_f32(i1 zeroext %c, float %a, float %b) {
     46 ; CHECK-LABEL: select_f32
     47 ; CHECK:       {{cmp w0, #0|tst w0, #0x1}}
     48 ; CHECK-NEXT:  fcsel {{s[0-9]+}}, s0, s1, ne
     49   %1 = select i1 %c, float %a, float %b
     50   ret float %1
     51 }
     52 
     53 define double @select_f64(i1 zeroext %c, double %a, double %b) {
     54 ; CHECK-LABEL: select_f64
     55 ; CHECK:       {{cmp w0, #0|tst w0, #0x1}}
     56 ; CHECK-NEXT:  fcsel {{d[0-9]+}}, d0, d1, ne
     57   %1 = select i1 %c, double %a, double %b
     58   ret double %1
     59 }
     60 
     61 ; Now test the folding of all compares.
     62 define float @select_fcmp_false(float %x, float %a, float %b) {
     63 ; CHECK-LABEL: select_fcmp_false
     64 ; CHECK:       mov.16b {{v[0-9]+}}, v2
     65   %1 = fcmp ogt float %x, %x
     66   %2 = select i1 %1, float %a, float %b
     67   ret float %2
     68 }
     69 
     70 define float @select_fcmp_ogt(float %x, float %y, float %a, float %b) {
     71 ; CHECK-LABEL: select_fcmp_ogt
     72 ; CHECK:       fcmp s0, s1
     73 ; CHECK-NEXT:  fcsel {{s[0-9]+}}, s2, s3, gt
     74   %1 = fcmp ogt float %x, %y
     75   %2 = select i1 %1, float %a, float %b
     76   ret float %2
     77 }
     78 
     79 define float @select_fcmp_oge(float %x, float %y, float %a, float %b) {
     80 ; CHECK-LABEL: select_fcmp_oge
     81 ; CHECK:       fcmp s0, s1
     82 ; CHECK-NEXT:  fcsel {{s[0-9]+}}, s2, s3, ge
     83   %1 = fcmp oge float %x, %y
     84   %2 = select i1 %1, float %a, float %b
     85   ret float %2
     86 }
     87 
     88 define float @select_fcmp_olt(float %x, float %y, float %a, float %b) {
     89 ; CHECK-LABEL: select_fcmp_olt
     90 ; CHECK:       fcmp s0, s1
     91 ; CHECK-NEXT:  fcsel {{s[0-9]+}}, s2, s3, mi
     92   %1 = fcmp olt float %x, %y
     93   %2 = select i1 %1, float %a, float %b
     94   ret float %2
     95 }
     96 
     97 define float @select_fcmp_ole(float %x, float %y, float %a, float %b) {
     98 ; CHECK-LABEL: select_fcmp_ole
     99 ; CHECK:       fcmp s0, s1
    100 ; CHECK-NEXT:  fcsel {{s[0-9]+}}, s2, s3, ls
    101   %1 = fcmp ole float %x, %y
    102   %2 = select i1 %1, float %a, float %b
    103   ret float %2
    104 }
    105 
    106 define float @select_fcmp_one(float %x, float %y, float %a, float %b) {
    107 ; CHECK-LABEL: select_fcmp_one
    108 ; CHECK:       fcmp s0, s1
    109 ; CHECK-NEXT:  fcsel [[REG:s[0-9]+]], s2, s3, mi
    110 ; CHECK-NEXT:  fcsel {{s[0-9]+}}, s2, [[REG]], gt
    111   %1 = fcmp one float %x, %y
    112   %2 = select i1 %1, float %a, float %b
    113   ret float %2
    114 }
    115 
    116 define float @select_fcmp_ord(float %x, float %y, float %a, float %b) {
    117 ; CHECK-LABEL: select_fcmp_ord
    118 ; CHECK:       fcmp s0, s1
    119 ; CHECK-NEXT:  fcsel {{s[0-9]+}}, s2, s3, vc
    120   %1 = fcmp ord float %x, %y
    121   %2 = select i1 %1, float %a, float %b
    122   ret float %2
    123 }
    124 
    125 define float @select_fcmp_uno(float %x, float %y, float %a, float %b) {
    126 ; CHECK-LABEL: select_fcmp_uno
    127 ; CHECK:       fcmp s0, s1
    128 ; CHECK-NEXT:  fcsel {{s[0-9]+}}, s2, s3, vs
    129   %1 = fcmp uno float %x, %y
    130   %2 = select i1 %1, float %a, float %b
    131   ret float %2
    132 }
    133 
    134 define float @select_fcmp_ueq(float %x, float %y, float %a, float %b) {
    135 ; CHECK-LABEL: select_fcmp_ueq
    136 ; CHECK:       fcmp s0, s1
    137 ; CHECK-NEXT:  fcsel [[REG:s[0-9]+]], s2, s3, eq
    138 ; CHECK-NEXT:  fcsel {{s[0-9]+}}, s2, [[REG]], vs
    139   %1 = fcmp ueq float %x, %y
    140   %2 = select i1 %1, float %a, float %b
    141   ret float %2
    142 }
    143 
    144 define float @select_fcmp_ugt(float %x, float %y, float %a, float %b) {
    145 ; CHECK-LABEL: select_fcmp_ugt
    146 ; CHECK:       fcmp s0, s1
    147 ; CHECK-NEXT:  fcsel {{s[0-9]+}}, s2, s3, hi
    148   %1 = fcmp ugt float %x, %y
    149   %2 = select i1 %1, float %a, float %b
    150   ret float %2
    151 }
    152 
    153 define float @select_fcmp_uge(float %x, float %y, float %a, float %b) {
    154 ; CHECK-LABEL: select_fcmp_uge
    155 ; CHECK:       fcmp s0, s1
    156 ; CHECK-NEXT:  fcsel {{s[0-9]+}}, s2, s3, pl
    157   %1 = fcmp uge float %x, %y
    158   %2 = select i1 %1, float %a, float %b
    159   ret float %2
    160 }
    161 
    162 define float @select_fcmp_ult(float %x, float %y, float %a, float %b) {
    163 ; CHECK-LABEL: select_fcmp_ult
    164 ; CHECK:       fcmp s0, s1
    165 ; CHECK-NEXT:  fcsel {{s[0-9]+}}, s2, s3, lt
    166   %1 = fcmp ult float %x, %y
    167   %2 = select i1 %1, float %a, float %b
    168   ret float %2
    169 }
    170 
    171 
    172 define float @select_fcmp_ule(float %x, float %y, float %a, float %b) {
    173 ; CHECK-LABEL: select_fcmp_ule
    174 ; CHECK:       fcmp s0, s1
    175 ; CHECK-NEXT:  fcsel {{s[0-9]+}}, s2, s3, le
    176   %1 = fcmp ule float %x, %y
    177   %2 = select i1 %1, float %a, float %b
    178   ret float %2
    179 }
    180 
    181 define float @select_fcmp_une(float %x, float %y, float %a, float %b) {
    182 ; CHECK-LABEL: select_fcmp_une
    183 ; CHECK:       fcmp s0, s1
    184 ; CHECK-NEXT:  fcsel {{s[0-9]+}}, s2, s3, ne
    185   %1 = fcmp une float %x, %y
    186   %2 = select i1 %1, float %a, float %b
    187   ret float %2
    188 }
    189 
    190 define float @select_fcmp_true(float %x, float %a, float %b) {
    191 ; CHECK-LABEL: select_fcmp_true
    192 ; CHECK:       mov.16b {{v[0-9]+}}, v1
    193   %1 = fcmp ueq float %x, %x
    194   %2 = select i1 %1, float %a, float %b
    195   ret float %2
    196 }
    197 
    198 define float @select_icmp_eq(i32 %x, i32 %y, float %a, float %b) {
    199 ; CHECK-LABEL: select_icmp_eq
    200 ; CHECK:       cmp w0, w1
    201 ; CHECK-NEXT:  fcsel {{s[0-9]+}}, s0, s1, eq
    202   %1 = icmp eq i32 %x, %y
    203   %2 = select i1 %1, float %a, float %b
    204   ret float %2
    205 }
    206 
    207 define float @select_icmp_ne(i32 %x, i32 %y, float %a, float %b) {
    208 ; CHECK-LABEL: select_icmp_ne
    209 ; CHECK:       cmp w0, w1
    210 ; CHECK-NEXT:  fcsel {{s[0-9]+}}, s0, s1, ne
    211   %1 = icmp ne i32 %x, %y
    212   %2 = select i1 %1, float %a, float %b
    213   ret float %2
    214 }
    215 
    216 define float @select_icmp_ugt(i32 %x, i32 %y, float %a, float %b) {
    217 ; CHECK-LABEL: select_icmp_ugt
    218 ; CHECK:       cmp w0, w1
    219 ; CHECK-NEXT:  fcsel {{s[0-9]+}}, s0, s1, hi
    220   %1 = icmp ugt i32 %x, %y
    221   %2 = select i1 %1, float %a, float %b
    222   ret float %2
    223 }
    224 
    225 define float @select_icmp_uge(i32 %x, i32 %y, float %a, float %b) {
    226 ; CHECK-LABEL: select_icmp_uge
    227 ; CHECK:       cmp w0, w1
    228 ; CHECK-NEXT:  fcsel {{s[0-9]+}}, s0, s1, hs
    229   %1 = icmp uge i32 %x, %y
    230   %2 = select i1 %1, float %a, float %b
    231   ret float %2
    232 }
    233 
    234 define float @select_icmp_ult(i32 %x, i32 %y, float %a, float %b) {
    235 ; CHECK-LABEL: select_icmp_ult
    236 ; CHECK:       cmp w0, w1
    237 ; CHECK-NEXT:  fcsel {{s[0-9]+}}, s0, s1, lo
    238   %1 = icmp ult i32 %x, %y
    239   %2 = select i1 %1, float %a, float %b
    240   ret float %2
    241 }
    242 
    243 define float @select_icmp_ule(i32 %x, i32 %y, float %a, float %b) {
    244 ; CHECK-LABEL: select_icmp_ule
    245 ; CHECK:       cmp w0, w1
    246 ; CHECK-NEXT:  fcsel {{s[0-9]+}}, s0, s1, ls
    247   %1 = icmp ule i32 %x, %y
    248   %2 = select i1 %1, float %a, float %b
    249   ret float %2
    250 }
    251 
    252 define float @select_icmp_sgt(i32 %x, i32 %y, float %a, float %b) {
    253 ; CHECK-LABEL: select_icmp_sgt
    254 ; CHECK:       cmp w0, w1
    255 ; CHECK-NEXT:  fcsel {{s[0-9]+}}, s0, s1, gt
    256   %1 = icmp sgt i32 %x, %y
    257   %2 = select i1 %1, float %a, float %b
    258   ret float %2
    259 }
    260 
    261 define float @select_icmp_sge(i32 %x, i32 %y, float %a, float %b) {
    262 ; CHECK-LABEL: select_icmp_sge
    263 ; CHECK:       cmp w0, w1
    264 ; CHECK-NEXT:  fcsel {{s[0-9]+}}, s0, s1, ge
    265   %1 = icmp sge i32 %x, %y
    266   %2 = select i1 %1, float %a, float %b
    267   ret float %2
    268 }
    269 
    270 define float @select_icmp_slt(i32 %x, i32 %y, float %a, float %b) {
    271 ; CHECK-LABEL: select_icmp_slt
    272 ; CHECK:       cmp w0, w1
    273 ; CHECK-NEXT:  fcsel {{s[0-9]+}}, s0, s1, lt
    274   %1 = icmp slt i32 %x, %y
    275   %2 = select i1 %1, float %a, float %b
    276   ret float %2
    277 }
    278 
    279 define float @select_icmp_sle(i32 %x, i32 %y, float %a, float %b) {
    280 ; CHECK-LABEL: select_icmp_sle
    281 ; CHECK:       cmp w0, w1
    282 ; CHECK-NEXT:  fcsel {{s[0-9]+}}, s0, s1, le
    283   %1 = icmp sle i32 %x, %y
    284   %2 = select i1 %1, float %a, float %b
    285   ret float %2
    286 }
    287 
    288 ; Test peephole optimizations for select.
    289 define zeroext i1 @select_opt1(i1 zeroext %c, i1 zeroext %a) {
    290 ; CHECK-LABEL: select_opt1
    291 ; CHECK:       orr {{w[0-9]+}}, w0, w1
    292   %1 = select i1 %c, i1 true, i1 %a
    293   ret i1 %1
    294 }
    295 
    296 define zeroext i1 @select_opt2(i1 zeroext %c, i1 zeroext %a) {
    297 ; CHECK-LABEL: select_opt2
    298 ; CHECK:       eor [[REG:w[0-9]+]], w0, #0x1
    299 ; CHECK:       orr {{w[0-9]+}}, [[REG]], w1
    300   %1 = select i1 %c, i1 %a, i1 true
    301   ret i1 %1
    302 }
    303 
    304 define zeroext i1 @select_opt3(i1 zeroext %c, i1 zeroext %a) {
    305 ; CHECK-LABEL: select_opt3
    306 ; CHECK:       bic {{w[0-9]+}}, w1, w0
    307   %1 = select i1 %c, i1 false, i1 %a
    308   ret i1 %1
    309 }
    310 
    311 define zeroext i1 @select_opt4(i1 zeroext %c, i1 zeroext %a) {
    312 ; CHECK-LABEL: select_opt4
    313 ; CHECK:       and {{w[0-9]+}}, w0, w1
    314   %1 = select i1 %c, i1 %a, i1 false
    315   ret i1 %1
    316 }
    317