1 ; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | 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: .param i32, i64, i64, i64, i64{{$}}
19 ; CHECK-NEXT: return{{$}}
20 define i128 @add128(i128 %x, i128 %y) {
25 ; CHECK-LABEL: sub128:
26 ; CHECK-NEXT: .param i32, i64, i64, i64, i64{{$}}
32 ; CHECK-NEXT: return{{$}}
33 define i128 @sub128(i128 %x, i128 %y) {
38 ; CHECK-LABEL: mul128:
39 ; CHECK-NEXT: .param i32, i64, i64, i64, i64{{$}}
41 ; CHECK: call __multi3@FUNCTION, ${{.+}}, ${{.+}}, ${{.+}}, ${{.+}}, ${{.+}}{{$}}
43 define i128 @mul128(i128 %x, i128 %y) {
48 ; CHECK-LABEL: sdiv128:
49 ; CHECK-NEXT: .param i32, i64, i64, i64, i64{{$}}
51 ; CHECK: call __divti3@FUNCTION, ${{.+}}, ${{.+}}, ${{.+}}, ${{.+}}, ${{.+}}{{$}}
53 define i128 @sdiv128(i128 %x, i128 %y) {
58 ; CHECK-LABEL: udiv128:
59 ; CHECK-NEXT: .param i32, i64, i64, i64, i64{{$}}
61 ; CHECK: call __udivti3@FUNCTION, ${{.+}}, ${{.+}}, ${{.+}}, ${{.+}}, ${{.+}}{{$}}
63 define i128 @udiv128(i128 %x, i128 %y) {
68 ; CHECK-LABEL: srem128:
69 ; CHECK-NEXT: .param i32, i64, i64, i64, i64{{$}}
71 ; CHECK: call __modti3@FUNCTION, ${{.+}}, ${{.+}}, ${{.+}}, ${{.+}}, ${{.+}}{{$}}
73 define i128 @srem128(i128 %x, i128 %y) {
78 ; CHECK-LABEL: urem128:
79 ; CHECK-NEXT: .param i32, i64, i64, i64, i64{{$}}
81 ; CHECK: call __umodti3@FUNCTION, ${{.+}}, ${{.+}}, ${{.+}}, ${{.+}}, ${{.+}}{{$}}
83 define i128 @urem128(i128 %x, i128 %y) {
88 ; CHECK-LABEL: and128:
89 ; CHECK-NEXT: .param i32, i64, i64, i64, i64{{$}}
95 ; CHECK-NEXT: return{{$}}
96 define i128 @and128(i128 %x, i128 %y) {
101 ; CHECK-LABEL: or128:
102 ; CHECK-NEXT: .param i32, i64, i64, i64, i64{{$}}
108 ; CHECK-NEXT: return{{$}}
109 define i128 @or128(i128 %x, i128 %y) {
114 ; CHECK-LABEL: xor128:
115 ; CHECK-NEXT: .param i32, i64, i64, i64, i64{{$}}
121 ; CHECK-NEXT: return{{$}}
122 define i128 @xor128(i128 %x, i128 %y) {
127 ; CHECK-LABEL: shl128:
128 ; CHECK-NEXT: .param i32, i64, i64, i64, i64{{$}}
130 ; CHECK: call __ashlti3@FUNCTION, ${{.+}}, ${{.+}}, ${{.+}}, ${{.+}}{{$}}
132 define i128 @shl128(i128 %x, i128 %y) {
137 ; CHECK-LABEL: shr128:
138 ; CHECK-NEXT: .param i32, i64, i64, i64, i64{{$}}
140 ; CHECK: call __lshrti3@FUNCTION, ${{.+}}, ${{.+}}, ${{.+}}, ${{.+}}{{$}}
142 define i128 @shr128(i128 %x, i128 %y) {
143 %a = lshr i128 %x, %y
147 ; CHECK-LABEL: sar128:
148 ; CHECK-NEXT: .param i32, i64, i64, i64, i64{{$}}
150 ; CHECK: call __ashrti3@FUNCTION, ${{.+}}, ${{.+}}, ${{.+}}, ${{.+}}{{$}}
152 define i128 @sar128(i128 %x, i128 %y) {
153 %a = ashr i128 %x, %y
157 ; CHECK-LABEL: clz128:
158 ; CHECK-NEXT: .param i32, i64, i64{{$}}
163 define i128 @clz128(i128 %x) {
164 %a = call i128 @llvm.ctlz.i128(i128 %x, i1 false)
168 ; CHECK-LABEL: clz128_zero_undef:
169 ; CHECK-NEXT: .param i32, i64, i64{{$}}
174 define i128 @clz128_zero_undef(i128 %x) {
175 %a = call i128 @llvm.ctlz.i128(i128 %x, i1 true)
179 ; CHECK-LABEL: ctz128:
180 ; CHECK-NEXT: .param i32, i64, i64{{$}}
185 define i128 @ctz128(i128 %x) {
186 %a = call i128 @llvm.cttz.i128(i128 %x, i1 false)
190 ; CHECK-LABEL: ctz128_zero_undef:
191 ; CHECK-NEXT: .param i32, i64, i64{{$}}
196 define i128 @ctz128_zero_undef(i128 %x) {
197 %a = call i128 @llvm.cttz.i128(i128 %x, i1 true)
201 ; CHECK-LABEL: popcnt128:
202 ; CHECK-NEXT: .param i32, i64, i64{{$}}
207 define i128 @popcnt128(i128 %x) {
208 %a = call i128 @llvm.ctpop.i128(i128 %x)
212 ; CHECK-LABEL: eqz128:
213 ; CHECK-NEXT: .param i64, i64{{$}}
214 ; CHECK-NEXT: .result i32{{$}}
218 define i32 @eqz128(i128 %x) {
219 %a = icmp eq i128 %x, 0
220 %b = zext i1 %a to i32
225 ; CHECK-NEXT: .param i32, i64, i64, i64, i64{{$}}
227 ; CHECK: call __ashlti3@FUNCTION, ${{.+}}, ${{.+}}, ${{.+}}, ${{.+}}{{$}}
228 ; CHECK: call __lshrti3@FUNCTION, ${{.+}}, ${{.+}}, ${{.+}}, ${{.+}}{{$}}
230 define i128 @rotl(i128 %x, i128 %y) {
231 %z = sub i128 128, %y
233 %c = lshr i128 %x, %z
238 ; CHECK-LABEL: masked_rotl:
239 ; CHECK-NEXT: .param i32, i64, i64, i64, i64{{$}}
241 ; CHECK: call __ashlti3@FUNCTION, ${{.+}}, ${{.+}}, ${{.+}}, ${{.+}}{{$}}
242 ; CHECK: call __lshrti3@FUNCTION, ${{.+}}, ${{.+}}, ${{.+}}, ${{.+}}{{$}}
244 define i128 @masked_rotl(i128 %x, i128 %y) {
245 %a = and i128 %y, 127
246 %z = sub i128 128, %a
248 %c = lshr i128 %x, %z
254 ; CHECK-NEXT: .param i32, i64, i64, i64, i64{{$}}
256 ; CHECK: call __lshrti3@FUNCTION, ${{.+}}, ${{.+}}, ${{.+}}, ${{.+}}{{$}}
257 ; CHECK: call __ashlti3@FUNCTION, ${{.+}}, ${{.+}}, ${{.+}}, ${{.+}}{{$}}
259 define i128 @rotr(i128 %x, i128 %y) {
260 %z = sub i128 128, %y
261 %b = lshr i128 %x, %y
267 ; CHECK-LABEL: masked_rotr:
268 ; CHECK-NEXT: .param i32, i64, i64, i64, i64{{$}}
270 ; CHECK: call __lshrti3@FUNCTION, ${{.+}}, ${{.+}}, ${{.+}}, ${{.+}}{{$}}
271 ; CHECK: call __ashlti3@FUNCTION, ${{.+}}, ${{.+}}, ${{.+}}, ${{.+}}{{$}}
273 define i128 @masked_rotr(i128 %x, i128 %y) {
274 %a = and i128 %y, 127
275 %z = sub i128 128, %a
276 %b = lshr i128 %x, %a