Home | History | Annotate | Download | only in AArch64
      1 ; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu | FileCheck %s
      2 
      3 @var32 = global i32 0
      4 @var64 = global i64 0
      5 
      6 define void @test_csel(i32 %lhs32, i32 %rhs32, i64 %lhs64) {
      7 ; CHECK-LABEL: test_csel:
      8 
      9   %tst1 = icmp ugt i32 %lhs32, %rhs32
     10   %val1 = select i1 %tst1, i32 42, i32 52
     11   store i32 %val1, i32* @var32
     12 ; CHECK: movz [[W52:w[0-9]+]], #52
     13 ; CHECK: movz [[W42:w[0-9]+]], #42
     14 ; CHECK: csel {{w[0-9]+}}, [[W42]], [[W52]], hi
     15 
     16   %rhs64 = sext i32 %rhs32 to i64
     17   %tst2 = icmp sle i64 %lhs64, %rhs64
     18   %val2 = select i1 %tst2, i64 %lhs64, i64 %rhs64
     19   store i64 %val2, i64* @var64
     20 ; CHECK: cmp [[LHS:x[0-9]+]], [[RHS:w[0-9]+]], sxtw
     21 ; CHECK: sxtw [[EXT_RHS:x[0-9]+]], [[RHS]]
     22 ; CHECK: csel {{x[0-9]+}}, [[LHS]], [[EXT_RHS]], le
     23 
     24   ret void
     25 ; CHECK: ret
     26 }
     27 
     28 define void @test_floatcsel(float %lhs32, float %rhs32, double %lhs64, double %rhs64) {
     29 ; CHECK-LABEL: test_floatcsel:
     30 
     31   %tst1 = fcmp one float %lhs32, %rhs32
     32 ; CHECK: fcmp {{s[0-9]+}}, {{s[0-9]+}}
     33   %val1 = select i1 %tst1, i32 42, i32 52
     34   store i32 %val1, i32* @var32
     35 ; CHECK: movz [[W52:w[0-9]+]], #52
     36 ; CHECK: movz [[W42:w[0-9]+]], #42
     37 ; CHECK: csel [[MAYBETRUE:w[0-9]+]], [[W42]], [[W52]], mi
     38 ; CHECK: csel {{w[0-9]+}}, [[W42]], [[MAYBETRUE]], gt
     39 
     40 
     41   %tst2 = fcmp ueq double %lhs64, %rhs64
     42 ; CHECK: fcmp {{d[0-9]+}}, {{d[0-9]+}}
     43   %val2 = select i1 %tst2, i64 9, i64 15
     44   store i64 %val2, i64* @var64
     45 ; CHECK: movz [[CONST15:x[0-9]+]], #15
     46 ; CHECK: movz [[CONST9:x[0-9]+]], #9
     47 ; CHECK: csel [[MAYBETRUE:x[0-9]+]], [[CONST9]], [[CONST15]], eq
     48 ; CHECK: csel {{x[0-9]+}}, [[CONST9]], [[MAYBETRUE]], vs
     49 
     50   ret void
     51 ; CHECK: ret
     52 }
     53 
     54 
     55 define void @test_csinc(i32 %lhs32, i32 %rhs32, i64 %lhs64) {
     56 ; CHECK-LABEL: test_csinc:
     57 
     58 ; Note that commuting rhs and lhs in the select changes ugt to ule (i.e. hi to ls).
     59   %tst1 = icmp ugt i32 %lhs32, %rhs32
     60   %inc1 = add i32 %rhs32, 1
     61   %val1 = select i1 %tst1, i32 %inc1, i32 %lhs32
     62   store volatile i32 %val1, i32* @var32
     63 ; CHECK: cmp [[LHS:w[0-9]+]], [[RHS:w[0-9]+]]
     64 ; CHECK: csinc {{w[0-9]+}}, [[LHS]], [[RHS]], ls
     65 
     66   %rhs2 = add i32 %rhs32, 42
     67   %tst2 = icmp sle i32 %lhs32, %rhs2
     68   %inc2 = add i32 %rhs32, 1
     69   %val2 = select i1 %tst2, i32 %lhs32, i32 %inc2
     70   store volatile i32 %val2, i32* @var32
     71 ; CHECK: cmp [[LHS:w[0-9]+]], {{w[0-9]+}}
     72 ; CHECK: csinc {{w[0-9]+}}, [[LHS]], {{w[0-9]+}}, le
     73 
     74 ; Note that commuting rhs and lhs in the select changes ugt to ule (i.e. hi to ls).
     75   %rhs3 = sext i32 %rhs32 to i64
     76   %tst3 = icmp ugt i64 %lhs64, %rhs3
     77   %inc3 = add i64 %rhs3, 1
     78   %val3 = select i1 %tst3, i64 %inc3, i64 %lhs64
     79   store volatile i64 %val3, i64* @var64
     80 ; CHECK: cmp [[LHS:x[0-9]+]], {{w[0-9]+}}
     81 ; CHECK: csinc {{x[0-9]+}}, [[LHS]], {{x[0-9]+}}, ls
     82 
     83   %rhs4 = zext i32 %rhs32 to i64
     84   %tst4 = icmp sle i64 %lhs64, %rhs4
     85   %inc4 = add i64 %rhs4, 1
     86   %val4 = select i1 %tst4, i64 %lhs64, i64 %inc4
     87   store volatile i64 %val4, i64* @var64
     88 ; CHECK: cmp [[LHS:x[0-9]+]], {{w[0-9]+}}
     89 ; CHECK: csinc {{x[0-9]+}}, [[LHS]], {{x[0-9]+}}, le
     90 
     91   ret void
     92 ; CHECK: ret
     93 }
     94 
     95 define void @test_csinv(i32 %lhs32, i32 %rhs32, i64 %lhs64) {
     96 ; CHECK-LABEL: test_csinv:
     97 
     98 ; Note that commuting rhs and lhs in the select changes ugt to ule (i.e. hi to ls).
     99   %tst1 = icmp ugt i32 %lhs32, %rhs32
    100   %inc1 = xor i32 -1, %rhs32
    101   %val1 = select i1 %tst1, i32 %inc1, i32 %lhs32
    102   store volatile i32 %val1, i32* @var32
    103 ; CHECK: cmp [[LHS:w[0-9]+]], [[RHS:w[0-9]+]]
    104 ; CHECK: csinv {{w[0-9]+}}, [[LHS]], [[RHS]], ls
    105 
    106   %rhs2 = add i32 %rhs32, 42
    107   %tst2 = icmp sle i32 %lhs32, %rhs2
    108   %inc2 = xor i32 -1, %rhs32
    109   %val2 = select i1 %tst2, i32 %lhs32, i32 %inc2
    110   store volatile i32 %val2, i32* @var32
    111 ; CHECK: cmp [[LHS:w[0-9]+]], {{w[0-9]+}}
    112 ; CHECK: csinv {{w[0-9]+}}, [[LHS]], {{w[0-9]+}}, le
    113 
    114 ; Note that commuting rhs and lhs in the select changes ugt to ule (i.e. hi to ls).
    115   %rhs3 = sext i32 %rhs32 to i64
    116   %tst3 = icmp ugt i64 %lhs64, %rhs3
    117   %inc3 = xor i64 -1, %rhs3
    118   %val3 = select i1 %tst3, i64 %inc3, i64 %lhs64
    119   store volatile i64 %val3, i64* @var64
    120 ; CHECK: cmp [[LHS:x[0-9]+]], {{w[0-9]+}}
    121 ; CHECK: csinv {{x[0-9]+}}, [[LHS]], {{x[0-9]+}}, ls
    122 
    123   %rhs4 = zext i32 %rhs32 to i64
    124   %tst4 = icmp sle i64 %lhs64, %rhs4
    125   %inc4 = xor i64 -1, %rhs4
    126   %val4 = select i1 %tst4, i64 %lhs64, i64 %inc4
    127   store volatile i64 %val4, i64* @var64
    128 ; CHECK: cmp [[LHS:x[0-9]+]], {{w[0-9]+}}
    129 ; CHECK: csinv {{x[0-9]+}}, [[LHS]], {{x[0-9]+}}, le
    130 
    131   ret void
    132 ; CHECK: ret
    133 }
    134 
    135 define void @test_csneg(i32 %lhs32, i32 %rhs32, i64 %lhs64) {
    136 ; CHECK-LABEL: test_csneg:
    137 
    138 ; Note that commuting rhs and lhs in the select changes ugt to ule (i.e. hi to ls).
    139   %tst1 = icmp ugt i32 %lhs32, %rhs32
    140   %inc1 = sub i32 0, %rhs32
    141   %val1 = select i1 %tst1, i32 %inc1, i32 %lhs32
    142   store volatile i32 %val1, i32* @var32
    143 ; CHECK: cmp [[LHS:w[0-9]+]], [[RHS:w[0-9]+]]
    144 ; CHECK: csneg {{w[0-9]+}}, [[LHS]], [[RHS]], ls
    145 
    146   %rhs2 = add i32 %rhs32, 42
    147   %tst2 = icmp sle i32 %lhs32, %rhs2
    148   %inc2 = sub i32 0, %rhs32
    149   %val2 = select i1 %tst2, i32 %lhs32, i32 %inc2
    150   store volatile i32 %val2, i32* @var32
    151 ; CHECK: cmp [[LHS:w[0-9]+]], {{w[0-9]+}}
    152 ; CHECK: csneg {{w[0-9]+}}, [[LHS]], {{w[0-9]+}}, le
    153 
    154 ; Note that commuting rhs and lhs in the select changes ugt to ule (i.e. hi to ls).
    155   %rhs3 = sext i32 %rhs32 to i64
    156   %tst3 = icmp ugt i64 %lhs64, %rhs3
    157   %inc3 = sub i64 0, %rhs3
    158   %val3 = select i1 %tst3, i64 %inc3, i64 %lhs64
    159   store volatile i64 %val3, i64* @var64
    160 ; CHECK: cmp [[LHS:x[0-9]+]], {{w[0-9]+}}
    161 ; CHECK: csneg {{x[0-9]+}}, [[LHS]], {{x[0-9]+}}, ls
    162 
    163   %rhs4 = zext i32 %rhs32 to i64
    164   %tst4 = icmp sle i64 %lhs64, %rhs4
    165   %inc4 = sub i64 0, %rhs4
    166   %val4 = select i1 %tst4, i64 %lhs64, i64 %inc4
    167   store volatile i64 %val4, i64* @var64
    168 ; CHECK: cmp [[LHS:x[0-9]+]], {{w[0-9]+}}
    169 ; CHECK: csneg {{x[0-9]+}}, [[LHS]], {{x[0-9]+}}, le
    170 
    171   ret void
    172 ; CHECK: ret
    173 }
    174 
    175 define void @test_cset(i32 %lhs, i32 %rhs, i64 %lhs64) {
    176 ; CHECK-LABEL: test_cset:
    177 
    178 ; N.b. code is not optimal here (32-bit csinc would be better) but
    179 ; incoming DAG is too complex
    180   %tst1 = icmp eq i32 %lhs, %rhs
    181   %val1 = zext i1 %tst1 to i32
    182   store i32 %val1, i32* @var32
    183 ; CHECK: cmp {{w[0-9]+}}, {{w[0-9]+}}
    184 ; CHECK: csinc {{w[0-9]+}}, wzr, wzr, ne
    185 
    186   %rhs64 = sext i32 %rhs to i64
    187   %tst2 = icmp ule i64 %lhs64, %rhs64
    188   %val2 = zext i1 %tst2 to i64
    189   store i64 %val2, i64* @var64
    190 ; CHECK: csinc {{w[0-9]+}}, wzr, wzr, hi
    191 
    192   ret void
    193 ; CHECK: ret
    194 }
    195 
    196 define void @test_csetm(i32 %lhs, i32 %rhs, i64 %lhs64) {
    197 ; CHECK-LABEL: test_csetm:
    198 
    199   %tst1 = icmp eq i32 %lhs, %rhs
    200   %val1 = sext i1 %tst1 to i32
    201   store i32 %val1, i32* @var32
    202 ; CHECK: cmp {{w[0-9]+}}, {{w[0-9]+}}
    203 ; CHECK: csinv {{w[0-9]+}}, wzr, wzr, ne
    204 
    205   %rhs64 = sext i32 %rhs to i64
    206   %tst2 = icmp ule i64 %lhs64, %rhs64
    207   %val2 = sext i1 %tst2 to i64
    208   store i64 %val2, i64* @var64
    209 ; CHECK: csinv {{x[0-9]+}}, xzr, xzr, hi
    210 
    211   ret void
    212 ; CHECK: ret
    213 }
    214