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