1; Test LOCR and LOCGR.
2;
3; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z196 -verify-machineinstrs | FileCheck %s
4;
5; Run the test again to make sure it still works the same even
6; in the presence of the load-store-on-condition-2 facility.
7; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z13 -verify-machineinstrs | FileCheck %s
8;
9; And again in the presence of the select instructions.
10; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z15 -verify-machineinstrs | FileCheck %s
11
12; Test LOCR.
13define i32 @f1(i32 %a, i32 %b, i32 %limit) {
14; CHECK-LABEL: f1:
15; CHECK: clfi %r4, 42
16; CHECK: locrhe %r2, %r3
17; CHECK: br %r14
18  %cond = icmp ult i32 %limit, 42
19  %res = select i1 %cond, i32 %a, i32 %b
20  ret i32 %res
21}
22
23; Test LOCGR.
24define i64 @f2(i64 %a, i64 %b, i64 %limit) {
25; CHECK-LABEL: f2:
26; CHECK: clgfi %r4, 42
27; CHECK: locgrhe %r2, %r3
28; CHECK: br %r14
29  %cond = icmp ult i64 %limit, 42
30  %res = select i1 %cond, i64 %a, i64 %b
31  ret i64 %res
32}
33
34; Test LOCR in a case that could use COMPARE AND BRANCH.  We prefer using
35; LOCR if possible.
36define i32 @f3(i32 %a, i32 %b, i32 %limit) {
37; CHECK-LABEL: f3:
38; CHECK: chi %r4, 42
39; CHECK: locrlh %r2, %r3
40; CHECK: br %r14
41  %cond = icmp eq i32 %limit, 42
42  %res = select i1 %cond, i32 %a, i32 %b
43  ret i32 %res
44}
45
46; ...and again for LOCGR.
47define i64 @f4(i64 %a, i64 %b, i64 %limit) {
48; CHECK-LABEL: f4:
49; CHECK: cghi %r4, 42
50; CHECK: locgrlh %r2, %r3
51; CHECK: br %r14
52  %cond = icmp eq i64 %limit, 42
53  %res = select i1 %cond, i64 %a, i64 %b
54  ret i64 %res
55}
56
57; Check that we also get LOCR as a result of early if-conversion.
58define i32 @f5(i32 %a, i32 %b, i32 %limit) {
59; CHECK-LABEL: f5:
60; CHECK: clfi %r4, 41
61; CHECK: locrh %r2, %r3
62; CHECK: br %r14
63entry:
64  %cond = icmp ult i32 %limit, 42
65  br i1 %cond, label %if.then, label %return
66
67if.then:
68  br label %return
69
70return:
71  %res = phi i32 [ %a, %if.then ], [ %b, %entry ]
72  ret i32 %res
73}
74
75; ... and likewise for LOCGR.
76define i64 @f6(i64 %a, i64 %b, i64 %limit) {
77; CHECK-LABEL: f6:
78; CHECK: clgfi %r4, 41
79; CHECK: locgrh %r2, %r3
80; CHECK: br %r14
81entry:
82  %cond = icmp ult i64 %limit, 42
83  br i1 %cond, label %if.then, label %return
84
85if.then:
86  br label %return
87
88return:
89  %res = phi i64 [ %a, %if.then ], [ %b, %entry ]
90  ret i64 %res
91}
92
93; Check that inverting the condition works as well.
94define i32 @f7(i32 %a, i32 %b, i32 %limit) {
95; CHECK-LABEL: f7:
96; CHECK: clfi %r4, 41
97; CHECK: locrle %r2, %r3
98; CHECK: br %r14
99entry:
100  %cond = icmp ult i32 %limit, 42
101  br i1 %cond, label %if.then, label %return
102
103if.then:
104  br label %return
105
106return:
107  %res = phi i32 [ %b, %if.then ], [ %a, %entry ]
108  ret i32 %res
109}
110
111; ... and likewise for LOCGR.
112define i64 @f8(i64 %a, i64 %b, i64 %limit) {
113; CHECK-LABEL: f8:
114; CHECK: clgfi %r4, 41
115; CHECK: locgrle %r2, %r3
116; CHECK: br %r14
117entry:
118  %cond = icmp ult i64 %limit, 42
119  br i1 %cond, label %if.then, label %return
120
121if.then:
122  br label %return
123
124return:
125  %res = phi i64 [ %b, %if.then ], [ %a, %entry ]
126  ret i64 %res
127}
128
129