blob: d9bec9b8ae887dce6ee52c7dddc0439da2a08d94 [file] [log] [blame]
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc < %s -disable-wasm-fallthrough-return-opt -wasm-keep-registers | FileCheck %s
; Test that basic 128-bit integer operations assemble as expected.
target triple = "wasm32-unknown-unknown"
declare i128 @llvm.ctlz.i128(i128, i1)
declare i128 @llvm.cttz.i128(i128, i1)
declare i128 @llvm.ctpop.i128(i128)
define i128 @add128(i128 %x, i128 %y) {
; CHECK-LABEL: add128:
; CHECK: .functype add128 (i32, i64, i64, i64, i64) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get $push8=, 0
; CHECK-NEXT: local.get $push7=, 1
; CHECK-NEXT: local.get $push6=, 3
; CHECK-NEXT: i64.add $push5=, $pop7, $pop6
; CHECK-NEXT: local.tee $push4=, 3, $pop5
; CHECK-NEXT: i64.store 0($pop8), $pop4
; CHECK-NEXT: local.get $push13=, 0
; CHECK-NEXT: local.get $push10=, 2
; CHECK-NEXT: local.get $push9=, 4
; CHECK-NEXT: i64.add $push0=, $pop10, $pop9
; CHECK-NEXT: local.get $push12=, 3
; CHECK-NEXT: local.get $push11=, 1
; CHECK-NEXT: i64.lt_u $push1=, $pop12, $pop11
; CHECK-NEXT: i64.extend_i32_u $push2=, $pop1
; CHECK-NEXT: i64.add $push3=, $pop0, $pop2
; CHECK-NEXT: i64.store 8($pop13), $pop3
; CHECK-NEXT: return
%a = add i128 %x, %y
ret i128 %a
}
define i128 @sub128(i128 %x, i128 %y) {
; CHECK-LABEL: sub128:
; CHECK: .functype sub128 (i32, i64, i64, i64, i64) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get $push7=, 0
; CHECK-NEXT: local.get $push6=, 1
; CHECK-NEXT: local.get $push5=, 3
; CHECK-NEXT: i64.sub $push0=, $pop6, $pop5
; CHECK-NEXT: i64.store 0($pop7), $pop0
; CHECK-NEXT: local.get $push12=, 0
; CHECK-NEXT: local.get $push9=, 2
; CHECK-NEXT: local.get $push8=, 4
; CHECK-NEXT: i64.sub $push1=, $pop9, $pop8
; CHECK-NEXT: local.get $push11=, 1
; CHECK-NEXT: local.get $push10=, 3
; CHECK-NEXT: i64.lt_u $push2=, $pop11, $pop10
; CHECK-NEXT: i64.extend_i32_u $push3=, $pop2
; CHECK-NEXT: i64.sub $push4=, $pop1, $pop3
; CHECK-NEXT: i64.store 8($pop12), $pop4
; CHECK-NEXT: return
%a = sub i128 %x, %y
ret i128 %a
}
define i128 @mul128(i128 %x, i128 %y) {
; CHECK-LABEL: mul128:
; CHECK: .functype mul128 (i32, i64, i64, i64, i64) -> ()
; CHECK-NEXT: .local i32
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: global.get $push2=, __stack_pointer
; CHECK-NEXT: i32.const $push3=, 16
; CHECK-NEXT: i32.sub $push7=, $pop2, $pop3
; CHECK-NEXT: local.tee $push6=, 5, $pop7
; CHECK-NEXT: global.set __stack_pointer, $pop6
; CHECK-NEXT: local.get $push12=, 5
; CHECK-NEXT: local.get $push11=, 1
; CHECK-NEXT: local.get $push10=, 2
; CHECK-NEXT: local.get $push9=, 3
; CHECK-NEXT: local.get $push8=, 4
; CHECK-NEXT: call __multi3, $pop12, $pop11, $pop10, $pop9, $pop8
; CHECK-NEXT: local.get $push14=, 0
; CHECK-NEXT: local.get $push13=, 5
; CHECK-NEXT: i64.load $push0=, 8($pop13)
; CHECK-NEXT: i64.store 8($pop14), $pop0
; CHECK-NEXT: local.get $push16=, 0
; CHECK-NEXT: local.get $push15=, 5
; CHECK-NEXT: i64.load $push1=, 0($pop15)
; CHECK-NEXT: i64.store 0($pop16), $pop1
; CHECK-NEXT: local.get $push17=, 5
; CHECK-NEXT: i32.const $push4=, 16
; CHECK-NEXT: i32.add $push5=, $pop17, $pop4
; CHECK-NEXT: global.set __stack_pointer, $pop5
; CHECK-NEXT: return
%a = mul i128 %x, %y
ret i128 %a
}
define i128 @sdiv128(i128 %x, i128 %y) {
; CHECK-LABEL: sdiv128:
; CHECK: .functype sdiv128 (i32, i64, i64, i64, i64) -> ()
; CHECK-NEXT: .local i32
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: global.get $push2=, __stack_pointer
; CHECK-NEXT: i32.const $push3=, 16
; CHECK-NEXT: i32.sub $push7=, $pop2, $pop3
; CHECK-NEXT: local.tee $push6=, 5, $pop7
; CHECK-NEXT: global.set __stack_pointer, $pop6
; CHECK-NEXT: local.get $push12=, 5
; CHECK-NEXT: local.get $push11=, 1
; CHECK-NEXT: local.get $push10=, 2
; CHECK-NEXT: local.get $push9=, 3
; CHECK-NEXT: local.get $push8=, 4
; CHECK-NEXT: call __divti3, $pop12, $pop11, $pop10, $pop9, $pop8
; CHECK-NEXT: local.get $push14=, 0
; CHECK-NEXT: local.get $push13=, 5
; CHECK-NEXT: i64.load $push0=, 8($pop13)
; CHECK-NEXT: i64.store 8($pop14), $pop0
; CHECK-NEXT: local.get $push16=, 0
; CHECK-NEXT: local.get $push15=, 5
; CHECK-NEXT: i64.load $push1=, 0($pop15)
; CHECK-NEXT: i64.store 0($pop16), $pop1
; CHECK-NEXT: local.get $push17=, 5
; CHECK-NEXT: i32.const $push4=, 16
; CHECK-NEXT: i32.add $push5=, $pop17, $pop4
; CHECK-NEXT: global.set __stack_pointer, $pop5
; CHECK-NEXT: return
%a = sdiv i128 %x, %y
ret i128 %a
}
define i128 @udiv128(i128 %x, i128 %y) {
; CHECK-LABEL: udiv128:
; CHECK: .functype udiv128 (i32, i64, i64, i64, i64) -> ()
; CHECK-NEXT: .local i32
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: global.get $push2=, __stack_pointer
; CHECK-NEXT: i32.const $push3=, 16
; CHECK-NEXT: i32.sub $push7=, $pop2, $pop3
; CHECK-NEXT: local.tee $push6=, 5, $pop7
; CHECK-NEXT: global.set __stack_pointer, $pop6
; CHECK-NEXT: local.get $push12=, 5
; CHECK-NEXT: local.get $push11=, 1
; CHECK-NEXT: local.get $push10=, 2
; CHECK-NEXT: local.get $push9=, 3
; CHECK-NEXT: local.get $push8=, 4
; CHECK-NEXT: call __udivti3, $pop12, $pop11, $pop10, $pop9, $pop8
; CHECK-NEXT: local.get $push14=, 0
; CHECK-NEXT: local.get $push13=, 5
; CHECK-NEXT: i64.load $push0=, 8($pop13)
; CHECK-NEXT: i64.store 8($pop14), $pop0
; CHECK-NEXT: local.get $push16=, 0
; CHECK-NEXT: local.get $push15=, 5
; CHECK-NEXT: i64.load $push1=, 0($pop15)
; CHECK-NEXT: i64.store 0($pop16), $pop1
; CHECK-NEXT: local.get $push17=, 5
; CHECK-NEXT: i32.const $push4=, 16
; CHECK-NEXT: i32.add $push5=, $pop17, $pop4
; CHECK-NEXT: global.set __stack_pointer, $pop5
; CHECK-NEXT: return
%a = udiv i128 %x, %y
ret i128 %a
}
define i128 @srem128(i128 %x, i128 %y) {
; CHECK-LABEL: srem128:
; CHECK: .functype srem128 (i32, i64, i64, i64, i64) -> ()
; CHECK-NEXT: .local i32
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: global.get $push2=, __stack_pointer
; CHECK-NEXT: i32.const $push3=, 16
; CHECK-NEXT: i32.sub $push7=, $pop2, $pop3
; CHECK-NEXT: local.tee $push6=, 5, $pop7
; CHECK-NEXT: global.set __stack_pointer, $pop6
; CHECK-NEXT: local.get $push12=, 5
; CHECK-NEXT: local.get $push11=, 1
; CHECK-NEXT: local.get $push10=, 2
; CHECK-NEXT: local.get $push9=, 3
; CHECK-NEXT: local.get $push8=, 4
; CHECK-NEXT: call __modti3, $pop12, $pop11, $pop10, $pop9, $pop8
; CHECK-NEXT: local.get $push14=, 0
; CHECK-NEXT: local.get $push13=, 5
; CHECK-NEXT: i64.load $push0=, 8($pop13)
; CHECK-NEXT: i64.store 8($pop14), $pop0
; CHECK-NEXT: local.get $push16=, 0
; CHECK-NEXT: local.get $push15=, 5
; CHECK-NEXT: i64.load $push1=, 0($pop15)
; CHECK-NEXT: i64.store 0($pop16), $pop1
; CHECK-NEXT: local.get $push17=, 5
; CHECK-NEXT: i32.const $push4=, 16
; CHECK-NEXT: i32.add $push5=, $pop17, $pop4
; CHECK-NEXT: global.set __stack_pointer, $pop5
; CHECK-NEXT: return
%a = srem i128 %x, %y
ret i128 %a
}
define i128 @urem128(i128 %x, i128 %y) {
; CHECK-LABEL: urem128:
; CHECK: .functype urem128 (i32, i64, i64, i64, i64) -> ()
; CHECK-NEXT: .local i32
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: global.get $push2=, __stack_pointer
; CHECK-NEXT: i32.const $push3=, 16
; CHECK-NEXT: i32.sub $push7=, $pop2, $pop3
; CHECK-NEXT: local.tee $push6=, 5, $pop7
; CHECK-NEXT: global.set __stack_pointer, $pop6
; CHECK-NEXT: local.get $push12=, 5
; CHECK-NEXT: local.get $push11=, 1
; CHECK-NEXT: local.get $push10=, 2
; CHECK-NEXT: local.get $push9=, 3
; CHECK-NEXT: local.get $push8=, 4
; CHECK-NEXT: call __umodti3, $pop12, $pop11, $pop10, $pop9, $pop8
; CHECK-NEXT: local.get $push14=, 0
; CHECK-NEXT: local.get $push13=, 5
; CHECK-NEXT: i64.load $push0=, 8($pop13)
; CHECK-NEXT: i64.store 8($pop14), $pop0
; CHECK-NEXT: local.get $push16=, 0
; CHECK-NEXT: local.get $push15=, 5
; CHECK-NEXT: i64.load $push1=, 0($pop15)
; CHECK-NEXT: i64.store 0($pop16), $pop1
; CHECK-NEXT: local.get $push17=, 5
; CHECK-NEXT: i32.const $push4=, 16
; CHECK-NEXT: i32.add $push5=, $pop17, $pop4
; CHECK-NEXT: global.set __stack_pointer, $pop5
; CHECK-NEXT: return
%a = urem i128 %x, %y
ret i128 %a
}
define i128 @and128(i128 %x, i128 %y) {
; CHECK-LABEL: and128:
; CHECK: .functype and128 (i32, i64, i64, i64, i64) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get $push4=, 0
; CHECK-NEXT: local.get $push3=, 2
; CHECK-NEXT: local.get $push2=, 4
; CHECK-NEXT: i64.and $push0=, $pop3, $pop2
; CHECK-NEXT: i64.store 8($pop4), $pop0
; CHECK-NEXT: local.get $push7=, 0
; CHECK-NEXT: local.get $push6=, 1
; CHECK-NEXT: local.get $push5=, 3
; CHECK-NEXT: i64.and $push1=, $pop6, $pop5
; CHECK-NEXT: i64.store 0($pop7), $pop1
; CHECK-NEXT: return
%a = and i128 %x, %y
ret i128 %a
}
define i128 @or128(i128 %x, i128 %y) {
; CHECK-LABEL: or128:
; CHECK: .functype or128 (i32, i64, i64, i64, i64) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get $push4=, 0
; CHECK-NEXT: local.get $push3=, 2
; CHECK-NEXT: local.get $push2=, 4
; CHECK-NEXT: i64.or $push0=, $pop3, $pop2
; CHECK-NEXT: i64.store 8($pop4), $pop0
; CHECK-NEXT: local.get $push7=, 0
; CHECK-NEXT: local.get $push6=, 1
; CHECK-NEXT: local.get $push5=, 3
; CHECK-NEXT: i64.or $push1=, $pop6, $pop5
; CHECK-NEXT: i64.store 0($pop7), $pop1
; CHECK-NEXT: return
%a = or i128 %x, %y
ret i128 %a
}
define i128 @xor128(i128 %x, i128 %y) {
; CHECK-LABEL: xor128:
; CHECK: .functype xor128 (i32, i64, i64, i64, i64) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get $push4=, 0
; CHECK-NEXT: local.get $push3=, 2
; CHECK-NEXT: local.get $push2=, 4
; CHECK-NEXT: i64.xor $push0=, $pop3, $pop2
; CHECK-NEXT: i64.store 8($pop4), $pop0
; CHECK-NEXT: local.get $push7=, 0
; CHECK-NEXT: local.get $push6=, 1
; CHECK-NEXT: local.get $push5=, 3
; CHECK-NEXT: i64.xor $push1=, $pop6, $pop5
; CHECK-NEXT: i64.store 0($pop7), $pop1
; CHECK-NEXT: return
%a = xor i128 %x, %y
ret i128 %a
}
define i128 @shl128(i128 %x, i128 %y) {
; CHECK-LABEL: shl128:
; CHECK: .functype shl128 (i32, i64, i64, i64, i64) -> ()
; CHECK-NEXT: .local i32
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: global.get $push3=, __stack_pointer
; CHECK-NEXT: i32.const $push4=, 16
; CHECK-NEXT: i32.sub $push8=, $pop3, $pop4
; CHECK-NEXT: local.tee $push7=, 5, $pop8
; CHECK-NEXT: global.set __stack_pointer, $pop7
; CHECK-NEXT: local.get $push12=, 5
; CHECK-NEXT: local.get $push11=, 1
; CHECK-NEXT: local.get $push10=, 2
; CHECK-NEXT: local.get $push9=, 3
; CHECK-NEXT: i32.wrap_i64 $push0=, $pop9
; CHECK-NEXT: call __ashlti3, $pop12, $pop11, $pop10, $pop0
; CHECK-NEXT: local.get $push14=, 0
; CHECK-NEXT: local.get $push13=, 5
; CHECK-NEXT: i64.load $push1=, 8($pop13)
; CHECK-NEXT: i64.store 8($pop14), $pop1
; CHECK-NEXT: local.get $push16=, 0
; CHECK-NEXT: local.get $push15=, 5
; CHECK-NEXT: i64.load $push2=, 0($pop15)
; CHECK-NEXT: i64.store 0($pop16), $pop2
; CHECK-NEXT: local.get $push17=, 5
; CHECK-NEXT: i32.const $push5=, 16
; CHECK-NEXT: i32.add $push6=, $pop17, $pop5
; CHECK-NEXT: global.set __stack_pointer, $pop6
; CHECK-NEXT: return
%a = shl i128 %x, %y
ret i128 %a
}
define i128 @shr128(i128 %x, i128 %y) {
; CHECK-LABEL: shr128:
; CHECK: .functype shr128 (i32, i64, i64, i64, i64) -> ()
; CHECK-NEXT: .local i32
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: global.get $push3=, __stack_pointer
; CHECK-NEXT: i32.const $push4=, 16
; CHECK-NEXT: i32.sub $push8=, $pop3, $pop4
; CHECK-NEXT: local.tee $push7=, 5, $pop8
; CHECK-NEXT: global.set __stack_pointer, $pop7
; CHECK-NEXT: local.get $push12=, 5
; CHECK-NEXT: local.get $push11=, 1
; CHECK-NEXT: local.get $push10=, 2
; CHECK-NEXT: local.get $push9=, 3
; CHECK-NEXT: i32.wrap_i64 $push0=, $pop9
; CHECK-NEXT: call __lshrti3, $pop12, $pop11, $pop10, $pop0
; CHECK-NEXT: local.get $push14=, 0
; CHECK-NEXT: local.get $push13=, 5
; CHECK-NEXT: i64.load $push1=, 8($pop13)
; CHECK-NEXT: i64.store 8($pop14), $pop1
; CHECK-NEXT: local.get $push16=, 0
; CHECK-NEXT: local.get $push15=, 5
; CHECK-NEXT: i64.load $push2=, 0($pop15)
; CHECK-NEXT: i64.store 0($pop16), $pop2
; CHECK-NEXT: local.get $push17=, 5
; CHECK-NEXT: i32.const $push5=, 16
; CHECK-NEXT: i32.add $push6=, $pop17, $pop5
; CHECK-NEXT: global.set __stack_pointer, $pop6
; CHECK-NEXT: return
%a = lshr i128 %x, %y
ret i128 %a
}
define i128 @sar128(i128 %x, i128 %y) {
; CHECK-LABEL: sar128:
; CHECK: .functype sar128 (i32, i64, i64, i64, i64) -> ()
; CHECK-NEXT: .local i32
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: global.get $push3=, __stack_pointer
; CHECK-NEXT: i32.const $push4=, 16
; CHECK-NEXT: i32.sub $push8=, $pop3, $pop4
; CHECK-NEXT: local.tee $push7=, 5, $pop8
; CHECK-NEXT: global.set __stack_pointer, $pop7
; CHECK-NEXT: local.get $push12=, 5
; CHECK-NEXT: local.get $push11=, 1
; CHECK-NEXT: local.get $push10=, 2
; CHECK-NEXT: local.get $push9=, 3
; CHECK-NEXT: i32.wrap_i64 $push0=, $pop9
; CHECK-NEXT: call __ashrti3, $pop12, $pop11, $pop10, $pop0
; CHECK-NEXT: local.get $push14=, 0
; CHECK-NEXT: local.get $push13=, 5
; CHECK-NEXT: i64.load $push1=, 8($pop13)
; CHECK-NEXT: i64.store 8($pop14), $pop1
; CHECK-NEXT: local.get $push16=, 0
; CHECK-NEXT: local.get $push15=, 5
; CHECK-NEXT: i64.load $push2=, 0($pop15)
; CHECK-NEXT: i64.store 0($pop16), $pop2
; CHECK-NEXT: local.get $push17=, 5
; CHECK-NEXT: i32.const $push5=, 16
; CHECK-NEXT: i32.add $push6=, $pop17, $pop5
; CHECK-NEXT: global.set __stack_pointer, $pop6
; CHECK-NEXT: return
%a = ashr i128 %x, %y
ret i128 %a
}
define i128 @clz128(i128 %x) {
; CHECK-LABEL: clz128:
; CHECK: .functype clz128 (i32, i64, i64) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get $push8=, 0
; CHECK-NEXT: i64.const $push0=, 0
; CHECK-NEXT: i64.store 8($pop8), $pop0
; CHECK-NEXT: local.get $push12=, 0
; CHECK-NEXT: local.get $push9=, 2
; CHECK-NEXT: i64.clz $push5=, $pop9
; CHECK-NEXT: local.get $push10=, 1
; CHECK-NEXT: i64.clz $push2=, $pop10
; CHECK-NEXT: i64.const $push3=, 64
; CHECK-NEXT: i64.add $push4=, $pop2, $pop3
; CHECK-NEXT: local.get $push11=, 2
; CHECK-NEXT: i64.const $push7=, 0
; CHECK-NEXT: i64.ne $push1=, $pop11, $pop7
; CHECK-NEXT: i64.select $push6=, $pop5, $pop4, $pop1
; CHECK-NEXT: i64.store 0($pop12), $pop6
; CHECK-NEXT: return
%a = call i128 @llvm.ctlz.i128(i128 %x, i1 false)
ret i128 %a
}
define i128 @clz128_zero_undef(i128 %x) {
; CHECK-LABEL: clz128_zero_undef:
; CHECK: .functype clz128_zero_undef (i32, i64, i64) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get $push8=, 0
; CHECK-NEXT: i64.const $push0=, 0
; CHECK-NEXT: i64.store 8($pop8), $pop0
; CHECK-NEXT: local.get $push12=, 0
; CHECK-NEXT: local.get $push9=, 2
; CHECK-NEXT: i64.clz $push5=, $pop9
; CHECK-NEXT: local.get $push10=, 1
; CHECK-NEXT: i64.clz $push2=, $pop10
; CHECK-NEXT: i64.const $push3=, 64
; CHECK-NEXT: i64.add $push4=, $pop2, $pop3
; CHECK-NEXT: local.get $push11=, 2
; CHECK-NEXT: i64.const $push7=, 0
; CHECK-NEXT: i64.ne $push1=, $pop11, $pop7
; CHECK-NEXT: i64.select $push6=, $pop5, $pop4, $pop1
; CHECK-NEXT: i64.store 0($pop12), $pop6
; CHECK-NEXT: return
%a = call i128 @llvm.ctlz.i128(i128 %x, i1 true)
ret i128 %a
}
define i128 @ctz128(i128 %x) {
; CHECK-LABEL: ctz128:
; CHECK: .functype ctz128 (i32, i64, i64) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get $push8=, 0
; CHECK-NEXT: i64.const $push0=, 0
; CHECK-NEXT: i64.store 8($pop8), $pop0
; CHECK-NEXT: local.get $push12=, 0
; CHECK-NEXT: local.get $push9=, 1
; CHECK-NEXT: i64.ctz $push5=, $pop9
; CHECK-NEXT: local.get $push10=, 2
; CHECK-NEXT: i64.ctz $push2=, $pop10
; CHECK-NEXT: i64.const $push3=, 64
; CHECK-NEXT: i64.add $push4=, $pop2, $pop3
; CHECK-NEXT: local.get $push11=, 1
; CHECK-NEXT: i64.const $push7=, 0
; CHECK-NEXT: i64.ne $push1=, $pop11, $pop7
; CHECK-NEXT: i64.select $push6=, $pop5, $pop4, $pop1
; CHECK-NEXT: i64.store 0($pop12), $pop6
; CHECK-NEXT: return
%a = call i128 @llvm.cttz.i128(i128 %x, i1 false)
ret i128 %a
}
define i128 @ctz128_zero_undef(i128 %x) {
; CHECK-LABEL: ctz128_zero_undef:
; CHECK: .functype ctz128_zero_undef (i32, i64, i64) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get $push8=, 0
; CHECK-NEXT: i64.const $push0=, 0
; CHECK-NEXT: i64.store 8($pop8), $pop0
; CHECK-NEXT: local.get $push12=, 0
; CHECK-NEXT: local.get $push9=, 1
; CHECK-NEXT: i64.ctz $push5=, $pop9
; CHECK-NEXT: local.get $push10=, 2
; CHECK-NEXT: i64.ctz $push2=, $pop10
; CHECK-NEXT: i64.const $push3=, 64
; CHECK-NEXT: i64.add $push4=, $pop2, $pop3
; CHECK-NEXT: local.get $push11=, 1
; CHECK-NEXT: i64.const $push7=, 0
; CHECK-NEXT: i64.ne $push1=, $pop11, $pop7
; CHECK-NEXT: i64.select $push6=, $pop5, $pop4, $pop1
; CHECK-NEXT: i64.store 0($pop12), $pop6
; CHECK-NEXT: return
%a = call i128 @llvm.cttz.i128(i128 %x, i1 true)
ret i128 %a
}
define i128 @popcnt128(i128 %x) {
; CHECK-LABEL: popcnt128:
; CHECK: .functype popcnt128 (i32, i64, i64) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get $push4=, 0
; CHECK-NEXT: i64.const $push0=, 0
; CHECK-NEXT: i64.store 8($pop4), $pop0
; CHECK-NEXT: local.get $push7=, 0
; CHECK-NEXT: local.get $push5=, 1
; CHECK-NEXT: i64.popcnt $push2=, $pop5
; CHECK-NEXT: local.get $push6=, 2
; CHECK-NEXT: i64.popcnt $push1=, $pop6
; CHECK-NEXT: i64.add $push3=, $pop2, $pop1
; CHECK-NEXT: i64.store 0($pop7), $pop3
; CHECK-NEXT: return
%a = call i128 @llvm.ctpop.i128(i128 %x)
ret i128 %a
}
define i32 @eqz128(i128 %x) {
; CHECK-LABEL: eqz128:
; CHECK: .functype eqz128 (i64, i64) -> (i32)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get $push3=, 0
; CHECK-NEXT: local.get $push2=, 1
; CHECK-NEXT: i64.or $push0=, $pop3, $pop2
; CHECK-NEXT: i64.eqz $push1=, $pop0
; CHECK-NEXT: return $pop1
%a = icmp eq i128 %x, 0
%b = zext i1 %a to i32
ret i32 %b
}
define i128 @rotl(i128 %x, i128 %y) {
; CHECK-LABEL: rotl:
; CHECK: .functype rotl (i32, i64, i64, i64, i64) -> ()
; CHECK-NEXT: .local i32, i32
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: global.get $push8=, __stack_pointer
; CHECK-NEXT: i32.const $push9=, 32
; CHECK-NEXT: i32.sub $push17=, $pop8, $pop9
; CHECK-NEXT: local.tee $push16=, 5, $pop17
; CHECK-NEXT: global.set __stack_pointer, $pop16
; CHECK-NEXT: local.get $push18=, 5
; CHECK-NEXT: i32.const $push12=, 16
; CHECK-NEXT: i32.add $push13=, $pop18, $pop12
; CHECK-NEXT: local.get $push21=, 1
; CHECK-NEXT: local.get $push20=, 2
; CHECK-NEXT: local.get $push19=, 3
; CHECK-NEXT: i32.wrap_i64 $push15=, $pop19
; CHECK-NEXT: local.tee $push14=, 6, $pop15
; CHECK-NEXT: call __ashlti3, $pop13, $pop21, $pop20, $pop14
; CHECK-NEXT: local.get $push25=, 5
; CHECK-NEXT: local.get $push24=, 1
; CHECK-NEXT: local.get $push23=, 2
; CHECK-NEXT: i32.const $push0=, 128
; CHECK-NEXT: local.get $push22=, 6
; CHECK-NEXT: i32.sub $push1=, $pop0, $pop22
; CHECK-NEXT: call __lshrti3, $pop25, $pop24, $pop23, $pop1
; CHECK-NEXT: local.get $push28=, 0
; CHECK-NEXT: local.get $push26=, 5
; CHECK-NEXT: i64.load $push2=, 24($pop26)
; CHECK-NEXT: local.get $push27=, 5
; CHECK-NEXT: i64.load $push3=, 8($pop27)
; CHECK-NEXT: i64.or $push4=, $pop2, $pop3
; CHECK-NEXT: i64.store 8($pop28), $pop4
; CHECK-NEXT: local.get $push31=, 0
; CHECK-NEXT: local.get $push29=, 5
; CHECK-NEXT: i64.load $push5=, 16($pop29)
; CHECK-NEXT: local.get $push30=, 5
; CHECK-NEXT: i64.load $push6=, 0($pop30)
; CHECK-NEXT: i64.or $push7=, $pop5, $pop6
; CHECK-NEXT: i64.store 0($pop31), $pop7
; CHECK-NEXT: local.get $push32=, 5
; CHECK-NEXT: i32.const $push10=, 32
; CHECK-NEXT: i32.add $push11=, $pop32, $pop10
; CHECK-NEXT: global.set __stack_pointer, $pop11
; CHECK-NEXT: return
%z = sub i128 128, %y
%b = shl i128 %x, %y
%c = lshr i128 %x, %z
%d = or i128 %b, %c
ret i128 %d
}
define i128 @masked_rotl(i128 %x, i128 %y) {
; CHECK-LABEL: masked_rotl:
; CHECK: .functype masked_rotl (i32, i64, i64, i64, i64) -> ()
; CHECK-NEXT: .local i32, i32
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: global.get $push10=, __stack_pointer
; CHECK-NEXT: i32.const $push11=, 32
; CHECK-NEXT: i32.sub $push19=, $pop10, $pop11
; CHECK-NEXT: local.tee $push18=, 5, $pop19
; CHECK-NEXT: global.set __stack_pointer, $pop18
; CHECK-NEXT: local.get $push20=, 5
; CHECK-NEXT: i32.const $push14=, 16
; CHECK-NEXT: i32.add $push15=, $pop20, $pop14
; CHECK-NEXT: local.get $push23=, 1
; CHECK-NEXT: local.get $push22=, 2
; CHECK-NEXT: local.get $push21=, 3
; CHECK-NEXT: i32.wrap_i64 $push0=, $pop21
; CHECK-NEXT: i32.const $push1=, 127
; CHECK-NEXT: i32.and $push17=, $pop0, $pop1
; CHECK-NEXT: local.tee $push16=, 6, $pop17
; CHECK-NEXT: call __ashlti3, $pop15, $pop23, $pop22, $pop16
; CHECK-NEXT: local.get $push27=, 5
; CHECK-NEXT: local.get $push26=, 1
; CHECK-NEXT: local.get $push25=, 2
; CHECK-NEXT: i32.const $push2=, 128
; CHECK-NEXT: local.get $push24=, 6
; CHECK-NEXT: i32.sub $push3=, $pop2, $pop24
; CHECK-NEXT: call __lshrti3, $pop27, $pop26, $pop25, $pop3
; CHECK-NEXT: local.get $push30=, 0
; CHECK-NEXT: local.get $push28=, 5
; CHECK-NEXT: i64.load $push4=, 24($pop28)
; CHECK-NEXT: local.get $push29=, 5
; CHECK-NEXT: i64.load $push5=, 8($pop29)
; CHECK-NEXT: i64.or $push6=, $pop4, $pop5
; CHECK-NEXT: i64.store 8($pop30), $pop6
; CHECK-NEXT: local.get $push33=, 0
; CHECK-NEXT: local.get $push31=, 5
; CHECK-NEXT: i64.load $push7=, 16($pop31)
; CHECK-NEXT: local.get $push32=, 5
; CHECK-NEXT: i64.load $push8=, 0($pop32)
; CHECK-NEXT: i64.or $push9=, $pop7, $pop8
; CHECK-NEXT: i64.store 0($pop33), $pop9
; CHECK-NEXT: local.get $push34=, 5
; CHECK-NEXT: i32.const $push12=, 32
; CHECK-NEXT: i32.add $push13=, $pop34, $pop12
; CHECK-NEXT: global.set __stack_pointer, $pop13
; CHECK-NEXT: return
%a = and i128 %y, 127
%z = sub i128 128, %a
%b = shl i128 %x, %a
%c = lshr i128 %x, %z
%d = or i128 %b, %c
ret i128 %d
}
define i128 @rotr(i128 %x, i128 %y) {
; CHECK-LABEL: rotr:
; CHECK: .functype rotr (i32, i64, i64, i64, i64) -> ()
; CHECK-NEXT: .local i32, i32
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: global.get $push8=, __stack_pointer
; CHECK-NEXT: i32.const $push9=, 32
; CHECK-NEXT: i32.sub $push17=, $pop8, $pop9
; CHECK-NEXT: local.tee $push16=, 5, $pop17
; CHECK-NEXT: global.set __stack_pointer, $pop16
; CHECK-NEXT: local.get $push18=, 5
; CHECK-NEXT: i32.const $push12=, 16
; CHECK-NEXT: i32.add $push13=, $pop18, $pop12
; CHECK-NEXT: local.get $push21=, 1
; CHECK-NEXT: local.get $push20=, 2
; CHECK-NEXT: local.get $push19=, 3
; CHECK-NEXT: i32.wrap_i64 $push15=, $pop19
; CHECK-NEXT: local.tee $push14=, 6, $pop15
; CHECK-NEXT: call __lshrti3, $pop13, $pop21, $pop20, $pop14
; CHECK-NEXT: local.get $push25=, 5
; CHECK-NEXT: local.get $push24=, 1
; CHECK-NEXT: local.get $push23=, 2
; CHECK-NEXT: i32.const $push0=, 128
; CHECK-NEXT: local.get $push22=, 6
; CHECK-NEXT: i32.sub $push1=, $pop0, $pop22
; CHECK-NEXT: call __ashlti3, $pop25, $pop24, $pop23, $pop1
; CHECK-NEXT: local.get $push28=, 0
; CHECK-NEXT: local.get $push26=, 5
; CHECK-NEXT: i64.load $push2=, 24($pop26)
; CHECK-NEXT: local.get $push27=, 5
; CHECK-NEXT: i64.load $push3=, 8($pop27)
; CHECK-NEXT: i64.or $push4=, $pop2, $pop3
; CHECK-NEXT: i64.store 8($pop28), $pop4
; CHECK-NEXT: local.get $push31=, 0
; CHECK-NEXT: local.get $push29=, 5
; CHECK-NEXT: i64.load $push5=, 16($pop29)
; CHECK-NEXT: local.get $push30=, 5
; CHECK-NEXT: i64.load $push6=, 0($pop30)
; CHECK-NEXT: i64.or $push7=, $pop5, $pop6
; CHECK-NEXT: i64.store 0($pop31), $pop7
; CHECK-NEXT: local.get $push32=, 5
; CHECK-NEXT: i32.const $push10=, 32
; CHECK-NEXT: i32.add $push11=, $pop32, $pop10
; CHECK-NEXT: global.set __stack_pointer, $pop11
; CHECK-NEXT: return
%z = sub i128 128, %y
%b = lshr i128 %x, %y
%c = shl i128 %x, %z
%d = or i128 %b, %c
ret i128 %d
}
define i128 @masked_rotr(i128 %x, i128 %y) {
; CHECK-LABEL: masked_rotr:
; CHECK: .functype masked_rotr (i32, i64, i64, i64, i64) -> ()
; CHECK-NEXT: .local i32, i32
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: global.get $push10=, __stack_pointer
; CHECK-NEXT: i32.const $push11=, 32
; CHECK-NEXT: i32.sub $push19=, $pop10, $pop11
; CHECK-NEXT: local.tee $push18=, 5, $pop19
; CHECK-NEXT: global.set __stack_pointer, $pop18
; CHECK-NEXT: local.get $push20=, 5
; CHECK-NEXT: i32.const $push14=, 16
; CHECK-NEXT: i32.add $push15=, $pop20, $pop14
; CHECK-NEXT: local.get $push23=, 1
; CHECK-NEXT: local.get $push22=, 2
; CHECK-NEXT: local.get $push21=, 3
; CHECK-NEXT: i32.wrap_i64 $push0=, $pop21
; CHECK-NEXT: i32.const $push1=, 127
; CHECK-NEXT: i32.and $push17=, $pop0, $pop1
; CHECK-NEXT: local.tee $push16=, 6, $pop17
; CHECK-NEXT: call __lshrti3, $pop15, $pop23, $pop22, $pop16
; CHECK-NEXT: local.get $push27=, 5
; CHECK-NEXT: local.get $push26=, 1
; CHECK-NEXT: local.get $push25=, 2
; CHECK-NEXT: i32.const $push2=, 128
; CHECK-NEXT: local.get $push24=, 6
; CHECK-NEXT: i32.sub $push3=, $pop2, $pop24
; CHECK-NEXT: call __ashlti3, $pop27, $pop26, $pop25, $pop3
; CHECK-NEXT: local.get $push30=, 0
; CHECK-NEXT: local.get $push28=, 5
; CHECK-NEXT: i64.load $push4=, 24($pop28)
; CHECK-NEXT: local.get $push29=, 5
; CHECK-NEXT: i64.load $push5=, 8($pop29)
; CHECK-NEXT: i64.or $push6=, $pop4, $pop5
; CHECK-NEXT: i64.store 8($pop30), $pop6
; CHECK-NEXT: local.get $push33=, 0
; CHECK-NEXT: local.get $push31=, 5
; CHECK-NEXT: i64.load $push7=, 16($pop31)
; CHECK-NEXT: local.get $push32=, 5
; CHECK-NEXT: i64.load $push8=, 0($pop32)
; CHECK-NEXT: i64.or $push9=, $pop7, $pop8
; CHECK-NEXT: i64.store 0($pop33), $pop9
; CHECK-NEXT: local.get $push34=, 5
; CHECK-NEXT: i32.const $push12=, 32
; CHECK-NEXT: i32.add $push13=, $pop34, $pop12
; CHECK-NEXT: global.set __stack_pointer, $pop13
; CHECK-NEXT: return
%a = and i128 %y, 127
%z = sub i128 128, %a
%b = lshr i128 %x, %a
%c = shl i128 %x, %z
%d = or i128 %b, %c
ret i128 %d
}