blob: edcd0c5dccd2ca90d9b467026540d6cc14d2cd44 [file] [log] [blame]
Ulrich Weigand9e3577f2013-05-06 16:17:29 +00001; Test insertions of i32s into the low half of an i64.
2;
3; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
4
5; Insertion of an i32 can be done using LR.
6define i64 @f1(i64 %a, i32 %b) {
Stephen Lind24ab202013-07-14 06:24:09 +00007; CHECK-LABEL: f1:
Ulrich Weigand9e3577f2013-05-06 16:17:29 +00008; CHECK-NOT: {{%r[23]}}
9; CHECK: lr %r2, %r3
10; CHECK: br %r14
11 %low = zext i32 %b to i64
12 %high = and i64 %a, -4294967296
13 %res = or i64 %high, %low
14 ret i64 %res
15}
16
17; ... and again with the operands reversed.
18define i64 @f2(i64 %a, i32 %b) {
Stephen Lind24ab202013-07-14 06:24:09 +000019; CHECK-LABEL: f2:
Ulrich Weigand9e3577f2013-05-06 16:17:29 +000020; CHECK-NOT: {{%r[23]}}
21; CHECK: lr %r2, %r3
22; CHECK: br %r14
23 %low = zext i32 %b to i64
24 %high = and i64 %a, -4294967296
25 %res = or i64 %low, %high
26 ret i64 %res
27}
28
29; Like f1, but with "in register" zero extension.
30define i64 @f3(i64 %a, i64 %b) {
Stephen Lind24ab202013-07-14 06:24:09 +000031; CHECK-LABEL: f3:
Ulrich Weigand9e3577f2013-05-06 16:17:29 +000032; CHECK-NOT: {{%r[23]}}
33; CHECK: lr %r2, %r3
34; CHECK: br %r14
35 %low = and i64 %b, 4294967295
36 %high = and i64 %a, -4294967296
37 %res = or i64 %high, %low
38 ret i64 %res
39}
40
41; ... and again with the operands reversed.
42define i64 @f4(i64 %a, i64 %b) {
Stephen Lind24ab202013-07-14 06:24:09 +000043; CHECK-LABEL: f4:
Ulrich Weigand9e3577f2013-05-06 16:17:29 +000044; CHECK-NOT: {{%r[23]}}
45; CHECK: lr %r2, %r3
46; CHECK: br %r14
47 %low = and i64 %b, 4294967295
48 %high = and i64 %a, -4294967296
49 %res = or i64 %low, %high
50 ret i64 %res
51}
52
53; Unary operations can be done directly into the low half.
54define i64 @f5(i64 %a, i32 %b) {
Stephen Lind24ab202013-07-14 06:24:09 +000055; CHECK-LABEL: f5:
Ulrich Weigand9e3577f2013-05-06 16:17:29 +000056; CHECK-NOT: {{%r[23]}}
57; CHECK: lcr %r2, %r3
58; CHECK: br %r14
59 %neg = sub i32 0, %b
60 %low = zext i32 %neg to i64
61 %high = and i64 %a, -4294967296
62 %res = or i64 %high, %low
63 ret i64 %res
64}
65
66; ...likewise three-operand binary operations like RLL.
67define i64 @f6(i64 %a, i32 %b) {
Stephen Lind24ab202013-07-14 06:24:09 +000068; CHECK-LABEL: f6:
Ulrich Weigand9e3577f2013-05-06 16:17:29 +000069; CHECK-NOT: {{%r[23]}}
70; CHECK: rll %r2, %r3, 1
71; CHECK: br %r14
72 %parta = shl i32 %b, 1
73 %partb = lshr i32 %b, 31
74 %rot = or i32 %parta, %partb
75 %low = zext i32 %rot to i64
76 %high = and i64 %a, -4294967296
77 %res = or i64 %low, %high
78 ret i64 %res
79}
80
81; Loads can be done directly into the low half. The range of L is checked
82; in the move tests.
83define i64 @f7(i64 %a, i32 *%src) {
Stephen Lind24ab202013-07-14 06:24:09 +000084; CHECK-LABEL: f7:
Ulrich Weigand9e3577f2013-05-06 16:17:29 +000085; CHECK-NOT: {{%r[23]}}
86; CHECK: l %r2, 0(%r3)
87; CHECK: br %r14
88 %b = load i32 *%src
89 %low = zext i32 %b to i64
90 %high = and i64 %a, -4294967296
91 %res = or i64 %high, %low
92 ret i64 %res
93}
94
95; ...likewise extending loads.
96define i64 @f8(i64 %a, i8 *%src) {
Stephen Lind24ab202013-07-14 06:24:09 +000097; CHECK-LABEL: f8:
Ulrich Weigand9e3577f2013-05-06 16:17:29 +000098; CHECK-NOT: {{%r[23]}}
99; CHECK: lb %r2, 0(%r3)
100; CHECK: br %r14
101 %byte = load i8 *%src
102 %b = sext i8 %byte to i32
103 %low = zext i32 %b to i64
104 %high = and i64 %a, -4294967296
105 %res = or i64 %high, %low
106 ret i64 %res
107}
108
109; Check a case like f1 in which there is no AND. We simply know from context
110; that the upper half of one OR operand and the lower half of the other are
111; both clear.
112define i64 @f9(i64 %a, i32 %b) {
Stephen Lind24ab202013-07-14 06:24:09 +0000113; CHECK-LABEL: f9:
Ulrich Weigand9e3577f2013-05-06 16:17:29 +0000114; CHECK: sllg %r2, %r2, 32
115; CHECK: lr %r2, %r3
116; CHECK: br %r14
117 %shift = shl i64 %a, 32
118 %low = zext i32 %b to i64
119 %or = or i64 %shift, %low
120 ret i64 %or
121}
122
123; ...and again with the operands reversed.
124define i64 @f10(i64 %a, i32 %b) {
Stephen Lind24ab202013-07-14 06:24:09 +0000125; CHECK-LABEL: f10:
Ulrich Weigand9e3577f2013-05-06 16:17:29 +0000126; CHECK: sllg %r2, %r2, 32
127; CHECK: lr %r2, %r3
128; CHECK: br %r14
129 %shift = shl i64 %a, 32
130 %low = zext i32 %b to i64
131 %or = or i64 %low, %shift
132 ret i64 %or
133}
134
135; Like f9, but with "in register" zero extension.
136define i64 @f11(i64 %a, i64 %b) {
Stephen Lind24ab202013-07-14 06:24:09 +0000137; CHECK-LABEL: f11:
Ulrich Weigand9e3577f2013-05-06 16:17:29 +0000138; CHECK: lr %r2, %r3
139; CHECK: br %r14
140 %shift = shl i64 %a, 32
141 %low = and i64 %b, 4294967295
142 %or = or i64 %shift, %low
143 ret i64 %or
144}
145
146; ...and again with the operands reversed.
147define i64 @f12(i64 %a, i64 %b) {
Stephen Lind24ab202013-07-14 06:24:09 +0000148; CHECK-LABEL: f12:
Ulrich Weigand9e3577f2013-05-06 16:17:29 +0000149; CHECK: lr %r2, %r3
150; CHECK: br %r14
151 %shift = shl i64 %a, 32
152 %low = and i64 %b, 4294967295
153 %or = or i64 %low, %shift
154 ret i64 %or
155}
156
157; Like f9, but for larger shifts than 32.
158define i64 @f13(i64 %a, i32 %b) {
Stephen Lind24ab202013-07-14 06:24:09 +0000159; CHECK-LABEL: f13:
Ulrich Weigand9e3577f2013-05-06 16:17:29 +0000160; CHECK: sllg %r2, %r2, 60
161; CHECK: lr %r2, %r3
162; CHECK: br %r14
163 %shift = shl i64 %a, 60
164 %low = zext i32 %b to i64
165 %or = or i64 %shift, %low
166 ret i64 %or
167}
Richard Sandifordccc2a7c2013-12-03 11:01:54 +0000168
169; We previously wrongly removed the upper AND as dead.
170define i64 @f14(i64 %a, i64 %b) {
171; CHECK-LABEL: f14:
172; CHECK: risbg {{%r[0-5]}}, %r2, 6, 134, 0
173; CHECK: br %r14
174 %and1 = and i64 %a, 144115188075855872
175 %and2 = and i64 %b, 15
176 %or = or i64 %and1, %and2
177 %res = icmp eq i64 %or, 0
178 %ext = sext i1 %res to i64
179 ret i64 %ext
180}