[InstCombine] Signed saturation patterns
[llvm-complete.git] / test / CodeGen / WebAssembly / i128.ll
blob1c6c132d50fdb3996142ea9a9165b7cec811b9bb
1 ; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-keep-registers | FileCheck %s
3 ; Test that basic 128-bit integer operations assemble as expected.
5 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
6 target triple = "wasm32-unknown-unknown"
8 declare i128 @llvm.ctlz.i128(i128, i1)
9 declare i128 @llvm.cttz.i128(i128, i1)
10 declare i128 @llvm.ctpop.i128(i128)
12 ; CHECK-LABEL: add128:
13 ; CHECK-NEXT: .functype add128 (i32, i64, i64, i64, i64) -> (){{$}}
14 ; CHECK-NOT:  .result
15 ; CHECK:      i64.add
16 ; CHECK:      i64.store
17 ; CHECK:      i64.add
18 ; CHECK:      i64.store
19 ; CHECK-NEXT: return{{$}}
20 define i128 @add128(i128 %x, i128 %y) {
21   %a = add i128 %x, %y
22   ret i128 %a
25 ; CHECK-LABEL: sub128:
26 ; CHECK-NEXT: .functype sub128 (i32, i64, i64, i64, i64) -> (){{$}}
27 ; CHECK:      i64.sub
28 ; CHECK:      i64.store
29 ; CHECK:      i64.sub
30 ; CHECK:      i64.store
31 ; CHECK-NEXT: return{{$}}
32 define i128 @sub128(i128 %x, i128 %y) {
33   %a = sub i128 %x, %y
34   ret i128 %a
37 ; CHECK-LABEL: mul128:
38 ; CHECK-NEXT: .functype mul128 (i32, i64, i64, i64, i64) -> (){{$}}
39 ; CHECK: call __multi3, ${{.+}}, ${{.+}}, ${{.+}}, ${{.+}}, ${{.+}}{{$}}
40 ; CHECK: return{{$}}
41 define i128 @mul128(i128 %x, i128 %y) {
42   %a = mul i128 %x, %y
43   ret i128 %a
46 ; CHECK-LABEL: sdiv128:
47 ; CHECK-NEXT: .functype sdiv128 (i32, i64, i64, i64, i64) -> (){{$}}
48 ; CHECK: call __divti3, ${{.+}}, ${{.+}}, ${{.+}}, ${{.+}}, ${{.+}}{{$}}
49 ; CHECK: return{{$}}
50 define i128 @sdiv128(i128 %x, i128 %y) {
51   %a = sdiv i128 %x, %y
52   ret i128 %a
55 ; CHECK-LABEL: udiv128:
56 ; CHECK-NEXT: .functype udiv128 (i32, i64, i64, i64, i64) -> (){{$}}
57 ; CHECK: call __udivti3, ${{.+}}, ${{.+}}, ${{.+}}, ${{.+}}, ${{.+}}{{$}}
58 ; CHECK: return{{$}}
59 define i128 @udiv128(i128 %x, i128 %y) {
60   %a = udiv i128 %x, %y
61   ret i128 %a
64 ; CHECK-LABEL: srem128:
65 ; CHECK-NEXT: .functype srem128 (i32, i64, i64, i64, i64) -> (){{$}}
66 ; CHECK: call __modti3, ${{.+}}, ${{.+}}, ${{.+}}, ${{.+}}, ${{.+}}{{$}}
67 ; CHECK: return{{$}}
68 define i128 @srem128(i128 %x, i128 %y) {
69   %a = srem i128 %x, %y
70   ret i128 %a
73 ; CHECK-LABEL: urem128:
74 ; CHECK-NEXT: .functype urem128 (i32, i64, i64, i64, i64) -> (){{$}}
75 ; CHECK: call __umodti3, ${{.+}}, ${{.+}}, ${{.+}}, ${{.+}}, ${{.+}}{{$}}
76 ; CHECK: return{{$}}
77 define i128 @urem128(i128 %x, i128 %y) {
78   %a = urem i128 %x, %y
79   ret i128 %a
82 ; CHECK-LABEL: and128:
83 ; CHECK-NEXT: .functype and128 (i32, i64, i64, i64, i64) -> (){{$}}
84 ; CHECK-NOT:  .result
85 ; CHECK:      i64.and
86 ; CHECK:      i64.store
87 ; CHECK:      i64.and
88 ; CHECK:      i64.store
89 ; CHECK-NEXT: return{{$}}
90 define i128 @and128(i128 %x, i128 %y) {
91   %a = and i128 %x, %y
92   ret i128 %a
95 ; CHECK-LABEL: or128:
96 ; CHECK-NEXT: .functype or128 (i32, i64, i64, i64, i64) -> (){{$}}
97 ; CHECK:      i64.or
98 ; CHECK:      i64.store
99 ; CHECK:      i64.or
100 ; CHECK:      i64.store
101 ; CHECK-NEXT: return{{$}}
102 define i128 @or128(i128 %x, i128 %y) {
103   %a = or i128 %x, %y
104   ret i128 %a
107 ; CHECK-LABEL: xor128:
108 ; CHECK-NEXT: .functype xor128 (i32, i64, i64, i64, i64) -> (){{$}}
109 ; CHECK:      i64.xor
110 ; CHECK:      i64.store
111 ; CHECK:      i64.xor
112 ; CHECK:      i64.store
113 ; CHECK-NEXT: return{{$}}
114 define i128 @xor128(i128 %x, i128 %y) {
115   %a = xor i128 %x, %y
116   ret i128 %a
119 ; CHECK-LABEL: shl128:
120 ; CHECK-NEXT: .functype shl128 (i32, i64, i64, i64, i64) -> (){{$}}
121 ; CHECK: call __ashlti3, ${{.+}}, ${{.+}}, ${{.+}}, ${{.+}}{{$}}
122 ; CHECK: return{{$}}
123 define i128 @shl128(i128 %x, i128 %y) {
124   %a = shl i128 %x, %y
125   ret i128 %a
128 ; CHECK-LABEL: shr128:
129 ; CHECK-NEXT: .functype shr128 (i32, i64, i64, i64, i64) -> (){{$}}
130 ; CHECK: call __lshrti3, ${{.+}}, ${{.+}}, ${{.+}}, ${{.+}}{{$}}
131 ; CHECK: return{{$}}
132 define i128 @shr128(i128 %x, i128 %y) {
133   %a = lshr i128 %x, %y
134   ret i128 %a
137 ; CHECK-LABEL: sar128:
138 ; CHECK-NEXT: .functype sar128 (i32, i64, i64, i64, i64) -> (){{$}}
139 ; CHECK: call __ashrti3, ${{.+}}, ${{.+}}, ${{.+}}, ${{.+}}{{$}}
140 ; CHECK: return{{$}}
141 define i128 @sar128(i128 %x, i128 %y) {
142   %a = ashr i128 %x, %y
143   ret i128 %a
146 ; CHECK-LABEL: clz128:
147 ; CHECK-NEXT: .functype clz128 (i32, i64, i64) -> (){{$}}
148 ; CHECK-NOT:  .result
149 ; CHECK:      i64.clz
150 ; CHECK:      i64.clz
151 ; CHECK:      return{{$}}
152 define i128 @clz128(i128 %x) {
153   %a = call i128 @llvm.ctlz.i128(i128 %x, i1 false)
154   ret i128 %a
157 ; CHECK-LABEL: clz128_zero_undef:
158 ; CHECK-NEXT: .functype clz128_zero_undef (i32, i64, i64) -> (){{$}}
159 ; CHECK:      i64.clz
160 ; CHECK:      i64.clz
161 ; CHECK:      return{{$}}
162 define i128 @clz128_zero_undef(i128 %x) {
163   %a = call i128 @llvm.ctlz.i128(i128 %x, i1 true)
164   ret i128 %a
167 ; CHECK-LABEL: ctz128:
168 ; CHECK-NEXT: .functype ctz128 (i32, i64, i64) -> (){{$}}
169 ; CHECK:      i64.ctz
170 ; CHECK:      i64.ctz
171 ; CHECK:      return{{$}}
172 define i128 @ctz128(i128 %x) {
173   %a = call i128 @llvm.cttz.i128(i128 %x, i1 false)
174   ret i128 %a
177 ; CHECK-LABEL: ctz128_zero_undef:
178 ; CHECK-NEXT: .functype ctz128_zero_undef (i32, i64, i64) -> (){{$}}
179 ; CHECK:      i64.ctz
180 ; CHECK:      i64.ctz
181 ; CHECK:      return{{$}}
182 define i128 @ctz128_zero_undef(i128 %x) {
183   %a = call i128 @llvm.cttz.i128(i128 %x, i1 true)
184   ret i128 %a
187 ; CHECK-LABEL: popcnt128:
188 ; CHECK-NEXT: .functype popcnt128 (i32, i64, i64) -> (){{$}}
189 ; CHECK:      i64.popcnt
190 ; CHECK:      i64.popcnt
191 ; CHECK:      return{{$}}
192 define i128 @popcnt128(i128 %x) {
193   %a = call i128 @llvm.ctpop.i128(i128 %x)
194   ret i128 %a
197 ; CHECK-LABEL: eqz128:
198 ; CHECK-NEXT: .functype eqz128 (i64, i64) -> (i32){{$}}
199 ; CHECK:     i64.or
200 ; CHECK:     i64.eqz
201 ; CHECK:     return $
202 define i32 @eqz128(i128 %x) {
203   %a = icmp eq i128 %x, 0
204   %b = zext i1 %a to i32
205   ret i32 %b
208 ; CHECK-LABEL: rotl:
209 ; CHECK-NEXT: .functype rotl (i32, i64, i64, i64, i64) -> (){{$}}
210 ; CHECK: call __ashlti3, ${{.+}}, ${{.+}}, ${{.+}}, ${{.+}}{{$}}
211 ; CHECK: call __lshrti3, ${{.+}}, ${{.+}}, ${{.+}}, ${{.+}}{{$}}
212 ; CHECK: return{{$}}
213 define i128 @rotl(i128 %x, i128 %y) {
214   %z = sub i128 128, %y
215   %b = shl i128 %x, %y
216   %c = lshr i128 %x, %z
217   %d = or i128 %b, %c
218   ret i128 %d
221 ; CHECK-LABEL: masked_rotl:
222 ; CHECK-NEXT: .functype masked_rotl (i32, i64, i64, i64, i64) -> (){{$}}
223 ; CHECK: call __ashlti3, ${{.+}}, ${{.+}}, ${{.+}}, ${{.+}}{{$}}
224 ; CHECK: call __lshrti3, ${{.+}}, ${{.+}}, ${{.+}}, ${{.+}}{{$}}
225 ; CHECK: return{{$}}
226 define i128 @masked_rotl(i128 %x, i128 %y) {
227   %a = and i128 %y, 127
228   %z = sub i128 128, %a
229   %b = shl i128 %x, %a
230   %c = lshr i128 %x, %z
231   %d = or i128 %b, %c
232   ret i128 %d
235 ; CHECK-LABEL: rotr:
236 ; CHECK-NEXT: .functype rotr (i32, i64, i64, i64, i64) -> (){{$}}
237 ; CHECK: call __lshrti3, ${{.+}}, ${{.+}}, ${{.+}}, ${{.+}}{{$}}
238 ; CHECK: call __ashlti3, ${{.+}}, ${{.+}}, ${{.+}}, ${{.+}}{{$}}
239 ; CHECK: return{{$}}
240 define i128 @rotr(i128 %x, i128 %y) {
241   %z = sub i128 128, %y
242   %b = lshr i128 %x, %y
243   %c = shl i128 %x, %z
244   %d = or i128 %b, %c
245   ret i128 %d
248 ; CHECK-LABEL: masked_rotr:
249 ; CHECK-NEXT: .functype masked_rotr (i32, i64, i64, i64, i64) -> (){{$}}
250 ; CHECK: call __lshrti3, ${{.+}}, ${{.+}}, ${{.+}}, ${{.+}}{{$}}
251 ; CHECK: call __ashlti3, ${{.+}}, ${{.+}}, ${{.+}}, ${{.+}}{{$}}
252 ; CHECK: return{{$}}
253 define i128 @masked_rotr(i128 %x, i128 %y) {
254   %a = and i128 %y, 127
255   %z = sub i128 128, %a
256   %b = lshr i128 %x, %a
257   %c = shl i128 %x, %z
258   %d = or i128 %b, %c
259   ret i128 %d