1; Test 64-bit multiplication in which the second operand is constant.
2;
3; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
4
5; Check multiplication by 2, which should use shifts.
6define i64 @f1(i64 %a, i64 *%dest) {
7; CHECK-LABEL: f1:
8; CHECK: sllg %r2, %r2, 1
9; CHECK: br %r14
10  %mul = mul i64 %a, 2
11  ret i64 %mul
12}
13
14; Check multiplication by 3.
15define i64 @f2(i64 %a, i64 *%dest) {
16; CHECK-LABEL: f2:
17; CHECK: mghi %r2, 3
18; CHECK: br %r14
19  %mul = mul i64 %a, 3
20  ret i64 %mul
21}
22
23; Check the high end of the MGHI range.
24define i64 @f3(i64 %a, i64 *%dest) {
25; CHECK-LABEL: f3:
26; CHECK: mghi %r2, 32767
27; CHECK: br %r14
28  %mul = mul i64 %a, 32767
29  ret i64 %mul
30}
31
32; Check the next value up, which should use shifts.
33define i64 @f4(i64 %a, i64 *%dest) {
34; CHECK-LABEL: f4:
35; CHECK: sllg %r2, %r2, 15
36; CHECK: br %r14
37  %mul = mul i64 %a, 32768
38  ret i64 %mul
39}
40
41; Check the next value up again, which can use MSGFI.
42define i64 @f5(i64 %a, i64 *%dest) {
43; CHECK-LABEL: f5:
44; CHECK: msgfi %r2, 32769
45; CHECK: br %r14
46  %mul = mul i64 %a, 32769
47  ret i64 %mul
48}
49
50; Check the high end of the MSGFI range.
51define i64 @f6(i64 %a, i64 *%dest) {
52; CHECK-LABEL: f6:
53; CHECK: msgfi %r2, 2147483647
54; CHECK: br %r14
55  %mul = mul i64 %a, 2147483647
56  ret i64 %mul
57}
58
59; Check the next value up, which should use shifts.
60define i64 @f7(i64 %a, i64 *%dest) {
61; CHECK-LABEL: f7:
62; CHECK: sllg %r2, %r2, 31
63; CHECK: br %r14
64  %mul = mul i64 %a, 2147483648
65  ret i64 %mul
66}
67
68; Check the next value up again, which cannot use a constant multiplicatoin.
69define i64 @f8(i64 %a, i64 *%dest) {
70; CHECK-LABEL: f8:
71; CHECK-NOT: msgfi
72; CHECK: br %r14
73  %mul = mul i64 %a, 2147483649
74  ret i64 %mul
75}
76
77; Check multiplication by -1, which is a negation.
78define i64 @f9(i64 %a, i64 *%dest) {
79; CHECK-LABEL: f9:
80; CHECK: lcgr {{%r[0-5]}}, %r2
81; CHECK: br %r14
82  %mul = mul i64 %a, -1
83  ret i64 %mul
84}
85
86; Check multiplication by -2, which should use shifts.
87define i64 @f10(i64 %a, i64 *%dest) {
88; CHECK-LABEL: f10:
89; CHECK: sllg [[SHIFTED:%r[0-5]]], %r2, 1
90; CHECK: lcgr %r2, [[SHIFTED]]
91; CHECK: br %r14
92  %mul = mul i64 %a, -2
93  ret i64 %mul
94}
95
96; Check multiplication by -3.
97define i64 @f11(i64 %a, i64 *%dest) {
98; CHECK-LABEL: f11:
99; CHECK: mghi %r2, -3
100; CHECK: br %r14
101  %mul = mul i64 %a, -3
102  ret i64 %mul
103}
104
105; Check the lowest useful MGHI value.
106define i64 @f12(i64 %a, i64 *%dest) {
107; CHECK-LABEL: f12:
108; CHECK: mghi %r2, -32767
109; CHECK: br %r14
110  %mul = mul i64 %a, -32767
111  ret i64 %mul
112}
113
114; Check the next value down, which should use shifts.
115define i64 @f13(i64 %a, i64 *%dest) {
116; CHECK-LABEL: f13:
117; CHECK: sllg [[SHIFTED:%r[0-5]]], %r2, 15
118; CHECK: lcgr %r2, [[SHIFTED]]
119; CHECK: br %r14
120  %mul = mul i64 %a, -32768
121  ret i64 %mul
122}
123
124; Check the next value down again, which can use MSGFI.
125define i64 @f14(i64 %a, i64 *%dest) {
126; CHECK-LABEL: f14:
127; CHECK: msgfi %r2, -32769
128; CHECK: br %r14
129  %mul = mul i64 %a, -32769
130  ret i64 %mul
131}
132
133; Check the lowest useful MSGFI value.
134define i64 @f15(i64 %a, i64 *%dest) {
135; CHECK-LABEL: f15:
136; CHECK: msgfi %r2, -2147483647
137; CHECK: br %r14
138  %mul = mul i64 %a, -2147483647
139  ret i64 %mul
140}
141
142; Check the next value down, which should use shifts.
143define i64 @f16(i64 %a, i64 *%dest) {
144; CHECK-LABEL: f16:
145; CHECK: sllg [[SHIFTED:%r[0-5]]], %r2, 31
146; CHECK: lcgr %r2, [[SHIFTED]]
147; CHECK: br %r14
148  %mul = mul i64 %a, -2147483648
149  ret i64 %mul
150}
151
152; Check the next value down again, which cannot use constant multiplication
153define i64 @f17(i64 %a, i64 *%dest) {
154; CHECK-LABEL: f17:
155; CHECK-NOT: msgfi
156; CHECK: br %r14
157  %mul = mul i64 %a, -2147483649
158  ret i64 %mul
159}
160