Home | History | Annotate | Download | only in AArch64
      1 ; RUN: llc -O3 < %s | FileCheck %s
      2 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-n32:64"
      3 target triple = "arm64-unknown-unknown"
      4 
      5 ; CHECK-LABEL: foo1
      6 ; CHECK: cinc w{{[0-9]+}}, w{{[0-9]+}}, ne
      7 define i32 @foo1(i32 %b, i32 %c) nounwind readnone ssp {
      8 entry:
      9   %not.tobool = icmp ne i32 %c, 0
     10   %add = zext i1 %not.tobool to i32
     11   %b.add = add i32 %c, %b
     12   %add1 = add i32 %b.add, %add
     13   ret i32 %add1
     14 }
     15 
     16 ; CHECK-LABEL: foo2
     17 ; CHECK: cneg w{{[0-9]+}}, w{{[0-9]+}}, ne
     18 define i32 @foo2(i32 %b, i32 %c) nounwind readnone ssp {
     19 entry:
     20   %mul = sub i32 0, %b
     21   %tobool = icmp eq i32 %c, 0
     22   %b.mul = select i1 %tobool, i32 %b, i32 %mul
     23   %add = add nsw i32 %b.mul, %c
     24   ret i32 %add
     25 }
     26 
     27 ; CHECK-LABEL: foo3
     28 ; CHECK: cinv w{{[0-9]+}}, w{{[0-9]+}}, ne
     29 define i32 @foo3(i32 %b, i32 %c) nounwind readnone ssp {
     30 entry:
     31   %not.tobool = icmp ne i32 %c, 0
     32   %xor = sext i1 %not.tobool to i32
     33   %b.xor = xor i32 %xor, %b
     34   %add = add nsw i32 %b.xor, %c
     35   ret i32 %add
     36 }
     37 
     38 ; rdar://11632325
     39 define i32@foo4(i32 %a) nounwind ssp {
     40 ; CHECK-LABEL: foo4
     41 ; CHECK: cneg
     42 ; CHECK-NEXT: ret
     43   %cmp = icmp sgt i32 %a, -1
     44   %neg = sub nsw i32 0, %a
     45   %cond = select i1 %cmp, i32 %a, i32 %neg
     46   ret i32 %cond
     47 }
     48 
     49 define i32@foo5(i32 %a, i32 %b) nounwind ssp {
     50 entry:
     51 ; CHECK-LABEL: foo5
     52 ; CHECK: subs
     53 ; CHECK-NEXT: cneg
     54 ; CHECK-NEXT: ret
     55   %sub = sub nsw i32 %a, %b
     56   %cmp = icmp sgt i32 %sub, -1
     57   %sub3 = sub nsw i32 0, %sub
     58   %cond = select i1 %cmp, i32 %sub, i32 %sub3
     59   ret i32 %cond
     60 }
     61 
     62 ; make sure we can handle branch instruction in optimizeCompare.
     63 define i32@foo6(i32 %a, i32 %b) nounwind ssp {
     64 ; CHECK-LABEL: foo6
     65 ; CHECK: b
     66   %sub = sub nsw i32 %a, %b
     67   %cmp = icmp sgt i32 %sub, 0
     68   br i1 %cmp, label %l.if, label %l.else
     69 
     70 l.if:
     71   ret i32 1
     72 
     73 l.else:
     74   ret i32 %sub
     75 }
     76 
     77 ; If CPSR is used multiple times and V flag is used, we don't remove cmp.
     78 define i32 @foo7(i32 %a, i32 %b) nounwind {
     79 entry:
     80 ; CHECK-LABEL: foo7:
     81 ; CHECK: sub
     82 ; FIXME: Misspelled CHECK-NEXT
     83 ; CHECK-next: adds
     84 ; CHECK-next: csneg
     85 ; CHECK-next: b
     86   %sub = sub nsw i32 %a, %b
     87   %cmp = icmp sgt i32 %sub, -1
     88   %sub3 = sub nsw i32 0, %sub
     89   %cond = select i1 %cmp, i32 %sub, i32 %sub3
     90   br i1 %cmp, label %if.then, label %if.else
     91 
     92 if.then:
     93   %cmp2 = icmp slt i32 %sub, -1
     94   %sel = select i1 %cmp2, i32 %cond, i32 %a
     95   ret i32 %sel
     96 
     97 if.else:
     98   ret i32 %cond
     99 }
    100 
    101 define i32 @foo8(i32 %v, i32 %a, i32 %b) nounwind readnone ssp {
    102 entry:
    103 ; CHECK-LABEL: foo8:
    104 ; CHECK: cmp w0, #0
    105 ; CHECK: csinv w0, w1, w2, ne
    106   %tobool = icmp eq i32 %v, 0
    107   %neg = xor i32 -1, %b
    108   %cond = select i1 %tobool, i32 %neg, i32 %a
    109   ret i32 %cond
    110 }
    111 
    112 define i32 @foo9(i32 %v) nounwind readnone optsize ssp {
    113 entry:
    114 ; CHECK-LABEL: foo9:
    115 ; CHECK: cmp w0, #0
    116 ; CHECK: orr w[[REG:[0-9]+]], wzr, #0x4
    117 ; CHECK: cinv w0, w[[REG]], eq
    118   %tobool = icmp ne i32 %v, 0
    119   %cond = select i1 %tobool, i32 4, i32 -5
    120   ret i32 %cond
    121 }
    122 
    123 define i64 @foo10(i64 %v) nounwind readnone optsize ssp {
    124 entry:
    125 ; CHECK-LABEL: foo10:
    126 ; CHECK: cmp x0, #0
    127 ; CHECK: orr w[[REG:[0-9]+]], wzr, #0x4
    128 ; CHECK: cinv x0, x[[REG]], eq
    129   %tobool = icmp ne i64 %v, 0
    130   %cond = select i1 %tobool, i64 4, i64 -5
    131   ret i64 %cond
    132 }
    133 
    134 define i32 @foo11(i32 %v) nounwind readnone optsize ssp {
    135 entry:
    136 ; CHECK-LABEL: foo11:
    137 ; CHECK: cmp w0, #0
    138 ; CHECK: orr w[[REG:[0-9]+]], wzr, #0x4
    139 ; CHECK: cneg w0, w[[REG]], eq
    140   %tobool = icmp ne i32 %v, 0
    141   %cond = select i1 %tobool, i32 4, i32 -4
    142   ret i32 %cond
    143 }
    144 
    145 define i64 @foo12(i64 %v) nounwind readnone optsize ssp {
    146 entry:
    147 ; CHECK-LABEL: foo12:
    148 ; CHECK: cmp x0, #0
    149 ; CHECK: orr w[[REG:[0-9]+]], wzr, #0x4
    150 ; CHECK: cneg x0, x[[REG]], eq
    151   %tobool = icmp ne i64 %v, 0
    152   %cond = select i1 %tobool, i64 4, i64 -4
    153   ret i64 %cond
    154 }
    155 
    156 define i32 @foo13(i32 %v, i32 %a, i32 %b) nounwind readnone optsize ssp {
    157 entry:
    158 ; CHECK-LABEL: foo13:
    159 ; CHECK: cmp w0, #0
    160 ; CHECK: csneg w0, w1, w2, ne
    161   %tobool = icmp eq i32 %v, 0
    162   %sub = sub i32 0, %b
    163   %cond = select i1 %tobool, i32 %sub, i32 %a
    164   ret i32 %cond
    165 }
    166 
    167 define i64 @foo14(i64 %v, i64 %a, i64 %b) nounwind readnone optsize ssp {
    168 entry:
    169 ; CHECK-LABEL: foo14:
    170 ; CHECK: cmp x0, #0
    171 ; CHECK: csneg x0, x1, x2, ne
    172   %tobool = icmp eq i64 %v, 0
    173   %sub = sub i64 0, %b
    174   %cond = select i1 %tobool, i64 %sub, i64 %a
    175   ret i64 %cond
    176 }
    177 
    178 define i32 @foo15(i32 %a, i32 %b) nounwind readnone optsize ssp {
    179 entry:
    180 ; CHECK-LABEL: foo15:
    181 ; CHECK: cmp w0, w1
    182 ; CHECK: orr w[[REG:[0-9]+]], wzr, #0x1
    183 ; CHECK: cinc w0, w[[REG]], gt
    184   %cmp = icmp sgt i32 %a, %b
    185   %. = select i1 %cmp, i32 2, i32 1
    186   ret i32 %.
    187 }
    188 
    189 define i32 @foo16(i32 %a, i32 %b) nounwind readnone optsize ssp {
    190 entry:
    191 ; CHECK-LABEL: foo16:
    192 ; CHECK: cmp w0, w1
    193 ; CHECK: orr w[[REG:[0-9]+]], wzr, #0x1
    194 ; CHECK: cinc w0, w[[REG]], le
    195   %cmp = icmp sgt i32 %a, %b
    196   %. = select i1 %cmp, i32 1, i32 2
    197   ret i32 %.
    198 }
    199 
    200 define i64 @foo17(i64 %a, i64 %b) nounwind readnone optsize ssp {
    201 entry:
    202 ; CHECK-LABEL: foo17:
    203 ; CHECK: cmp x0, x1
    204 ; CHECK: orr w[[REG:[0-9]+]], wzr, #0x1
    205 ; CHECK: cinc x0, x[[REG]], gt
    206   %cmp = icmp sgt i64 %a, %b
    207   %. = select i1 %cmp, i64 2, i64 1
    208   ret i64 %.
    209 }
    210 
    211 define i64 @foo18(i64 %a, i64 %b) nounwind readnone optsize ssp {
    212 entry:
    213 ; CHECK-LABEL: foo18:
    214 ; CHECK: cmp x0, x1
    215 ; CHECK: orr w[[REG:[0-9]+]], wzr, #0x1
    216 ; CHECK: cinc x0, x[[REG]], le
    217   %cmp = icmp sgt i64 %a, %b
    218   %. = select i1 %cmp, i64 1, i64 2
    219   ret i64 %.
    220 }
    221 
    222 define i64 @foo19(i64 %a, i64 %b, i64 %c) {
    223 entry:
    224 ; CHECK-LABEL: foo19:
    225 ; CHECK: cinc x0, x2
    226 ; CHECK-NOT: add
    227   %cmp = icmp ult i64 %a, %b
    228   %inc = zext i1 %cmp to i64
    229   %inc.c = add i64 %inc, %c
    230   ret i64 %inc.c
    231 }
    232 
    233 define i32 @foo20(i32 %x) {
    234 ; CHECK-LABEL: foo20:
    235 ; CHECK: cmp w0, #5
    236 ; CHECK: orr w[[REG:[0-9]+]], wzr, #0x6
    237 ; CHECK: csinc w0, w[[REG]], wzr, eq
    238   %cmp = icmp eq i32 %x, 5
    239   %res = select i1 %cmp, i32 6, i32 1
    240   ret i32 %res
    241 }
    242 
    243 define i64 @foo21(i64 %x) {
    244 ; CHECK-LABEL: foo21:
    245 ; CHECK: cmp x0, #5
    246 ; CHECK: orr w[[REG:[0-9]+]], wzr, #0x6
    247 ; CHECK: csinc x0, x[[REG]], xzr, eq
    248   %cmp = icmp eq i64 %x, 5
    249   %res = select i1 %cmp, i64 6, i64 1
    250   ret i64 %res
    251 }
    252 
    253 define i32 @foo22(i32 %x) {
    254 ; CHECK-LABEL: foo22:
    255 ; CHECK: cmp w0, #5
    256 ; CHECK: orr w[[REG:[0-9]+]], wzr, #0x6
    257 ; CHECK: csinc w0, w[[REG]], wzr, ne
    258   %cmp = icmp eq i32 %x, 5
    259   %res = select i1 %cmp, i32 1, i32 6
    260   ret i32 %res
    261 }
    262 
    263 define i64 @foo23(i64 %x) {
    264 ; CHECK-LABEL: foo23:
    265 ; CHECK: cmp x0, #5
    266 ; CHECK: orr w[[REG:[0-9]+]], wzr, #0x6
    267 ; CHECK: csinc x0, x[[REG]], xzr, ne
    268   %cmp = icmp eq i64 %x, 5
    269   %res = select i1 %cmp, i64 1, i64 6
    270   ret i64 %res
    271 }
    272