blob: 4a13ef47c8889299db5f703db0d9db1f8bf33c83 [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) {
7; CHECK: f1:
8; 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) {
19; CHECK: f2:
20; 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) {
31; CHECK: f3:
32; 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) {
43; CHECK: f4:
44; 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) {
55; CHECK: f5:
56; 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) {
68; CHECK: f6:
69; 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) {
84; CHECK: f7:
85; 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) {
97; CHECK: f8:
98; 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) {
113; CHECK: f9:
114; 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) {
125; CHECK: f10:
126; 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) {
137; CHECK: f11:
138; 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) {
148; CHECK: f12:
149; 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) {
159; CHECK: f13:
160; 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}