[SystemZ] Also clear kill flag for index reg in splitMove().
[oota-llvm.git] / test / CodeGen / SystemZ / memcmp-02.ll
1 ; Test memcmp using CLC, with i64 results.
2 ;
3 ; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
4
5 declare i64 @memcmp(i8 *%src1, i8 *%src2, i64 %size)
6
7 ; Zero-length comparisons should be optimized away.
8 define i64 @f1(i8 *%src1, i8 *%src2) {
9 ; CHECK-LABEL: f1:
10 ; CHECK: lghi %r2, 0
11 ; CHECK: br %r14
12   %res = call i64 @memcmp(i8 *%src1, i8 *%src2, i64 0)
13   ret i64 %res
14 }
15
16 ; Check a case where the result is used as an integer.
17 define i64 @f2(i8 *%src1, i8 *%src2) {
18 ; CHECK-LABEL: f2:
19 ; CHECK: clc 0(2,%r2), 0(%r3)
20 ; CHECK: ipm [[REG:%r[0-5]]]
21 ; CHECK: srl [[REG]], 28
22 ; CHECK: rll [[REG]], [[REG]], 31
23 ; CHECK: lgfr %r2, [[REG]]
24 ; CHECK: br %r14
25   %res = call i64 @memcmp(i8 *%src1, i8 *%src2, i64 2)
26   ret i64 %res
27 }
28
29 ; Check a case where the result is tested for equality.
30 define void @f3(i8 *%src1, i8 *%src2, i64 *%dest) {
31 ; CHECK-LABEL: f3:
32 ; CHECK: clc 0(3,%r2), 0(%r3)
33 ; CHECK-NEXT: je {{\..*}}
34 ; CHECK: br %r14
35   %res = call i64 @memcmp(i8 *%src1, i8 *%src2, i64 3)
36   %cmp = icmp eq i64 %res, 0
37   br i1 %cmp, label %exit, label %store
38
39 store:
40   store i64 0, i64 *%dest
41   br label %exit
42
43 exit:
44   ret void
45 }
46
47 ; Check a case where the result is tested for inequality.
48 define void @f4(i8 *%src1, i8 *%src2, i64 *%dest) {
49 ; CHECK-LABEL: f4:
50 ; CHECK: clc 0(4,%r2), 0(%r3)
51 ; CHECK-NEXT: jlh {{\..*}}
52 ; CHECK: br %r14
53 entry:
54   %res = call i64 @memcmp(i8 *%src1, i8 *%src2, i64 4)
55   %cmp = icmp ne i64 %res, 0
56   br i1 %cmp, label %exit, label %store
57
58 store:
59   store i64 0, i64 *%dest
60   br label %exit
61
62 exit:
63   ret void
64 }
65
66 ; Check a case where the result is tested via slt.
67 define void @f5(i8 *%src1, i8 *%src2, i64 *%dest) {
68 ; CHECK-LABEL: f5:
69 ; CHECK: clc 0(5,%r2), 0(%r3)
70 ; CHECK-NEXT: jl {{\..*}}
71 ; CHECK: br %r14
72 entry:
73   %res = call i64 @memcmp(i8 *%src1, i8 *%src2, i64 5)
74   %cmp = icmp slt i64 %res, 0
75   br i1 %cmp, label %exit, label %store
76
77 store:
78   store i64 0, i64 *%dest
79   br label %exit
80
81 exit:
82   ret void
83 }
84
85 ; Check a case where the result is tested for sgt.
86 define void @f6(i8 *%src1, i8 *%src2, i64 *%dest) {
87 ; CHECK-LABEL: f6:
88 ; CHECK: clc 0(6,%r2), 0(%r3)
89 ; CHECK-NEXT: jh {{\..*}}
90 ; CHECK: br %r14
91 entry:
92   %res = call i64 @memcmp(i8 *%src1, i8 *%src2, i64 6)
93   %cmp = icmp sgt i64 %res, 0
94   br i1 %cmp, label %exit, label %store
95
96 store:
97   store i64 0, i64 *%dest
98   br label %exit
99
100 exit:
101   ret void
102 }
103
104 ; Check the upper end of the CLC range.  Here the result is used both as
105 ; an integer and for branching.
106 define i64 @f7(i8 *%src1, i8 *%src2, i64 *%dest) {
107 ; CHECK-LABEL: f7:
108 ; CHECK: clc 0(256,%r2), 0(%r3)
109 ; CHECK: ipm [[REG:%r[0-5]]]
110 ; CHECK: srl [[REG]], 28
111 ; CHECK: rll [[REG]], [[REG]], 31
112 ; CHECK: lgfr %r2, [[REG]]
113 ; CHECK: jl {{.L*}}
114 ; CHECK: br %r14
115 entry:
116   %res = call i64 @memcmp(i8 *%src1, i8 *%src2, i64 256)
117   %cmp = icmp slt i64 %res, 0
118   br i1 %cmp, label %exit, label %store
119
120 store:
121   store i64 0, i64 *%dest
122   br label %exit
123
124 exit:
125   ret i64 %res
126 }
127
128 ; 257 bytes needs two CLCs.
129 define i64 @f8(i8 *%src1, i8 *%src2) {
130 ; CHECK-LABEL: f8:
131 ; CHECK: clc 0(256,%r2), 0(%r3)
132 ; CHECK: jlh [[LABEL:\..*]]
133 ; CHECK: clc 256(1,%r2), 256(%r3)
134 ; CHECK: [[LABEL]]:
135 ; CHECK: ipm [[REG:%r[0-5]]]
136 ; CHECK: br %r14
137   %res = call i64 @memcmp(i8 *%src1, i8 *%src2, i64 257)
138   ret i64 %res
139 }