Home | History | Annotate | Download | only in Lanai
      1 ; RUN: llc < %s -mtriple=lanai | FileCheck %s
      2 
      3 define i32 @f(i32 inreg %a, i32 inreg %b) nounwind ssp {
      4 entry:
      5 ; CHECK-LABEL: f:
      6 ; CHECK: sub.f %r6, %r7, [[IN:%.*]]
      7 ; CHECK: sel.gt [[IN]], %r0, %rv
      8   %cmp = icmp sgt i32 %a, %b
      9   %sub = sub nsw i32 %a, %b
     10   %sub. = select i1 %cmp, i32 %sub, i32 0
     11   ret i32 %sub.
     12 }
     13 
     14 define i32 @g(i32 inreg %a, i32 inreg %b) nounwind ssp {
     15 entry:
     16 ; CHECK-LABEL: g:
     17 ; CHECK: sub.f %r7, %r6, [[IN:%.*]]
     18 ; CHECK: sel.lt [[IN]], %r0, %rv
     19   %cmp = icmp slt i32 %a, %b
     20   %sub = sub nsw i32 %b, %a
     21   %sub. = select i1 %cmp, i32 %sub, i32 0
     22   ret i32 %sub.
     23 }
     24 
     25 define i32 @h(i32 inreg %a, i32 inreg %b) nounwind ssp {
     26 entry:
     27 ; CHECK-LABEL: h:
     28 ; CHECK: sub.f %r6, 0x3, [[IN:%.*]]
     29 ; CHECK: sel.gt [[IN]], %r7, %rv
     30   %cmp = icmp sgt i32 %a, 3
     31   %sub = sub nsw i32 %a, 3
     32   %sub. = select i1 %cmp, i32 %sub, i32 %b
     33   ret i32 %sub.
     34 }
     35 
     36 define i32 @i(i32 inreg %a, i32 inreg %b) nounwind readnone ssp {
     37 entry:
     38 ; CHECK-LABEL: i:
     39 ; CHECK: sub.f %r7, %r6, [[IN:%.*]]
     40 ; CHECK: sel.ult [[IN]], %r0, %rv
     41   %cmp = icmp ult i32 %a, %b
     42   %sub = sub i32 %b, %a
     43   %sub. = select i1 %cmp, i32 %sub, i32 0
     44   ret i32 %sub.
     45 }
     46 ; If SR is live-out, we can't remove cmp if there exists a swapped sub.
     47 define i32 @j(i32 inreg %a, i32 inreg %b) nounwind {
     48 entry:
     49 ; CHECK-LABEL: j:
     50 ; CHECK: sub.f %r7, %r6, %r0
     51 ; CHECK: sub %r6, %r7, %rv
     52   %cmp = icmp eq i32 %b, %a
     53   %sub = sub nsw i32 %a, %b
     54   br i1 %cmp, label %if.then, label %if.else
     55 
     56 if.then:
     57   %cmp2 = icmp sgt i32 %b, %a
     58   %sel = select i1 %cmp2, i32 %sub, i32 %a
     59   ret i32 %sel
     60 
     61 if.else:
     62   ret i32 %sub
     63 }
     64 
     65 declare void @abort()
     66 declare void @exit(i32)
     67 @t = common global i32 0
     68 
     69 ; If the comparison uses the C bit (signed overflow/underflow), we can't
     70 ; omit the comparison.
     71 define i32 @cmp_ult0(i32 inreg %a, i32 inreg %b, i32 inreg %x, i32 inreg %y) {
     72 entry:
     73 ; CHECK-LABEL: cmp_ult0
     74 ; CHECK: sub {{.*}}, 0x11, [[IN:%.*]]
     75 ; CHECK: sub.f [[IN]], 0x0, %r0
     76   %load = load i32, i32* @t, align 4
     77   %sub = sub i32 %load, 17
     78   %cmp = icmp ult i32 %sub, 0
     79   br i1 %cmp, label %if.then, label %if.else
     80 
     81 if.then:
     82   call void @abort()
     83   unreachable
     84 
     85 if.else:
     86   call void @exit(i32 0)
     87   unreachable
     88 }
     89 
     90 ; Same for the V bit.
     91 ; TODO: add test that exercises V bit individually (VC/VS).
     92 define i32 @cmp_gt0(i32 inreg %a, i32 inreg %b, i32 inreg %x, i32 inreg %y) {
     93 entry:
     94 ; CHECK-LABEL: cmp_gt0
     95 ; CHECK: sub {{.*}}, 0x11, [[IN:%.*]]
     96 ; CHECK: sub.f [[IN]], 0x1, %r0
     97   %load = load i32, i32* @t, align 4
     98   %sub = sub i32 %load, 17
     99   %cmp = icmp sgt i32 %sub, 0
    100   br i1 %cmp, label %if.then, label %if.else
    101 
    102 if.then:
    103   call void @abort()
    104   unreachable
    105 
    106 if.else:
    107   call void @exit(i32 0)
    108   unreachable
    109 }
    110