1; Test the Test Data Class instruction logic operation folding.
2;
3; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
4
5declare i32 @llvm.s390.tdc.f32(float, i64)
6declare i32 @llvm.s390.tdc.f64(double, i64)
7declare i32 @llvm.s390.tdc.f128(fp128, i64)
8
9; Check using or i1
10define i32 @f1(float %x) {
11; CHECK-LABEL: f1
12; CHECK: tceb %f0, 7
13; CHECK-NEXT: ipm [[REG1:%r[0-9]+]]
14; CHECK-NEXT: risbg %r2, [[REG1]], 63, 191, 36
15  %a = call i32 @llvm.s390.tdc.f32(float %x, i64 3)
16  %b = call i32 @llvm.s390.tdc.f32(float %x, i64 6)
17  %a1 = icmp ne i32 %a, 0
18  %b1 = icmp ne i32 %b, 0
19  %res = or i1 %a1, %b1
20  %xres = zext i1 %res to i32
21  ret i32 %xres
22}
23
24; Check using and i1
25define i32 @f2(double %x) {
26; CHECK-LABEL: f2
27; CHECK: tcdb %f0, 2
28; CHECK-NEXT: ipm [[REG1:%r[0-9]+]]
29; CHECK-NEXT: risbg %r2, [[REG1]], 63, 191, 36
30  %a = call i32 @llvm.s390.tdc.f64(double %x, i64 3)
31  %b = call i32 @llvm.s390.tdc.f64(double %x, i64 6)
32  %a1 = icmp ne i32 %a, 0
33  %b1 = icmp ne i32 %b, 0
34  %res = and i1 %a1, %b1
35  %xres = zext i1 %res to i32
36  ret i32 %xres
37}
38
39; Check using xor i1
40define i32 @f3(fp128 %x) {
41; CHECK-LABEL: f3
42; CHECK: tcxb %f0, 5
43; CHECK-NEXT: ipm [[REG1:%r[0-9]+]]
44; CHECK-NEXT: risbg %r2, [[REG1]], 63, 191, 36
45  %a = call i32 @llvm.s390.tdc.f128(fp128 %x, i64 3)
46  %b = call i32 @llvm.s390.tdc.f128(fp128 %x, i64 6)
47  %a1 = icmp ne i32 %a, 0
48  %b1 = icmp ne i32 %b, 0
49  %res = xor i1 %a1, %b1
50  %xres = zext i1 %res to i32
51  ret i32 %xres
52}
53
54; Check using xor i1 - negated test
55define i32 @f4(fp128 %x) {
56; CHECK-LABEL: f4
57; CHECK: tcxb %f0, 4090
58; CHECK-NEXT: ipm [[REG1:%r[0-9]+]]
59; CHECK-NEXT: risbg %r2, [[REG1]], 63, 191, 36
60  %a = call i32 @llvm.s390.tdc.f128(fp128 %x, i64 3)
61  %b = call i32 @llvm.s390.tdc.f128(fp128 %x, i64 6)
62  %a1 = icmp ne i32 %a, 0
63  %b1 = icmp eq i32 %b, 0
64  %res = xor i1 %a1, %b1
65  %xres = zext i1 %res to i32
66  ret i32 %xres
67}
68
69; Check different first args
70define i32 @f5(float %x, float %y) {
71; CHECK-LABEL: f5
72; CHECK-NOT: tceb {{%f[0-9]+}}, 5
73; CHECK-DAG: tceb %f0, 3
74; CHECK-DAG: tceb %f2, 6
75  %a = call i32 @llvm.s390.tdc.f32(float %x, i64 3)
76  %b = call i32 @llvm.s390.tdc.f32(float %y, i64 6)
77  %a1 = icmp ne i32 %a, 0
78  %b1 = icmp ne i32 %b, 0
79  %res = xor i1 %a1, %b1
80  %xres = zext i1 %res to i32
81  ret i32 %xres
82}
83
84; Non-const mask (not supported)
85define i32 @f6(float %x, i64 %y) {
86; CHECK-LABEL: f6
87; CHECK-DAG: tceb %f0, 0(%r2)
88; CHECK-DAG: tceb %f0, 6
89  %a = call i32 @llvm.s390.tdc.f32(float %x, i64 %y)
90  %b = call i32 @llvm.s390.tdc.f32(float %x, i64 6)
91  %a1 = icmp ne i32 %a, 0
92  %b1 = icmp ne i32 %b, 0
93  %res = xor i1 %a1, %b1
94  %xres = zext i1 %res to i32
95  ret i32 %xres
96}
97