blob: c26383e9df03b1426c05e6e9fb652ae213a3d3dd [file] [log] [blame]
Ulrich Weigand9e3577f2013-05-06 16:17:29 +00001; Test 128-bit addition in which the second operand is a zero-extended i32.
2;
3; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
4
5; Check register additions. The XOR ensures that we don't instead zero-extend
6; %b into a register and use memory addition.
7define void @f1(i128 *%aptr, i32 %b) {
Stephen Lind24ab202013-07-14 06:24:09 +00008; CHECK-LABEL: f1:
Ulrich Weigand9e3577f2013-05-06 16:17:29 +00009; CHECK: slgfr {{%r[0-5]}}, %r3
10; CHECK: slbgr
11; CHECK: br %r14
David Blaikiea79ac142015-02-27 21:17:42 +000012 %a = load i128 , i128 *%aptr
Ulrich Weigand9e3577f2013-05-06 16:17:29 +000013 %xor = xor i128 %a, 127
14 %bext = zext i32 %b to i128
15 %sub = sub i128 %xor, %bext
16 store i128 %sub, i128 *%aptr
17 ret void
18}
19
20; Like f1, but using an "in-register" extension.
21define void @f2(i128 *%aptr, i64 %b) {
Stephen Lind24ab202013-07-14 06:24:09 +000022; CHECK-LABEL: f2:
Ulrich Weigand9e3577f2013-05-06 16:17:29 +000023; CHECK: slgfr {{%r[0-5]}}, %r3
24; CHECK: slbgr
25; CHECK: br %r14
David Blaikiea79ac142015-02-27 21:17:42 +000026 %a = load i128 , i128 *%aptr
Ulrich Weigand9e3577f2013-05-06 16:17:29 +000027 %xor = xor i128 %a, 127
28 %trunc = trunc i64 %b to i32
29 %bext = zext i32 %trunc to i128
30 %sub = sub i128 %xor, %bext
31 store i128 %sub, i128 *%aptr
32 ret void
33}
34
35; Test register addition in cases where the second operand is zero extended
36; from i64 rather than i32, but is later masked to i32 range.
37define void @f3(i128 *%aptr, i64 %b) {
Stephen Lind24ab202013-07-14 06:24:09 +000038; CHECK-LABEL: f3:
Ulrich Weigand9e3577f2013-05-06 16:17:29 +000039; CHECK: slgfr {{%r[0-5]}}, %r3
40; CHECK: slbgr
41; CHECK: br %r14
David Blaikiea79ac142015-02-27 21:17:42 +000042 %a = load i128 , i128 *%aptr
Ulrich Weigand9e3577f2013-05-06 16:17:29 +000043 %xor = xor i128 %a, 127
44 %bext = zext i64 %b to i128
45 %and = and i128 %bext, 4294967295
46 %sub = sub i128 %xor, %and
47 store i128 %sub, i128 *%aptr
48 ret void
49}
50
51; Test SLGF with no offset.
52define void @f4(i128 *%aptr, i32 *%bsrc) {
Stephen Lind24ab202013-07-14 06:24:09 +000053; CHECK-LABEL: f4:
Ulrich Weigand9e3577f2013-05-06 16:17:29 +000054; CHECK: slgf {{%r[0-5]}}, 0(%r3)
55; CHECK: slbgr
56; CHECK: br %r14
David Blaikiea79ac142015-02-27 21:17:42 +000057 %a = load i128 , i128 *%aptr
Ulrich Weigand9e3577f2013-05-06 16:17:29 +000058 %xor = xor i128 %a, 127
David Blaikiea79ac142015-02-27 21:17:42 +000059 %b = load i32 , i32 *%bsrc
Ulrich Weigand9e3577f2013-05-06 16:17:29 +000060 %bext = zext i32 %b to i128
61 %sub = sub i128 %xor, %bext
62 store i128 %sub, i128 *%aptr
63 ret void
64}
65
66; Check the high end of the SLGF range.
67define void @f5(i128 *%aptr, i32 *%bsrc) {
Stephen Lind24ab202013-07-14 06:24:09 +000068; CHECK-LABEL: f5:
Ulrich Weigand9e3577f2013-05-06 16:17:29 +000069; CHECK: slgf {{%r[0-5]}}, 524284(%r3)
70; CHECK: slbgr
71; CHECK: br %r14
David Blaikiea79ac142015-02-27 21:17:42 +000072 %a = load i128 , i128 *%aptr
Ulrich Weigand9e3577f2013-05-06 16:17:29 +000073 %xor = xor i128 %a, 127
David Blaikie79e6c742015-02-27 19:29:02 +000074 %ptr = getelementptr i32, i32 *%bsrc, i64 131071
David Blaikiea79ac142015-02-27 21:17:42 +000075 %b = load i32 , i32 *%ptr
Ulrich Weigand9e3577f2013-05-06 16:17:29 +000076 %bext = zext i32 %b to i128
77 %sub = sub i128 %xor, %bext
78 store i128 %sub, i128 *%aptr
79 ret void
80}
81
82; Check the next word up, which must use separate address logic.
83; Other sequences besides this one would be OK.
84define void @f6(i128 *%aptr, i32 *%bsrc) {
Stephen Lind24ab202013-07-14 06:24:09 +000085; CHECK-LABEL: f6:
Ulrich Weigand9e3577f2013-05-06 16:17:29 +000086; CHECK: agfi %r3, 524288
87; CHECK: slgf {{%r[0-5]}}, 0(%r3)
88; CHECK: slbgr
89; CHECK: br %r14
David Blaikiea79ac142015-02-27 21:17:42 +000090 %a = load i128 , i128 *%aptr
Ulrich Weigand9e3577f2013-05-06 16:17:29 +000091 %xor = xor i128 %a, 127
David Blaikie79e6c742015-02-27 19:29:02 +000092 %ptr = getelementptr i32, i32 *%bsrc, i64 131072
David Blaikiea79ac142015-02-27 21:17:42 +000093 %b = load i32 , i32 *%ptr
Ulrich Weigand9e3577f2013-05-06 16:17:29 +000094 %bext = zext i32 %b to i128
95 %sub = sub i128 %xor, %bext
96 store i128 %sub, i128 *%aptr
97 ret void
98}
99
100; Check the high end of the negative aligned SLGF range.
101define void @f7(i128 *%aptr, i32 *%bsrc) {
Stephen Lind24ab202013-07-14 06:24:09 +0000102; CHECK-LABEL: f7:
Ulrich Weigand9e3577f2013-05-06 16:17:29 +0000103; CHECK: slgf {{%r[0-5]}}, -4(%r3)
104; CHECK: slbgr
105; CHECK: br %r14
David Blaikiea79ac142015-02-27 21:17:42 +0000106 %a = load i128 , i128 *%aptr
Ulrich Weigand9e3577f2013-05-06 16:17:29 +0000107 %xor = xor i128 %a, 127
David Blaikie79e6c742015-02-27 19:29:02 +0000108 %ptr = getelementptr i32, i32 *%bsrc, i128 -1
David Blaikiea79ac142015-02-27 21:17:42 +0000109 %b = load i32 , i32 *%ptr
Ulrich Weigand9e3577f2013-05-06 16:17:29 +0000110 %bext = zext i32 %b to i128
111 %sub = sub i128 %xor, %bext
112 store i128 %sub, i128 *%aptr
113 ret void
114}
115
116; Check the low end of the SLGF range.
117define void @f8(i128 *%aptr, i32 *%bsrc) {
Stephen Lind24ab202013-07-14 06:24:09 +0000118; CHECK-LABEL: f8:
Ulrich Weigand9e3577f2013-05-06 16:17:29 +0000119; CHECK: slgf {{%r[0-5]}}, -524288(%r3)
120; CHECK: slbgr
121; CHECK: br %r14
David Blaikiea79ac142015-02-27 21:17:42 +0000122 %a = load i128 , i128 *%aptr
Ulrich Weigand9e3577f2013-05-06 16:17:29 +0000123 %xor = xor i128 %a, 127
David Blaikie79e6c742015-02-27 19:29:02 +0000124 %ptr = getelementptr i32, i32 *%bsrc, i128 -131072
David Blaikiea79ac142015-02-27 21:17:42 +0000125 %b = load i32 , i32 *%ptr
Ulrich Weigand9e3577f2013-05-06 16:17:29 +0000126 %bext = zext i32 %b to i128
127 %sub = sub i128 %xor, %bext
128 store i128 %sub, i128 *%aptr
129 ret void
130}
131
132; Check the next word down, which needs separate address logic.
133; Other sequences besides this one would be OK.
134define void @f9(i128 *%aptr, i32 *%bsrc) {
Stephen Lind24ab202013-07-14 06:24:09 +0000135; CHECK-LABEL: f9:
Ulrich Weigand9e3577f2013-05-06 16:17:29 +0000136; CHECK: agfi %r3, -524292
137; CHECK: slgf {{%r[0-5]}}, 0(%r3)
138; CHECK: slbgr
139; CHECK: br %r14
David Blaikiea79ac142015-02-27 21:17:42 +0000140 %a = load i128 , i128 *%aptr
Ulrich Weigand9e3577f2013-05-06 16:17:29 +0000141 %xor = xor i128 %a, 127
David Blaikie79e6c742015-02-27 19:29:02 +0000142 %ptr = getelementptr i32, i32 *%bsrc, i128 -131073
David Blaikiea79ac142015-02-27 21:17:42 +0000143 %b = load i32 , i32 *%ptr
Ulrich Weigand9e3577f2013-05-06 16:17:29 +0000144 %bext = zext i32 %b to i128
145 %sub = sub i128 %xor, %bext
146 store i128 %sub, i128 *%aptr
147 ret void
148}
149
150; Check that SLGF allows an index.
151define void @f10(i128 *%aptr, i64 %src, i64 %index) {
Stephen Lind24ab202013-07-14 06:24:09 +0000152; CHECK-LABEL: f10:
Ulrich Weigand9e3577f2013-05-06 16:17:29 +0000153; CHECK: slgf {{%r[0-5]}}, 524284({{%r4,%r3|%r3,%r4}})
154; CHECK: br %r14
David Blaikiea79ac142015-02-27 21:17:42 +0000155 %a = load i128 , i128 *%aptr
Ulrich Weigand9e3577f2013-05-06 16:17:29 +0000156 %xor = xor i128 %a, 127
157 %add1 = add i64 %src, %index
158 %add2 = add i64 %add1, 524284
159 %ptr = inttoptr i64 %add2 to i32 *
David Blaikiea79ac142015-02-27 21:17:42 +0000160 %b = load i32 , i32 *%ptr
Ulrich Weigand9e3577f2013-05-06 16:17:29 +0000161 %bext = zext i32 %b to i128
162 %sub = sub i128 %xor, %bext
163 store i128 %sub, i128 *%aptr
164 ret void
165}