1; Test 32-bit comparisons in which the second operand is a PC-relative
2; variable.
3;
4; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
5
6@g = dso_local global i32 1
7@h = dso_local global i32 1, align 2, section "foo"
8
9; Check signed comparisons.
10define dso_local i32 @f1(i32 %src1) {
11; CHECK-LABEL: f1:
12; CHECK: crl %r2, g
13; CHECK-NEXT: blr %r14
14; CHECK: br %r14
15entry:
16  %src2 = load i32, i32 *@g
17  %cond = icmp slt i32 %src1, %src2
18  br i1 %cond, label %exit, label %mulb
19mulb:
20  %mul = mul i32 %src1, %src1
21  br label %exit
22exit:
23  %res = phi i32 [ %src1, %entry ], [ %mul, %mulb ]
24  ret i32 %res
25}
26
27; Check unsigned comparisons.
28define dso_local i32 @f2(i32 %src1) {
29; CHECK-LABEL: f2:
30; CHECK: clrl %r2, g
31; CHECK-NEXT: blr %r14
32; CHECK: br %r14
33entry:
34  %src2 = load i32, i32 *@g
35  %cond = icmp ult i32 %src1, %src2
36  br i1 %cond, label %exit, label %mulb
37mulb:
38  %mul = mul i32 %src1, %src1
39  br label %exit
40exit:
41  %res = phi i32 [ %src1, %entry ], [ %mul, %mulb ]
42  ret i32 %res
43}
44
45; Check equality, which can use CRL or CLRL.
46define dso_local i32 @f3(i32 %src1) {
47; CHECK-LABEL: f3:
48; CHECK: c{{l?}}rl %r2, g
49; CHECK-NEXT: ber %r14
50; CHECK: br %r14
51entry:
52  %src2 = load i32, i32 *@g
53  %cond = icmp eq i32 %src1, %src2
54  br i1 %cond, label %exit, label %mulb
55mulb:
56  %mul = mul i32 %src1, %src1
57  br label %exit
58exit:
59  %res = phi i32 [ %src1, %entry ], [ %mul, %mulb ]
60  ret i32 %res
61}
62
63; ...likewise inequality.
64define dso_local i32 @f4(i32 %src1) {
65; CHECK-LABEL: f4:
66; CHECK: c{{l?}}rl %r2, g
67; CHECK-NEXT: blhr %r14
68; CHECK: br %r14
69entry:
70  %src2 = load i32, i32 *@g
71  %cond = icmp ne i32 %src1, %src2
72  br i1 %cond, label %exit, label %mulb
73mulb:
74  %mul = mul i32 %src1, %src1
75  br label %exit
76exit:
77  %res = phi i32 [ %src1, %entry ], [ %mul, %mulb ]
78  ret i32 %res
79}
80
81; Repeat f1 with an unaligned address.
82define dso_local i32 @f5(i32 %src1) {
83; CHECK-LABEL: f5:
84; CHECK: larl [[REG:%r[0-5]]], h
85; CHECK: c %r2, 0([[REG]])
86; CHECK-NEXT: blr %r14
87; CHECK: br %r14
88entry:
89  %src2 = load i32, i32 *@h, align 2
90  %cond = icmp slt i32 %src1, %src2
91  br i1 %cond, label %exit, label %mulb
92mulb:
93  %mul = mul i32 %src1, %src1
94  br label %exit
95exit:
96  %res = phi i32 [ %src1, %entry ], [ %mul, %mulb ]
97  ret i32 %res
98}
99
100; Repeat f2 with an unaligned address.
101define dso_local i32 @f6(i32 %src1) {
102; CHECK-LABEL: f6:
103; CHECK: larl [[REG:%r[0-5]]], h
104; CHECK: cl %r2, 0([[REG]])
105; CHECK-NEXT: blr %r14
106; CHECK: br %r14
107entry:
108  %src2 = load i32, i32 *@h, align 2
109  %cond = icmp ult i32 %src1, %src2
110  br i1 %cond, label %exit, label %mulb
111mulb:
112  %mul = mul i32 %src1, %src1
113  br label %exit
114exit:
115  %res = phi i32 [ %src1, %entry ], [ %mul, %mulb ]
116  ret i32 %res
117}
118
119; Check the comparison can be reversed if that allows CRL to be used.
120define dso_local i32 @f7(i32 %src2) {
121; CHECK-LABEL: f7:
122; CHECK: crl %r2, g
123; CHECK-NEXT: bhr %r14
124; CHECK: br %r14
125entry:
126  %src1 = load i32, i32 *@g
127  %cond = icmp slt i32 %src1, %src2
128  br i1 %cond, label %exit, label %mulb
129mulb:
130  %mul = mul i32 %src2, %src2
131  br label %exit
132exit:
133  %res = phi i32 [ %src2, %entry ], [ %mul, %mulb ]
134  ret i32 %res
135}
136