[InstCombine] Signed saturation patterns
[llvm-complete.git] / test / CodeGen / Lanai / sub-cmp-peephole.ll
blobfec23f6969fe819f2cda1c47f2408fc65ab2ff1e
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=lanai | FileCheck %s
4 define i32 @f(i32 inreg %a, i32 inreg %b) nounwind ssp {
5 ; CHECK-LABEL: f:
6 ; CHECK:       ! %bb.0:
7 ; CHECK-NEXT:    st %fp, [--%sp]
8 ; CHECK-NEXT:    add %sp, 0x8, %fp
9 ; CHECK-NEXT:    sub %sp, 0x8, %sp
10 ; CHECK-NEXT:    sub.f %r6, %r7, %r3
11 ; CHECK-NEXT:    sel.gt %r3, %r0, %rv
12 ; CHECK-NEXT:    ld -4[%fp], %pc ! return
13 ; CHECK-NEXT:    add %fp, 0x0, %sp
14 ; CHECK-NEXT:    ld -8[%fp], %fp
15   %cmp = icmp sgt i32 %a, %b
16   %sub = sub nsw i32 %a, %b
17   %sub. = select i1 %cmp, i32 %sub, i32 0
18   ret i32 %sub.
21 define i32 @g(i32 inreg %a, i32 inreg %b) nounwind ssp {
22 ; CHECK-LABEL: g:
23 ; CHECK:       ! %bb.0:
24 ; CHECK-NEXT:    st %fp, [--%sp]
25 ; CHECK-NEXT:    add %sp, 0x8, %fp
26 ; CHECK-NEXT:    sub %sp, 0x8, %sp
27 ; CHECK-NEXT:    sub.f %r7, %r6, %r3
28 ; CHECK-NEXT:    sel.gt %r3, %r0, %rv
29 ; CHECK-NEXT:    ld -4[%fp], %pc ! return
30 ; CHECK-NEXT:    add %fp, 0x0, %sp
31 ; CHECK-NEXT:    ld -8[%fp], %fp
32   %cmp = icmp slt i32 %a, %b
33   %sub = sub nsw i32 %b, %a
34   %sub. = select i1 %cmp, i32 %sub, i32 0
35   ret i32 %sub.
38 define i32 @h(i32 inreg %a, i32 inreg %b) nounwind ssp {
39 ; CHECK-LABEL: h:
40 ; CHECK:       ! %bb.0:
41 ; CHECK-NEXT:    st %fp, [--%sp]
42 ; CHECK-NEXT:    add %sp, 0x8, %fp
43 ; CHECK-NEXT:    sub %sp, 0x8, %sp
44 ; CHECK-NEXT:    sub.f %r6, 0x3, %r3
45 ; CHECK-NEXT:    sel.gt %r3, %r7, %rv
46 ; CHECK-NEXT:    ld -4[%fp], %pc ! return
47 ; CHECK-NEXT:    add %fp, 0x0, %sp
48 ; CHECK-NEXT:    ld -8[%fp], %fp
49   %cmp = icmp sgt i32 %a, 3
50   %sub = sub nsw i32 %a, 3
51   %sub. = select i1 %cmp, i32 %sub, i32 %b
52   ret i32 %sub.
55 define i32 @i(i32 inreg %a, i32 inreg %b) nounwind readnone ssp {
56 ; CHECK-LABEL: i:
57 ; CHECK:       ! %bb.0:
58 ; CHECK-NEXT:    st %fp, [--%sp]
59 ; CHECK-NEXT:    add %sp, 0x8, %fp
60 ; CHECK-NEXT:    sub %sp, 0x8, %sp
61 ; CHECK-NEXT:    sub.f %r7, %r6, %r3
62 ; CHECK-NEXT:    sel.ugt %r3, %r0, %rv
63 ; CHECK-NEXT:    ld -4[%fp], %pc ! return
64 ; CHECK-NEXT:    add %fp, 0x0, %sp
65 ; CHECK-NEXT:    ld -8[%fp], %fp
66   %cmp = icmp ult i32 %a, %b
67   %sub = sub i32 %b, %a
68   %sub. = select i1 %cmp, i32 %sub, i32 0
69   ret i32 %sub.
72 ; If SR is live-out, we can't remove cmp if there exists a swapped sub.
73 define i32 @j(i32 inreg %a, i32 inreg %b) nounwind {
74 ; CHECK-LABEL: j:
75 ; CHECK:       ! %bb.0: ! %entry
76 ; CHECK-NEXT:    st %fp, [--%sp]
77 ; CHECK-NEXT:    add %sp, 0x8, %fp
78 ; CHECK-NEXT:    sub.f %r6, %r7, %rv
79 ; CHECK-NEXT:    bne .LBB4_2
80 ; CHECK-NEXT:    sub %sp, 0x8, %sp
81 ; CHECK-NEXT:  .LBB4_1: ! %if.then
82 ; CHECK-NEXT:    sub.f %r7, %r6, %r0
83 ; CHECK-NEXT:    sel.gt %rv, %r6, %rv
84 ; CHECK-NEXT:  .LBB4_2: ! %if.else
85 ; CHECK-NEXT:    ld -4[%fp], %pc ! return
86 ; CHECK-NEXT:    add %fp, 0x0, %sp
87 ; CHECK-NEXT:    ld -8[%fp], %fp
88 entry:
89   %cmp = icmp eq i32 %b, %a
90   %sub = sub nsw i32 %a, %b
91   br i1 %cmp, label %if.then, label %if.else
93 if.then:
94   %cmp2 = icmp sgt i32 %b, %a
95   %sel = select i1 %cmp2, i32 %sub, i32 %a
96   ret i32 %sel
98 if.else:
99   ret i32 %sub
102 declare void @abort()
103 declare void @exit(i32)
104 @t = common global i32 0
106 ; If the comparison uses the C bit (signed overflow/underflow), we can't
107 ; omit the comparison.
108 define i32 @cmp_ult0(i32 inreg %a, i32 inreg %b, i32 inreg %x, i32 inreg %y) {
109 ; CHECK-LABEL: cmp_ult0:
110 ; CHECK:       ! %bb.0: ! %entry
111 ; CHECK-NEXT:    st %fp, [--%sp]
112 ; CHECK-NEXT:    add %sp, 0x8, %fp
113 ; CHECK-NEXT:    mov hi(t), %r3
114 ; CHECK-NEXT:    or %r3, lo(t), %r3
115 ; CHECK-NEXT:    ld 0[%r3], %r3
116 ; CHECK-NEXT:    sub %r3, 0x11, %r3
117 ; CHECK-NEXT:    sub.f %r3, 0x0, %r0
118 ; CHECK-NEXT:    buge .LBB5_2
119 ; CHECK-NEXT:    sub %sp, 0x10, %sp
120 ; CHECK-NEXT:  .LBB5_1: ! %if.then
121 ; CHECK-NEXT:    add %pc, 0x10, %rca
122 ; CHECK-NEXT:    st %rca, [--%sp]
123 ; CHECK-NEXT:    bt abort
124 ; CHECK-NEXT:    nop
125 ; CHECK-NEXT:  .LBB5_2: ! %if.else
126 ; CHECK-NEXT:    st %r0, 0[%sp]
127 ; CHECK-NEXT:    add %pc, 0x10, %rca
128 ; CHECK-NEXT:    st %rca, [--%sp]
129 ; CHECK-NEXT:    bt exit
130 ; CHECK-NEXT:    nop
131 entry:
132   %load = load i32, i32* @t, align 4
133   %sub = sub i32 %load, 17
134   %cmp = icmp ult i32 %sub, 0
135   br i1 %cmp, label %if.then, label %if.else
137 if.then:
138   call void @abort()
139   unreachable
141 if.else:
142   call void @exit(i32 0)
143   unreachable
146 ; Same for the V bit.
147 ; TODO: add test that exercises V bit individually (VC/VS).
148 define i32 @cmp_gt0(i32 inreg %a, i32 inreg %b, i32 inreg %x, i32 inreg %y) {
149 ; CHECK-LABEL: cmp_gt0:
150 ; CHECK:       ! %bb.0: ! %entry
151 ; CHECK-NEXT:    st %fp, [--%sp]
152 ; CHECK-NEXT:    add %sp, 0x8, %fp
153 ; CHECK-NEXT:    mov hi(t), %r3
154 ; CHECK-NEXT:    or %r3, lo(t), %r3
155 ; CHECK-NEXT:    ld 0[%r3], %r3
156 ; CHECK-NEXT:    sub %r3, 0x11, %r3
157 ; CHECK-NEXT:    sub.f %r3, 0x1, %r0
158 ; CHECK-NEXT:    blt .LBB6_2
159 ; CHECK-NEXT:    sub %sp, 0x10, %sp
160 ; CHECK-NEXT:  .LBB6_1: ! %if.then
161 ; CHECK-NEXT:    add %pc, 0x10, %rca
162 ; CHECK-NEXT:    st %rca, [--%sp]
163 ; CHECK-NEXT:    bt abort
164 ; CHECK-NEXT:    nop
165 ; CHECK-NEXT:  .LBB6_2: ! %if.else
166 ; CHECK-NEXT:    st %r0, 0[%sp]
167 ; CHECK-NEXT:    add %pc, 0x10, %rca
168 ; CHECK-NEXT:    st %rca, [--%sp]
169 ; CHECK-NEXT:    bt exit
170 ; CHECK-NEXT:    nop
171 entry:
172   %load = load i32, i32* @t, align 4
173   %sub = sub i32 %load, 17
174   %cmp = icmp sgt i32 %sub, 0
175   br i1 %cmp, label %if.then, label %if.else
177 if.then:
178   call void @abort()
179   unreachable
181 if.else:
182   call void @exit(i32 0)
183   unreachable