Dan Gohman e665e781dc
[SelectionDAG] Use the nuw flag when expanding loads. (#119288)
When expanding a load into two loads, use nuw for the add that computes
the offset from the base of the second load, because the original load
doesn't straddle the address space.

It turns out there's already a dedicated helper function for doing this,
`getObjectPtrOffset`.

This is in target-independent code, however in practice it only seems to
affact WebAssembly code, because WebAssembly load and store
instructions' constant offsets don't perform wrapping, so constant
folding often depends on the nuw flag being present.

This was noticed in the development of #119204.
2024-12-10 06:28:09 -08:00

1766 lines
56 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc < %s -mtriple=wasm32-unknown-unknown -mattr=+simd128,+nontrapping-fptoint | FileCheck %s
; i32 saturate
define i32 @stest_f64i32(double %x) {
; CHECK-LABEL: stest_f64i32:
; CHECK: .functype stest_f64i32 (f64) -> (i32)
; CHECK-NEXT: # %bb.0: # %entry
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.trunc_sat_f64_s
; CHECK-NEXT: # fallthrough-return
entry:
%conv = fptosi double %x to i64
%0 = icmp slt i64 %conv, 2147483647
%spec.store.select = select i1 %0, i64 %conv, i64 2147483647
%1 = icmp sgt i64 %spec.store.select, -2147483648
%spec.store.select7 = select i1 %1, i64 %spec.store.select, i64 -2147483648
%conv6 = trunc i64 %spec.store.select7 to i32
ret i32 %conv6
}
define i32 @utest_f64i32(double %x) {
; CHECK-LABEL: utest_f64i32:
; CHECK: .functype utest_f64i32 (f64) -> (i32)
; CHECK-NEXT: # %bb.0: # %entry
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.trunc_sat_f64_u
; CHECK-NEXT: # fallthrough-return
entry:
%conv = fptoui double %x to i64
%0 = icmp ult i64 %conv, 4294967295
%spec.store.select = select i1 %0, i64 %conv, i64 4294967295
%conv6 = trunc i64 %spec.store.select to i32
ret i32 %conv6
}
define i32 @ustest_f64i32(double %x) {
; CHECK-LABEL: ustest_f64i32:
; CHECK: .functype ustest_f64i32 (f64) -> (i32)
; CHECK-NEXT: # %bb.0: # %entry
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.trunc_sat_f64_u
; CHECK-NEXT: # fallthrough-return
entry:
%conv = fptosi double %x to i64
%0 = icmp slt i64 %conv, 4294967295
%spec.store.select = select i1 %0, i64 %conv, i64 4294967295
%1 = icmp sgt i64 %spec.store.select, 0
%spec.store.select7 = select i1 %1, i64 %spec.store.select, i64 0
%conv6 = trunc i64 %spec.store.select7 to i32
ret i32 %conv6
}
define i32 @stest_f32i32(float %x) {
; CHECK-LABEL: stest_f32i32:
; CHECK: .functype stest_f32i32 (f32) -> (i32)
; CHECK-NEXT: # %bb.0: # %entry
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.trunc_sat_f32_s
; CHECK-NEXT: # fallthrough-return
entry:
%conv = fptosi float %x to i64
%0 = icmp slt i64 %conv, 2147483647
%spec.store.select = select i1 %0, i64 %conv, i64 2147483647
%1 = icmp sgt i64 %spec.store.select, -2147483648
%spec.store.select7 = select i1 %1, i64 %spec.store.select, i64 -2147483648
%conv6 = trunc i64 %spec.store.select7 to i32
ret i32 %conv6
}
define i32 @utest_f32i32(float %x) {
; CHECK-LABEL: utest_f32i32:
; CHECK: .functype utest_f32i32 (f32) -> (i32)
; CHECK-NEXT: # %bb.0: # %entry
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.trunc_sat_f32_u
; CHECK-NEXT: # fallthrough-return
entry:
%conv = fptoui float %x to i64
%0 = icmp ult i64 %conv, 4294967295
%spec.store.select = select i1 %0, i64 %conv, i64 4294967295
%conv6 = trunc i64 %spec.store.select to i32
ret i32 %conv6
}
define i32 @ustest_f32i32(float %x) {
; CHECK-LABEL: ustest_f32i32:
; CHECK: .functype ustest_f32i32 (f32) -> (i32)
; CHECK-NEXT: # %bb.0: # %entry
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.trunc_sat_f32_u
; CHECK-NEXT: # fallthrough-return
entry:
%conv = fptosi float %x to i64
%0 = icmp slt i64 %conv, 4294967295
%spec.store.select = select i1 %0, i64 %conv, i64 4294967295
%1 = icmp sgt i64 %spec.store.select, 0
%spec.store.select7 = select i1 %1, i64 %spec.store.select, i64 0
%conv6 = trunc i64 %spec.store.select7 to i32
ret i32 %conv6
}
define i32 @stest_f16i32(half %x) {
; CHECK-LABEL: stest_f16i32:
; CHECK: .functype stest_f16i32 (f32) -> (i32)
; CHECK-NEXT: # %bb.0: # %entry
; CHECK-NEXT: local.get 0
; CHECK-NEXT: call __truncsfhf2
; CHECK-NEXT: call __extendhfsf2
; CHECK-NEXT: i32.trunc_sat_f32_s
; CHECK-NEXT: # fallthrough-return
entry:
%conv = fptosi half %x to i64
%0 = icmp slt i64 %conv, 2147483647
%spec.store.select = select i1 %0, i64 %conv, i64 2147483647
%1 = icmp sgt i64 %spec.store.select, -2147483648
%spec.store.select7 = select i1 %1, i64 %spec.store.select, i64 -2147483648
%conv6 = trunc i64 %spec.store.select7 to i32
ret i32 %conv6
}
define i32 @stest_f16i32_cse(half %x) {
; CHECK-LABEL: stest_f16i32_cse:
; CHECK: .functype stest_f16i32_cse (f32) -> (i32)
; CHECK-NEXT: # %bb.0: # %entry
; CHECK-NEXT: local.get 0
; CHECK-NEXT: call __truncsfhf2
; CHECK-NEXT: call __extendhfsf2
; CHECK-NEXT: i64.trunc_sat_f32_s
; CHECK-NEXT: i32.wrap_i64
; CHECK-NEXT: # fallthrough-return
entry:
%conv = fptosi half %x to i64
%conv6 = trunc i64 %conv to i32
ret i32 %conv6
}
define i32 @utesth_f16i32(half %x) {
; CHECK-LABEL: utesth_f16i32:
; CHECK: .functype utesth_f16i32 (f32) -> (i32)
; CHECK-NEXT: # %bb.0: # %entry
; CHECK-NEXT: local.get 0
; CHECK-NEXT: call __truncsfhf2
; CHECK-NEXT: call __extendhfsf2
; CHECK-NEXT: i32.trunc_sat_f32_u
; CHECK-NEXT: # fallthrough-return
entry:
%conv = fptoui half %x to i64
%0 = icmp ult i64 %conv, 4294967295
%spec.store.select = select i1 %0, i64 %conv, i64 4294967295
%conv6 = trunc i64 %spec.store.select to i32
ret i32 %conv6
}
define i32 @utesth_f16i32_cse(half %x) {
; CHECK-LABEL: utesth_f16i32_cse:
; CHECK: .functype utesth_f16i32_cse (f32) -> (i32)
; CHECK-NEXT: # %bb.0: # %entry
; CHECK-NEXT: local.get 0
; CHECK-NEXT: call __truncsfhf2
; CHECK-NEXT: call __extendhfsf2
; CHECK-NEXT: i64.trunc_sat_f32_u
; CHECK-NEXT: i32.wrap_i64
; CHECK-NEXT: # fallthrough-return
entry:
%conv = fptoui half %x to i64
%conv6 = trunc i64 %conv to i32
ret i32 %conv6
}
define i32 @ustest_f16i32(half %x) {
; CHECK-LABEL: ustest_f16i32:
; CHECK: .functype ustest_f16i32 (f32) -> (i32)
; CHECK-NEXT: # %bb.0: # %entry
; CHECK-NEXT: local.get 0
; CHECK-NEXT: call __truncsfhf2
; CHECK-NEXT: call __extendhfsf2
; CHECK-NEXT: i32.trunc_sat_f32_u
; CHECK-NEXT: # fallthrough-return
entry:
%conv = fptosi half %x to i64
%0 = icmp slt i64 %conv, 4294967295
%spec.store.select = select i1 %0, i64 %conv, i64 4294967295
%1 = icmp sgt i64 %spec.store.select, 0
%spec.store.select7 = select i1 %1, i64 %spec.store.select, i64 0
%conv6 = trunc i64 %spec.store.select7 to i32
ret i32 %conv6
}
define i32 @ustest_f16i32_cse(half %x) {
; CHECK-LABEL: ustest_f16i32_cse:
; CHECK: .functype ustest_f16i32_cse (f32) -> (i32)
; CHECK-NEXT: # %bb.0: # %entry
; CHECK-NEXT: local.get 0
; CHECK-NEXT: call __truncsfhf2
; CHECK-NEXT: call __extendhfsf2
; CHECK-NEXT: i32.trunc_sat_f32_u
; CHECK-NEXT: # fallthrough-return
entry:
%conv = fptosi half %x to i64
%0 = icmp sgt i64 %conv, 0
%spec.store.select7 = select i1 %0, i64 %conv, i64 0
%conv6 = trunc i64 %spec.store.select7 to i32
ret i32 %conv6
}
; i16 saturate
define i16 @stest_f64i16(double %x) {
; CHECK-LABEL: stest_f64i16:
; CHECK: .functype stest_f64i16 (f64) -> (i32)
; CHECK-NEXT: .local i32
; CHECK-NEXT: # %bb.0: # %entry
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.trunc_sat_f64_s
; CHECK-NEXT: local.tee 1
; CHECK-NEXT: i32.const 32767
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i32.const 32767
; CHECK-NEXT: i32.lt_s
; CHECK-NEXT: i32.select
; CHECK-NEXT: local.tee 1
; CHECK-NEXT: i32.const -32768
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i32.const -32768
; CHECK-NEXT: i32.gt_s
; CHECK-NEXT: i32.select
; CHECK-NEXT: # fallthrough-return
entry:
%conv = fptosi double %x to i32
%0 = icmp slt i32 %conv, 32767
%spec.store.select = select i1 %0, i32 %conv, i32 32767
%1 = icmp sgt i32 %spec.store.select, -32768
%spec.store.select7 = select i1 %1, i32 %spec.store.select, i32 -32768
%conv6 = trunc i32 %spec.store.select7 to i16
ret i16 %conv6
}
define i16 @utest_f64i16(double %x) {
; CHECK-LABEL: utest_f64i16:
; CHECK: .functype utest_f64i16 (f64) -> (i32)
; CHECK-NEXT: .local i32
; CHECK-NEXT: # %bb.0: # %entry
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.trunc_sat_f64_u
; CHECK-NEXT: local.tee 1
; CHECK-NEXT: i32.const 65535
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i32.const 65535
; CHECK-NEXT: i32.lt_u
; CHECK-NEXT: i32.select
; CHECK-NEXT: # fallthrough-return
entry:
%conv = fptoui double %x to i32
%0 = icmp ult i32 %conv, 65535
%spec.store.select = select i1 %0, i32 %conv, i32 65535
%conv6 = trunc i32 %spec.store.select to i16
ret i16 %conv6
}
define i16 @ustest_f64i16(double %x) {
; CHECK-LABEL: ustest_f64i16:
; CHECK: .functype ustest_f64i16 (f64) -> (i32)
; CHECK-NEXT: .local i32
; CHECK-NEXT: # %bb.0: # %entry
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.trunc_sat_f64_s
; CHECK-NEXT: local.tee 1
; CHECK-NEXT: i32.const 65535
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i32.const 65535
; CHECK-NEXT: i32.lt_s
; CHECK-NEXT: i32.select
; CHECK-NEXT: local.tee 1
; CHECK-NEXT: i32.const 0
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i32.const 0
; CHECK-NEXT: i32.gt_s
; CHECK-NEXT: i32.select
; CHECK-NEXT: # fallthrough-return
entry:
%conv = fptosi double %x to i32
%0 = icmp slt i32 %conv, 65535
%spec.store.select = select i1 %0, i32 %conv, i32 65535
%1 = icmp sgt i32 %spec.store.select, 0
%spec.store.select7 = select i1 %1, i32 %spec.store.select, i32 0
%conv6 = trunc i32 %spec.store.select7 to i16
ret i16 %conv6
}
define i16 @stest_f32i16(float %x) {
; CHECK-LABEL: stest_f32i16:
; CHECK: .functype stest_f32i16 (f32) -> (i32)
; CHECK-NEXT: .local i32
; CHECK-NEXT: # %bb.0: # %entry
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.trunc_sat_f32_s
; CHECK-NEXT: local.tee 1
; CHECK-NEXT: i32.const 32767
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i32.const 32767
; CHECK-NEXT: i32.lt_s
; CHECK-NEXT: i32.select
; CHECK-NEXT: local.tee 1
; CHECK-NEXT: i32.const -32768
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i32.const -32768
; CHECK-NEXT: i32.gt_s
; CHECK-NEXT: i32.select
; CHECK-NEXT: # fallthrough-return
entry:
%conv = fptosi float %x to i32
%0 = icmp slt i32 %conv, 32767
%spec.store.select = select i1 %0, i32 %conv, i32 32767
%1 = icmp sgt i32 %spec.store.select, -32768
%spec.store.select7 = select i1 %1, i32 %spec.store.select, i32 -32768
%conv6 = trunc i32 %spec.store.select7 to i16
ret i16 %conv6
}
define i16 @utest_f32i16(float %x) {
; CHECK-LABEL: utest_f32i16:
; CHECK: .functype utest_f32i16 (f32) -> (i32)
; CHECK-NEXT: .local i32
; CHECK-NEXT: # %bb.0: # %entry
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.trunc_sat_f32_u
; CHECK-NEXT: local.tee 1
; CHECK-NEXT: i32.const 65535
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i32.const 65535
; CHECK-NEXT: i32.lt_u
; CHECK-NEXT: i32.select
; CHECK-NEXT: # fallthrough-return
entry:
%conv = fptoui float %x to i32
%0 = icmp ult i32 %conv, 65535
%spec.store.select = select i1 %0, i32 %conv, i32 65535
%conv6 = trunc i32 %spec.store.select to i16
ret i16 %conv6
}
define i16 @ustest_f32i16(float %x) {
; CHECK-LABEL: ustest_f32i16:
; CHECK: .functype ustest_f32i16 (f32) -> (i32)
; CHECK-NEXT: .local i32
; CHECK-NEXT: # %bb.0: # %entry
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.trunc_sat_f32_s
; CHECK-NEXT: local.tee 1
; CHECK-NEXT: i32.const 65535
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i32.const 65535
; CHECK-NEXT: i32.lt_s
; CHECK-NEXT: i32.select
; CHECK-NEXT: local.tee 1
; CHECK-NEXT: i32.const 0
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i32.const 0
; CHECK-NEXT: i32.gt_s
; CHECK-NEXT: i32.select
; CHECK-NEXT: # fallthrough-return
entry:
%conv = fptosi float %x to i32
%0 = icmp slt i32 %conv, 65535
%spec.store.select = select i1 %0, i32 %conv, i32 65535
%1 = icmp sgt i32 %spec.store.select, 0
%spec.store.select7 = select i1 %1, i32 %spec.store.select, i32 0
%conv6 = trunc i32 %spec.store.select7 to i16
ret i16 %conv6
}
define i16 @stest_f16i16(half %x) {
; CHECK-LABEL: stest_f16i16:
; CHECK: .functype stest_f16i16 (f32) -> (i32)
; CHECK-NEXT: .local i32
; CHECK-NEXT: # %bb.0: # %entry
; CHECK-NEXT: local.get 0
; CHECK-NEXT: call __truncsfhf2
; CHECK-NEXT: call __extendhfsf2
; CHECK-NEXT: i32.trunc_sat_f32_s
; CHECK-NEXT: local.tee 1
; CHECK-NEXT: i32.const 32767
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i32.const 32767
; CHECK-NEXT: i32.lt_s
; CHECK-NEXT: i32.select
; CHECK-NEXT: local.tee 1
; CHECK-NEXT: i32.const -32768
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i32.const -32768
; CHECK-NEXT: i32.gt_s
; CHECK-NEXT: i32.select
; CHECK-NEXT: # fallthrough-return
entry:
%conv = fptosi half %x to i32
%0 = icmp slt i32 %conv, 32767
%spec.store.select = select i1 %0, i32 %conv, i32 32767
%1 = icmp sgt i32 %spec.store.select, -32768
%spec.store.select7 = select i1 %1, i32 %spec.store.select, i32 -32768
%conv6 = trunc i32 %spec.store.select7 to i16
ret i16 %conv6
}
define i16 @utesth_f16i16(half %x) {
; CHECK-LABEL: utesth_f16i16:
; CHECK: .functype utesth_f16i16 (f32) -> (i32)
; CHECK-NEXT: .local i32
; CHECK-NEXT: # %bb.0: # %entry
; CHECK-NEXT: local.get 0
; CHECK-NEXT: call __truncsfhf2
; CHECK-NEXT: call __extendhfsf2
; CHECK-NEXT: i32.trunc_sat_f32_u
; CHECK-NEXT: local.tee 1
; CHECK-NEXT: i32.const 65535
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i32.const 65535
; CHECK-NEXT: i32.lt_u
; CHECK-NEXT: i32.select
; CHECK-NEXT: # fallthrough-return
entry:
%conv = fptoui half %x to i32
%0 = icmp ult i32 %conv, 65535
%spec.store.select = select i1 %0, i32 %conv, i32 65535
%conv6 = trunc i32 %spec.store.select to i16
ret i16 %conv6
}
define i16 @utesth_f16i16_cse(half %x) {
; CHECK-LABEL: utesth_f16i16_cse:
; CHECK: .functype utesth_f16i16_cse (f32) -> (i32)
; CHECK-NEXT: # %bb.0: # %entry
; CHECK-NEXT: local.get 0
; CHECK-NEXT: call __truncsfhf2
; CHECK-NEXT: call __extendhfsf2
; CHECK-NEXT: i32.trunc_sat_f32_u
; CHECK-NEXT: # fallthrough-return
entry:
%conv = fptoui half %x to i32
%conv6 = trunc i32 %conv to i16
ret i16 %conv6
}
define i16 @ustest_f16i16(half %x) {
; CHECK-LABEL: ustest_f16i16:
; CHECK: .functype ustest_f16i16 (f32) -> (i32)
; CHECK-NEXT: .local i32
; CHECK-NEXT: # %bb.0: # %entry
; CHECK-NEXT: local.get 0
; CHECK-NEXT: call __truncsfhf2
; CHECK-NEXT: call __extendhfsf2
; CHECK-NEXT: i32.trunc_sat_f32_s
; CHECK-NEXT: local.tee 1
; CHECK-NEXT: i32.const 65535
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i32.const 65535
; CHECK-NEXT: i32.lt_s
; CHECK-NEXT: i32.select
; CHECK-NEXT: local.tee 1
; CHECK-NEXT: i32.const 0
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i32.const 0
; CHECK-NEXT: i32.gt_s
; CHECK-NEXT: i32.select
; CHECK-NEXT: # fallthrough-return
entry:
%conv = fptosi half %x to i32
%0 = icmp slt i32 %conv, 65535
%spec.store.select = select i1 %0, i32 %conv, i32 65535
%1 = icmp sgt i32 %spec.store.select, 0
%spec.store.select7 = select i1 %1, i32 %spec.store.select, i32 0
%conv6 = trunc i32 %spec.store.select7 to i16
ret i16 %conv6
}
define i16 @ustest_f16i16_cse(half %x) {
; CHECK-LABEL: ustest_f16i16_cse:
; CHECK: .functype ustest_f16i16_cse (f32) -> (i32)
; CHECK-NEXT: # %bb.0: # %entry
; CHECK-NEXT: local.get 0
; CHECK-NEXT: call __truncsfhf2
; CHECK-NEXT: call __extendhfsf2
; CHECK-NEXT: i32.trunc_sat_f32_u
; CHECK-NEXT: # fallthrough-return
entry:
%conv = fptosi half %x to i32
%0 = icmp sgt i32 %conv, 0
%spec.store.select7 = select i1 %0, i32 %conv, i32 0
%conv6 = trunc i32 %spec.store.select7 to i16
ret i16 %conv6
}
; i64 saturate
define i64 @stest_f64i64(double %x) {
; CHECK-LABEL: stest_f64i64:
; CHECK: .functype stest_f64i64 (f64) -> (i64)
; CHECK-NEXT: # %bb.0: # %entry
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i64.trunc_sat_f64_s
; CHECK-NEXT: # fallthrough-return
entry:
%conv = fptosi double %x to i128
%0 = icmp slt i128 %conv, 9223372036854775807
%spec.store.select = select i1 %0, i128 %conv, i128 9223372036854775807
%1 = icmp sgt i128 %spec.store.select, -9223372036854775808
%spec.store.select7 = select i1 %1, i128 %spec.store.select, i128 -9223372036854775808
%conv6 = trunc i128 %spec.store.select7 to i64
ret i64 %conv6
}
define i64 @utest_f64i64(double %x) {
; CHECK-LABEL: utest_f64i64:
; CHECK: .functype utest_f64i64 (f64) -> (i64)
; CHECK-NEXT: .local i32, i64, i64
; CHECK-NEXT: # %bb.0: # %entry
; CHECK-NEXT: global.get __stack_pointer
; CHECK-NEXT: i32.const 16
; CHECK-NEXT: i32.sub
; CHECK-NEXT: local.tee 1
; CHECK-NEXT: global.set __stack_pointer
; CHECK-NEXT: local.get 1
; CHECK-NEXT: local.get 0
; CHECK-NEXT: call __fixunsdfti
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i64.load 8
; CHECK-NEXT: local.set 2
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i64.load 0
; CHECK-NEXT: local.set 3
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i32.const 16
; CHECK-NEXT: i32.add
; CHECK-NEXT: global.set __stack_pointer
; CHECK-NEXT: local.get 3
; CHECK-NEXT: i64.const 0
; CHECK-NEXT: local.get 2
; CHECK-NEXT: i64.eqz
; CHECK-NEXT: i64.select
; CHECK-NEXT: # fallthrough-return
entry:
%conv = fptoui double %x to i128
%0 = icmp ult i128 %conv, 18446744073709551616
%spec.store.select = select i1 %0, i128 %conv, i128 18446744073709551616
%conv6 = trunc i128 %spec.store.select to i64
ret i64 %conv6
}
define i64 @utest_f64i64_cse_combine(double %x) #0 {
; CHECK-LABEL: utest_f64i64_cse_combine:
; CHECK: .functype utest_f64i64_cse_combine (f64) -> (i64)
; CHECK-NEXT: .local i32, i64, i64
; CHECK-NEXT: # %bb.0: # %entry
; CHECK-NEXT: global.get __stack_pointer
; CHECK-NEXT: i32.const 16
; CHECK-NEXT: i32.sub
; CHECK-NEXT: local.tee 1
; CHECK-NEXT: global.set __stack_pointer
; CHECK-NEXT: local.get 1
; CHECK-NEXT: local.get 0
; CHECK-NEXT: call __fixunsdfti
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i64.load 8
; CHECK-NEXT: local.set 2
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i64.load 0
; CHECK-NEXT: local.set 3
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i32.const 16
; CHECK-NEXT: i32.add
; CHECK-NEXT: global.set __stack_pointer
; CHECK-NEXT: local.get 3
; CHECK-NEXT: i64.const 0
; CHECK-NEXT: local.get 2
; CHECK-NEXT: i64.eqz
; CHECK-NEXT: i64.select
; CHECK-NEXT: # fallthrough-return
entry:
%conv = fptoui double %x to i128
%spec.store.select = call i128 @llvm.umin.i128(i128 %conv, i128 18446744073709551616)
%conv6 = trunc i128 %spec.store.select to i64
ret i64 %conv6
}
define i64 @ustest_f64i64(double %x) {
; CHECK-LABEL: ustest_f64i64:
; CHECK: .functype ustest_f64i64 (f64) -> (i64)
; CHECK-NEXT: .local i32, i64, i64
; CHECK-NEXT: # %bb.0: # %entry
; CHECK-NEXT: global.get __stack_pointer
; CHECK-NEXT: i32.const 16
; CHECK-NEXT: i32.sub
; CHECK-NEXT: local.tee 1
; CHECK-NEXT: global.set __stack_pointer
; CHECK-NEXT: local.get 1
; CHECK-NEXT: local.get 0
; CHECK-NEXT: call __fixdfti
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i64.load 8
; CHECK-NEXT: local.set 2
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i64.load 0
; CHECK-NEXT: local.set 3
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i32.const 16
; CHECK-NEXT: i32.add
; CHECK-NEXT: global.set __stack_pointer
; CHECK-NEXT: local.get 3
; CHECK-NEXT: i64.const 0
; CHECK-NEXT: local.get 2
; CHECK-NEXT: i64.const 1
; CHECK-NEXT: i64.lt_s
; CHECK-NEXT: local.tee 1
; CHECK-NEXT: i64.select
; CHECK-NEXT: local.tee 3
; CHECK-NEXT: i64.const 0
; CHECK-NEXT: local.get 3
; CHECK-NEXT: i64.const 0
; CHECK-NEXT: i64.ne
; CHECK-NEXT: local.get 2
; CHECK-NEXT: i64.const 1
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i64.select
; CHECK-NEXT: local.tee 2
; CHECK-NEXT: i64.const 0
; CHECK-NEXT: i64.gt_s
; CHECK-NEXT: local.get 2
; CHECK-NEXT: i64.eqz
; CHECK-NEXT: i32.select
; CHECK-NEXT: i64.select
; CHECK-NEXT: # fallthrough-return
entry:
%conv = fptosi double %x to i128
%0 = icmp slt i128 %conv, 18446744073709551616
%spec.store.select = select i1 %0, i128 %conv, i128 18446744073709551616
%1 = icmp sgt i128 %spec.store.select, 0
%spec.store.select7 = select i1 %1, i128 %spec.store.select, i128 0
%conv6 = trunc i128 %spec.store.select7 to i64
ret i64 %conv6
}
define i64 @ustest_f64i64_cse_combine(double %x) #0 {
; CHECK-LABEL: ustest_f64i64_cse_combine:
; CHECK: .functype ustest_f64i64_cse_combine (f64) -> (i64)
; CHECK-NEXT: .local i32, i64, i64
; CHECK-NEXT: # %bb.0: # %entry
; CHECK-NEXT: global.get __stack_pointer
; CHECK-NEXT: i32.const 16
; CHECK-NEXT: i32.sub
; CHECK-NEXT: local.tee 1
; CHECK-NEXT: global.set __stack_pointer
; CHECK-NEXT: local.get 1
; CHECK-NEXT: local.get 0
; CHECK-NEXT: call __fixdfti
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i64.load 8
; CHECK-NEXT: local.set 2
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i64.load 0
; CHECK-NEXT: local.set 3
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i32.const 16
; CHECK-NEXT: i32.add
; CHECK-NEXT: global.set __stack_pointer
; CHECK-NEXT: i64.const 0
; CHECK-NEXT: local.get 3
; CHECK-NEXT: i64.const 0
; CHECK-NEXT: local.get 2
; CHECK-NEXT: i64.const 1
; CHECK-NEXT: i64.lt_s
; CHECK-NEXT: local.tee 1
; CHECK-NEXT: i64.select
; CHECK-NEXT: local.get 2
; CHECK-NEXT: i64.const 1
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i64.select
; CHECK-NEXT: i64.const 0
; CHECK-NEXT: i64.lt_s
; CHECK-NEXT: i64.select
; CHECK-NEXT: # fallthrough-return
entry:
%conv = fptosi double %x to i128
%spec.store.select = call i128 @llvm.smin.i128(i128 %conv, i128 18446744073709551616)
%spec.store.select7 = call i128 @llvm.smax.i128(i128 %spec.store.select, i128 0)
%conv6 = trunc i128 %spec.store.select7 to i64
ret i64 %conv6
}
define i64 @stest_f32i64(float %x) {
; CHECK-LABEL: stest_f32i64:
; CHECK: .functype stest_f32i64 (f32) -> (i64)
; CHECK-NEXT: # %bb.0: # %entry
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i64.trunc_sat_f32_s
; CHECK-NEXT: # fallthrough-return
entry:
%conv = fptosi float %x to i128
%0 = icmp slt i128 %conv, 9223372036854775807
%spec.store.select = select i1 %0, i128 %conv, i128 9223372036854775807
%1 = icmp sgt i128 %spec.store.select, -9223372036854775808
%spec.store.select7 = select i1 %1, i128 %spec.store.select, i128 -9223372036854775808
%conv6 = trunc i128 %spec.store.select7 to i64
ret i64 %conv6
}
define i64 @utest_f32i64(float %x) {
; CHECK-LABEL: utest_f32i64:
; CHECK: .functype utest_f32i64 (f32) -> (i64)
; CHECK-NEXT: .local i32, i64, i64
; CHECK-NEXT: # %bb.0: # %entry
; CHECK-NEXT: global.get __stack_pointer
; CHECK-NEXT: i32.const 16
; CHECK-NEXT: i32.sub
; CHECK-NEXT: local.tee 1
; CHECK-NEXT: global.set __stack_pointer
; CHECK-NEXT: local.get 1
; CHECK-NEXT: local.get 0
; CHECK-NEXT: call __fixunssfti
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i64.load 8
; CHECK-NEXT: local.set 2
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i64.load 0
; CHECK-NEXT: local.set 3
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i32.const 16
; CHECK-NEXT: i32.add
; CHECK-NEXT: global.set __stack_pointer
; CHECK-NEXT: local.get 3
; CHECK-NEXT: i64.const 0
; CHECK-NEXT: local.get 2
; CHECK-NEXT: i64.eqz
; CHECK-NEXT: i64.select
; CHECK-NEXT: # fallthrough-return
entry:
%conv = fptoui float %x to i128
%0 = icmp ult i128 %conv, 18446744073709551616
%spec.store.select = select i1 %0, i128 %conv, i128 18446744073709551616
%conv6 = trunc i128 %spec.store.select to i64
ret i64 %conv6
}
define i64 @stest_f32i64_cse_combine(float %x) #0 {
; CHECK-LABEL: stest_f32i64_cse_combine:
; CHECK: .functype stest_f32i64_cse_combine (f32) -> (i64)
; CHECK-NEXT: # %bb.0: # %entry
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i64.trunc_sat_f32_s
; CHECK-NEXT: # fallthrough-return
entry:
%conv = fptosi float %x to i128
%spec.store.select = call i128 @llvm.smin.i128(i128 %conv, i128 9223372036854775807)
%spec.store.select7 = call i128 @llvm.smax.i128(i128 %spec.store.select, i128 -9223372036854775808)
%conv6 = trunc i128 %spec.store.select7 to i64
ret i64 %conv6
}
define i64 @ustest_f32i64(float %x) {
; CHECK-LABEL: ustest_f32i64:
; CHECK: .functype ustest_f32i64 (f32) -> (i64)
; CHECK-NEXT: .local i32, i64, i64
; CHECK-NEXT: # %bb.0: # %entry
; CHECK-NEXT: global.get __stack_pointer
; CHECK-NEXT: i32.const 16
; CHECK-NEXT: i32.sub
; CHECK-NEXT: local.tee 1
; CHECK-NEXT: global.set __stack_pointer
; CHECK-NEXT: local.get 1
; CHECK-NEXT: local.get 0
; CHECK-NEXT: call __fixsfti
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i64.load 8
; CHECK-NEXT: local.set 2
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i64.load 0
; CHECK-NEXT: local.set 3
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i32.const 16
; CHECK-NEXT: i32.add
; CHECK-NEXT: global.set __stack_pointer
; CHECK-NEXT: local.get 3
; CHECK-NEXT: i64.const 0
; CHECK-NEXT: local.get 2
; CHECK-NEXT: i64.const 1
; CHECK-NEXT: i64.lt_s
; CHECK-NEXT: local.tee 1
; CHECK-NEXT: i64.select
; CHECK-NEXT: local.tee 3
; CHECK-NEXT: i64.const 0
; CHECK-NEXT: local.get 3
; CHECK-NEXT: i64.const 0
; CHECK-NEXT: i64.ne
; CHECK-NEXT: local.get 2
; CHECK-NEXT: i64.const 1
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i64.select
; CHECK-NEXT: local.tee 2
; CHECK-NEXT: i64.const 0
; CHECK-NEXT: i64.gt_s
; CHECK-NEXT: local.get 2
; CHECK-NEXT: i64.eqz
; CHECK-NEXT: i32.select
; CHECK-NEXT: i64.select
; CHECK-NEXT: # fallthrough-return
entry:
%conv = fptosi float %x to i128
%0 = icmp slt i128 %conv, 18446744073709551616
%spec.store.select = select i1 %0, i128 %conv, i128 18446744073709551616
%1 = icmp sgt i128 %spec.store.select, 0
%spec.store.select7 = select i1 %1, i128 %spec.store.select, i128 0
%conv6 = trunc i128 %spec.store.select7 to i64
ret i64 %conv6
}
define i64 @ustest_f32i64_cse_combine(float %x) #0 {
; CHECK-LABEL: ustest_f32i64_cse_combine:
; CHECK: .functype ustest_f32i64_cse_combine (f32) -> (i64)
; CHECK-NEXT: .local i32, i64, i64
; CHECK-NEXT: # %bb.0: # %entry
; CHECK-NEXT: global.get __stack_pointer
; CHECK-NEXT: i32.const 16
; CHECK-NEXT: i32.sub
; CHECK-NEXT: local.tee 1
; CHECK-NEXT: global.set __stack_pointer
; CHECK-NEXT: local.get 1
; CHECK-NEXT: local.get 0
; CHECK-NEXT: call __fixsfti
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i64.load 8
; CHECK-NEXT: local.set 2
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i64.load 0
; CHECK-NEXT: local.set 3
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i32.const 16
; CHECK-NEXT: i32.add
; CHECK-NEXT: global.set __stack_pointer
; CHECK-NEXT: i64.const 0
; CHECK-NEXT: local.get 3
; CHECK-NEXT: i64.const 0
; CHECK-NEXT: local.get 2
; CHECK-NEXT: i64.const 1
; CHECK-NEXT: i64.lt_s
; CHECK-NEXT: local.tee 1
; CHECK-NEXT: i64.select
; CHECK-NEXT: local.get 2
; CHECK-NEXT: i64.const 1
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i64.select
; CHECK-NEXT: i64.const 0
; CHECK-NEXT: i64.lt_s
; CHECK-NEXT: i64.select
; CHECK-NEXT: # fallthrough-return
entry:
%conv = fptosi float %x to i128
%spec.store.select = call i128 @llvm.smin.i128(i128 %conv, i128 18446744073709551616)
%spec.store.select7 = call i128 @llvm.smax.i128(i128 %spec.store.select, i128 0)
%conv6 = trunc i128 %spec.store.select7 to i64
ret i64 %conv6
}
define i64 @stest_f16i64(half %x) {
; CHECK-LABEL: stest_f16i64:
; CHECK: .functype stest_f16i64 (f32) -> (i64)
; CHECK-NEXT: # %bb.0: # %entry
; CHECK-NEXT: local.get 0
; CHECK-NEXT: call __truncsfhf2
; CHECK-NEXT: call __extendhfsf2
; CHECK-NEXT: i64.trunc_sat_f32_s
; CHECK-NEXT: # fallthrough-return
entry:
%conv = fptosi half %x to i128
%0 = icmp slt i128 %conv, 9223372036854775807
%spec.store.select = select i1 %0, i128 %conv, i128 9223372036854775807
%1 = icmp sgt i128 %spec.store.select, -9223372036854775808
%spec.store.select7 = select i1 %1, i128 %spec.store.select, i128 -9223372036854775808
%conv6 = trunc i128 %spec.store.select7 to i64
ret i64 %conv6
}
define i64 @utesth_f16i64(half %x) {
; CHECK-LABEL: utesth_f16i64:
; CHECK: .functype utesth_f16i64 (f32) -> (i64)
; CHECK-NEXT: .local i32, i64, i64
; CHECK-NEXT: # %bb.0: # %entry
; CHECK-NEXT: global.get __stack_pointer
; CHECK-NEXT: i32.const 16
; CHECK-NEXT: i32.sub
; CHECK-NEXT: local.tee 1
; CHECK-NEXT: global.set __stack_pointer
; CHECK-NEXT: local.get 1
; CHECK-NEXT: local.get 0
; CHECK-NEXT: call __truncsfhf2
; CHECK-NEXT: call __extendhfsf2
; CHECK-NEXT: call __fixunssfti
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i64.load 8
; CHECK-NEXT: local.set 2
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i64.load 0
; CHECK-NEXT: local.set 3
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i32.const 16
; CHECK-NEXT: i32.add
; CHECK-NEXT: global.set __stack_pointer
; CHECK-NEXT: local.get 3
; CHECK-NEXT: i64.const 0
; CHECK-NEXT: local.get 2
; CHECK-NEXT: i64.eqz
; CHECK-NEXT: i64.select
; CHECK-NEXT: # fallthrough-return
entry:
%conv = fptoui half %x to i128
%0 = icmp ult i128 %conv, 18446744073709551616
%spec.store.select = select i1 %0, i128 %conv, i128 18446744073709551616
%conv6 = trunc i128 %spec.store.select to i64
ret i64 %conv6
}
define i64 @utesth_f16i64_cse(half %x) {
; CHECK-LABEL: utesth_f16i64_cse:
; CHECK: .functype utesth_f16i64_cse (f32) -> (i64)
; CHECK-NEXT: .local i32, i64
; CHECK-NEXT: # %bb.0: # %entry
; CHECK-NEXT: global.get __stack_pointer
; CHECK-NEXT: i32.const 16
; CHECK-NEXT: i32.sub
; CHECK-NEXT: local.tee 1
; CHECK-NEXT: global.set __stack_pointer
; CHECK-NEXT: local.get 1
; CHECK-NEXT: local.get 0
; CHECK-NEXT: call __truncsfhf2
; CHECK-NEXT: call __extendhfsf2
; CHECK-NEXT: call __fixunssfti
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i64.load 0
; CHECK-NEXT: local.set 2
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i32.const 16
; CHECK-NEXT: i32.add
; CHECK-NEXT: global.set __stack_pointer
; CHECK-NEXT: local.get 2
; CHECK-NEXT: # fallthrough-return
entry:
%conv = fptoui half %x to i128
%conv6 = trunc i128 %conv to i64
ret i64 %conv6
}
define i64 @ustest_f16i64(half %x) {
; CHECK-LABEL: ustest_f16i64:
; CHECK: .functype ustest_f16i64 (f32) -> (i64)
; CHECK-NEXT: .local i32, i64, i64
; CHECK-NEXT: # %bb.0: # %entry
; CHECK-NEXT: global.get __stack_pointer
; CHECK-NEXT: i32.const 16
; CHECK-NEXT: i32.sub
; CHECK-NEXT: local.tee 1
; CHECK-NEXT: global.set __stack_pointer
; CHECK-NEXT: local.get 1
; CHECK-NEXT: local.get 0
; CHECK-NEXT: call __truncsfhf2
; CHECK-NEXT: call __extendhfsf2
; CHECK-NEXT: call __fixsfti
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i64.load 8
; CHECK-NEXT: local.set 2
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i64.load 0
; CHECK-NEXT: local.set 3
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i32.const 16
; CHECK-NEXT: i32.add
; CHECK-NEXT: global.set __stack_pointer
; CHECK-NEXT: local.get 3
; CHECK-NEXT: i64.const 0
; CHECK-NEXT: local.get 2
; CHECK-NEXT: i64.const 1
; CHECK-NEXT: i64.lt_s
; CHECK-NEXT: local.tee 1
; CHECK-NEXT: i64.select
; CHECK-NEXT: local.tee 3
; CHECK-NEXT: i64.const 0
; CHECK-NEXT: local.get 3
; CHECK-NEXT: i64.const 0
; CHECK-NEXT: i64.ne
; CHECK-NEXT: local.get 2
; CHECK-NEXT: i64.const 1
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i64.select
; CHECK-NEXT: local.tee 2
; CHECK-NEXT: i64.const 0
; CHECK-NEXT: i64.gt_s
; CHECK-NEXT: local.get 2
; CHECK-NEXT: i64.eqz
; CHECK-NEXT: i32.select
; CHECK-NEXT: i64.select
; CHECK-NEXT: # fallthrough-return
entry:
%conv = fptosi half %x to i128
%0 = icmp slt i128 %conv, 18446744073709551616
%spec.store.select = select i1 %0, i128 %conv, i128 18446744073709551616
%1 = icmp sgt i128 %spec.store.select, 0
%spec.store.select7 = select i1 %1, i128 %spec.store.select, i128 0
%conv6 = trunc i128 %spec.store.select7 to i64
ret i64 %conv6
}
; i32 saturate
define i32 @stest_f64i32_mm(double %x) {
; CHECK-LABEL: stest_f64i32_mm:
; CHECK: .functype stest_f64i32_mm (f64) -> (i32)
; CHECK-NEXT: # %bb.0: # %entry
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.trunc_sat_f64_s
; CHECK-NEXT: # fallthrough-return
entry:
%conv = fptosi double %x to i64
%spec.store.select = call i64 @llvm.smin.i64(i64 %conv, i64 2147483647)
%spec.store.select7 = call i64 @llvm.smax.i64(i64 %spec.store.select, i64 -2147483648)
%conv6 = trunc i64 %spec.store.select7 to i32
ret i32 %conv6
}
define i32 @utest_f64i32_mm(double %x) {
; CHECK-LABEL: utest_f64i32_mm:
; CHECK: .functype utest_f64i32_mm (f64) -> (i32)
; CHECK-NEXT: # %bb.0: # %entry
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.trunc_sat_f64_u
; CHECK-NEXT: # fallthrough-return
entry:
%conv = fptoui double %x to i64
%spec.store.select = call i64 @llvm.umin.i64(i64 %conv, i64 4294967295)
%conv6 = trunc i64 %spec.store.select to i32
ret i32 %conv6
}
define i32 @ustest_f64i32_mm(double %x) {
; CHECK-LABEL: ustest_f64i32_mm:
; CHECK: .functype ustest_f64i32_mm (f64) -> (i32)
; CHECK-NEXT: # %bb.0: # %entry
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.trunc_sat_f64_u
; CHECK-NEXT: # fallthrough-return
entry:
%conv = fptosi double %x to i64
%spec.store.select = call i64 @llvm.smin.i64(i64 %conv, i64 4294967295)
%spec.store.select7 = call i64 @llvm.smax.i64(i64 %spec.store.select, i64 0)
%conv6 = trunc i64 %spec.store.select7 to i32
ret i32 %conv6
}
define i32 @stest_f32i32_mm(float %x) {
; CHECK-LABEL: stest_f32i32_mm:
; CHECK: .functype stest_f32i32_mm (f32) -> (i32)
; CHECK-NEXT: # %bb.0: # %entry
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.trunc_sat_f32_s
; CHECK-NEXT: # fallthrough-return
entry:
%conv = fptosi float %x to i64
%spec.store.select = call i64 @llvm.smin.i64(i64 %conv, i64 2147483647)
%spec.store.select7 = call i64 @llvm.smax.i64(i64 %spec.store.select, i64 -2147483648)
%conv6 = trunc i64 %spec.store.select7 to i32
ret i32 %conv6
}
define i32 @utest_f32i32_mm(float %x) {
; CHECK-LABEL: utest_f32i32_mm:
; CHECK: .functype utest_f32i32_mm (f32) -> (i32)
; CHECK-NEXT: # %bb.0: # %entry
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.trunc_sat_f32_u
; CHECK-NEXT: # fallthrough-return
entry:
%conv = fptoui float %x to i64
%spec.store.select = call i64 @llvm.umin.i64(i64 %conv, i64 4294967295)
%conv6 = trunc i64 %spec.store.select to i32
ret i32 %conv6
}
define i32 @ustest_f32i32_mm(float %x) {
; CHECK-LABEL: ustest_f32i32_mm:
; CHECK: .functype ustest_f32i32_mm (f32) -> (i32)
; CHECK-NEXT: # %bb.0: # %entry
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.trunc_sat_f32_u
; CHECK-NEXT: # fallthrough-return
entry:
%conv = fptosi float %x to i64
%spec.store.select = call i64 @llvm.smin.i64(i64 %conv, i64 4294967295)
%spec.store.select7 = call i64 @llvm.smax.i64(i64 %spec.store.select, i64 0)
%conv6 = trunc i64 %spec.store.select7 to i32
ret i32 %conv6
}
define i32 @stest_f16i32_mm(half %x) {
; CHECK-LABEL: stest_f16i32_mm:
; CHECK: .functype stest_f16i32_mm (f32) -> (i32)
; CHECK-NEXT: # %bb.0: # %entry
; CHECK-NEXT: local.get 0
; CHECK-NEXT: call __truncsfhf2
; CHECK-NEXT: call __extendhfsf2
; CHECK-NEXT: i32.trunc_sat_f32_s
; CHECK-NEXT: # fallthrough-return
entry:
%conv = fptosi half %x to i64
%spec.store.select = call i64 @llvm.smin.i64(i64 %conv, i64 2147483647)
%spec.store.select7 = call i64 @llvm.smax.i64(i64 %spec.store.select, i64 -2147483648)
%conv6 = trunc i64 %spec.store.select7 to i32
ret i32 %conv6
}
define i32 @utesth_f16i32_mm(half %x) {
; CHECK-LABEL: utesth_f16i32_mm:
; CHECK: .functype utesth_f16i32_mm (f32) -> (i32)
; CHECK-NEXT: # %bb.0: # %entry
; CHECK-NEXT: local.get 0
; CHECK-NEXT: call __truncsfhf2
; CHECK-NEXT: call __extendhfsf2
; CHECK-NEXT: i32.trunc_sat_f32_u
; CHECK-NEXT: # fallthrough-return
entry:
%conv = fptoui half %x to i64
%spec.store.select = call i64 @llvm.umin.i64(i64 %conv, i64 4294967295)
%conv6 = trunc i64 %spec.store.select to i32
ret i32 %conv6
}
define i32 @ustest_f16i32_mm(half %x) {
; CHECK-LABEL: ustest_f16i32_mm:
; CHECK: .functype ustest_f16i32_mm (f32) -> (i32)
; CHECK-NEXT: # %bb.0: # %entry
; CHECK-NEXT: local.get 0
; CHECK-NEXT: call __truncsfhf2
; CHECK-NEXT: call __extendhfsf2
; CHECK-NEXT: i32.trunc_sat_f32_u
; CHECK-NEXT: # fallthrough-return
entry:
%conv = fptosi half %x to i64
%spec.store.select = call i64 @llvm.smin.i64(i64 %conv, i64 4294967295)
%spec.store.select7 = call i64 @llvm.smax.i64(i64 %spec.store.select, i64 0)
%conv6 = trunc i64 %spec.store.select7 to i32
ret i32 %conv6
}
define i32 @ustest_f16i32_mm_cse(half %x) {
; CHECK-LABEL: ustest_f16i32_mm_cse:
; CHECK: .functype ustest_f16i32_mm_cse (f32) -> (i32)
; CHECK-NEXT: # %bb.0: # %entry
; CHECK-NEXT: local.get 0
; CHECK-NEXT: call __truncsfhf2
; CHECK-NEXT: call __extendhfsf2
; CHECK-NEXT: i32.trunc_sat_f32_u
; CHECK-NEXT: # fallthrough-return
entry:
%conv = fptosi half %x to i64
%spec.store.select7 = call i64 @llvm.smax.i64(i64 %conv, i64 0)
%conv6 = trunc i64 %spec.store.select7 to i32
ret i32 %conv6
}
; i16 saturate
define i16 @stest_f64i16_mm(double %x) {
; CHECK-LABEL: stest_f64i16_mm:
; CHECK: .functype stest_f64i16_mm (f64) -> (i32)
; CHECK-NEXT: .local i32
; CHECK-NEXT: # %bb.0: # %entry
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.trunc_sat_f64_s
; CHECK-NEXT: local.tee 1
; CHECK-NEXT: i32.const 32767
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i32.const 32767
; CHECK-NEXT: i32.lt_s
; CHECK-NEXT: i32.select
; CHECK-NEXT: local.tee 1
; CHECK-NEXT: i32.const -32768
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i32.const -32768
; CHECK-NEXT: i32.gt_s
; CHECK-NEXT: i32.select
; CHECK-NEXT: # fallthrough-return
entry:
%conv = fptosi double %x to i32
%spec.store.select = call i32 @llvm.smin.i32(i32 %conv, i32 32767)
%spec.store.select7 = call i32 @llvm.smax.i32(i32 %spec.store.select, i32 -32768)
%conv6 = trunc i32 %spec.store.select7 to i16
ret i16 %conv6
}
define i16 @utest_f64i16_mm(double %x) {
; CHECK-LABEL: utest_f64i16_mm:
; CHECK: .functype utest_f64i16_mm (f64) -> (i32)
; CHECK-NEXT: .local i32
; CHECK-NEXT: # %bb.0: # %entry
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.trunc_sat_f64_u
; CHECK-NEXT: local.tee 1
; CHECK-NEXT: i32.const 65535
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i32.const 65535
; CHECK-NEXT: i32.lt_u
; CHECK-NEXT: i32.select
; CHECK-NEXT: # fallthrough-return
entry:
%conv = fptoui double %x to i32
%spec.store.select = call i32 @llvm.umin.i32(i32 %conv, i32 65535)
%conv6 = trunc i32 %spec.store.select to i16
ret i16 %conv6
}
define i16 @ustest_f64i16_mm(double %x) {
; CHECK-LABEL: ustest_f64i16_mm:
; CHECK: .functype ustest_f64i16_mm (f64) -> (i32)
; CHECK-NEXT: .local i32
; CHECK-NEXT: # %bb.0: # %entry
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.trunc_sat_f64_s
; CHECK-NEXT: local.tee 1
; CHECK-NEXT: i32.const 65535
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i32.const 65535
; CHECK-NEXT: i32.lt_s
; CHECK-NEXT: i32.select
; CHECK-NEXT: local.tee 1
; CHECK-NEXT: i32.const 0
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i32.const 0
; CHECK-NEXT: i32.gt_s
; CHECK-NEXT: i32.select
; CHECK-NEXT: # fallthrough-return
entry:
%conv = fptosi double %x to i32
%spec.store.select = call i32 @llvm.smin.i32(i32 %conv, i32 65535)
%spec.store.select7 = call i32 @llvm.smax.i32(i32 %spec.store.select, i32 0)
%conv6 = trunc i32 %spec.store.select7 to i16
ret i16 %conv6
}
define i16 @stest_f32i16_mm(float %x) {
; CHECK-LABEL: stest_f32i16_mm:
; CHECK: .functype stest_f32i16_mm (f32) -> (i32)
; CHECK-NEXT: .local i32
; CHECK-NEXT: # %bb.0: # %entry
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.trunc_sat_f32_s
; CHECK-NEXT: local.tee 1
; CHECK-NEXT: i32.const 32767
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i32.const 32767
; CHECK-NEXT: i32.lt_s
; CHECK-NEXT: i32.select
; CHECK-NEXT: local.tee 1
; CHECK-NEXT: i32.const -32768
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i32.const -32768
; CHECK-NEXT: i32.gt_s
; CHECK-NEXT: i32.select
; CHECK-NEXT: # fallthrough-return
entry:
%conv = fptosi float %x to i32
%spec.store.select = call i32 @llvm.smin.i32(i32 %conv, i32 32767)
%spec.store.select7 = call i32 @llvm.smax.i32(i32 %spec.store.select, i32 -32768)
%conv6 = trunc i32 %spec.store.select7 to i16
ret i16 %conv6
}
define i16 @utest_f32i16_mm(float %x) {
; CHECK-LABEL: utest_f32i16_mm:
; CHECK: .functype utest_f32i16_mm (f32) -> (i32)
; CHECK-NEXT: .local i32
; CHECK-NEXT: # %bb.0: # %entry
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.trunc_sat_f32_u
; CHECK-NEXT: local.tee 1
; CHECK-NEXT: i32.const 65535
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i32.const 65535
; CHECK-NEXT: i32.lt_u
; CHECK-NEXT: i32.select
; CHECK-NEXT: # fallthrough-return
entry:
%conv = fptoui float %x to i32
%spec.store.select = call i32 @llvm.umin.i32(i32 %conv, i32 65535)
%conv6 = trunc i32 %spec.store.select to i16
ret i16 %conv6
}
define i16 @ustest_f32i16_mm(float %x) {
; CHECK-LABEL: ustest_f32i16_mm:
; CHECK: .functype ustest_f32i16_mm (f32) -> (i32)
; CHECK-NEXT: .local i32
; CHECK-NEXT: # %bb.0: # %entry
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.trunc_sat_f32_s
; CHECK-NEXT: local.tee 1
; CHECK-NEXT: i32.const 65535
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i32.const 65535
; CHECK-NEXT: i32.lt_s
; CHECK-NEXT: i32.select
; CHECK-NEXT: local.tee 1
; CHECK-NEXT: i32.const 0
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i32.const 0
; CHECK-NEXT: i32.gt_s
; CHECK-NEXT: i32.select
; CHECK-NEXT: # fallthrough-return
entry:
%conv = fptosi float %x to i32
%spec.store.select = call i32 @llvm.smin.i32(i32 %conv, i32 65535)
%spec.store.select7 = call i32 @llvm.smax.i32(i32 %spec.store.select, i32 0)
%conv6 = trunc i32 %spec.store.select7 to i16
ret i16 %conv6
}
define i16 @stest_f16i16_mm(half %x) {
; CHECK-LABEL: stest_f16i16_mm:
; CHECK: .functype stest_f16i16_mm (f32) -> (i32)
; CHECK-NEXT: .local i32
; CHECK-NEXT: # %bb.0: # %entry
; CHECK-NEXT: local.get 0
; CHECK-NEXT: call __truncsfhf2
; CHECK-NEXT: call __extendhfsf2
; CHECK-NEXT: i32.trunc_sat_f32_s
; CHECK-NEXT: local.tee 1
; CHECK-NEXT: i32.const 32767
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i32.const 32767
; CHECK-NEXT: i32.lt_s
; CHECK-NEXT: i32.select
; CHECK-NEXT: local.tee 1
; CHECK-NEXT: i32.const -32768
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i32.const -32768
; CHECK-NEXT: i32.gt_s
; CHECK-NEXT: i32.select
; CHECK-NEXT: # fallthrough-return
entry:
%conv = fptosi half %x to i32
%spec.store.select = call i32 @llvm.smin.i32(i32 %conv, i32 32767)
%spec.store.select7 = call i32 @llvm.smax.i32(i32 %spec.store.select, i32 -32768)
%conv6 = trunc i32 %spec.store.select7 to i16
ret i16 %conv6
}
define i16 @utesth_f16i16_mm(half %x) {
; CHECK-LABEL: utesth_f16i16_mm:
; CHECK: .functype utesth_f16i16_mm (f32) -> (i32)
; CHECK-NEXT: .local i32
; CHECK-NEXT: # %bb.0: # %entry
; CHECK-NEXT: local.get 0
; CHECK-NEXT: call __truncsfhf2
; CHECK-NEXT: call __extendhfsf2
; CHECK-NEXT: i32.trunc_sat_f32_u
; CHECK-NEXT: local.tee 1
; CHECK-NEXT: i32.const 65535
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i32.const 65535
; CHECK-NEXT: i32.lt_u
; CHECK-NEXT: i32.select
; CHECK-NEXT: # fallthrough-return
entry:
%conv = fptoui half %x to i32
%spec.store.select = call i32 @llvm.umin.i32(i32 %conv, i32 65535)
%conv6 = trunc i32 %spec.store.select to i16
ret i16 %conv6
}
define i16 @ustest_f16i16_mm(half %x) {
; CHECK-LABEL: ustest_f16i16_mm:
; CHECK: .functype ustest_f16i16_mm (f32) -> (i32)
; CHECK-NEXT: .local i32
; CHECK-NEXT: # %bb.0: # %entry
; CHECK-NEXT: local.get 0
; CHECK-NEXT: call __truncsfhf2
; CHECK-NEXT: call __extendhfsf2
; CHECK-NEXT: i32.trunc_sat_f32_s
; CHECK-NEXT: local.tee 1
; CHECK-NEXT: i32.const 65535
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i32.const 65535
; CHECK-NEXT: i32.lt_s
; CHECK-NEXT: i32.select
; CHECK-NEXT: local.tee 1
; CHECK-NEXT: i32.const 0
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i32.const 0
; CHECK-NEXT: i32.gt_s
; CHECK-NEXT: i32.select
; CHECK-NEXT: # fallthrough-return
entry:
%conv = fptosi half %x to i32
%spec.store.select = call i32 @llvm.smin.i32(i32 %conv, i32 65535)
%spec.store.select7 = call i32 @llvm.smax.i32(i32 %spec.store.select, i32 0)
%conv6 = trunc i32 %spec.store.select7 to i16
ret i16 %conv6
}
define i16 @ustest_f16i16_mm_cse(half %x) {
; CHECK-LABEL: ustest_f16i16_mm_cse:
; CHECK: .functype ustest_f16i16_mm_cse (f32) -> (i32)
; CHECK-NEXT: # %bb.0: # %entry
; CHECK-NEXT: local.get 0
; CHECK-NEXT: call __truncsfhf2
; CHECK-NEXT: call __extendhfsf2
; CHECK-NEXT: i32.trunc_sat_f32_u
; CHECK-NEXT: # fallthrough-return
entry:
%conv = fptosi half %x to i32
%spec.store.select7 = call i32 @llvm.smax.i32(i32 %conv, i32 0)
%conv6 = trunc i32 %spec.store.select7 to i16
ret i16 %conv6
}
; i64 saturate
define i64 @stest_f64i64_mm(double %x) {
; CHECK-LABEL: stest_f64i64_mm:
; CHECK: .functype stest_f64i64_mm (f64) -> (i64)
; CHECK-NEXT: # %bb.0: # %entry
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i64.trunc_sat_f64_s
; CHECK-NEXT: # fallthrough-return
entry:
%conv = fptosi double %x to i128
%spec.store.select = call i128 @llvm.smin.i128(i128 %conv, i128 9223372036854775807)
%spec.store.select7 = call i128 @llvm.smax.i128(i128 %spec.store.select, i128 -9223372036854775808)
%conv6 = trunc i128 %spec.store.select7 to i64
ret i64 %conv6
}
define i64 @utest_f64i64_mm(double %x) {
; CHECK-LABEL: utest_f64i64_mm:
; CHECK: .functype utest_f64i64_mm (f64) -> (i64)
; CHECK-NEXT: .local i32, i64, i64
; CHECK-NEXT: # %bb.0: # %entry
; CHECK-NEXT: global.get __stack_pointer
; CHECK-NEXT: i32.const 16
; CHECK-NEXT: i32.sub
; CHECK-NEXT: local.tee 1
; CHECK-NEXT: global.set __stack_pointer
; CHECK-NEXT: local.get 1
; CHECK-NEXT: local.get 0
; CHECK-NEXT: call __fixunsdfti
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i64.load 8
; CHECK-NEXT: local.set 2
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i64.load 0
; CHECK-NEXT: local.set 3
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i32.const 16
; CHECK-NEXT: i32.add
; CHECK-NEXT: global.set __stack_pointer
; CHECK-NEXT: local.get 3
; CHECK-NEXT: i64.const 0
; CHECK-NEXT: local.get 2
; CHECK-NEXT: i64.eqz
; CHECK-NEXT: i64.select
; CHECK-NEXT: # fallthrough-return
entry:
%conv = fptoui double %x to i128
%spec.store.select = call i128 @llvm.umin.i128(i128 %conv, i128 18446744073709551616)
%conv6 = trunc i128 %spec.store.select to i64
ret i64 %conv6
}
define i64 @ustest_f64i64_mm(double %x) {
; CHECK-LABEL: ustest_f64i64_mm:
; CHECK: .functype ustest_f64i64_mm (f64) -> (i64)
; CHECK-NEXT: .local i32, i64, i64
; CHECK-NEXT: # %bb.0: # %entry
; CHECK-NEXT: global.get __stack_pointer
; CHECK-NEXT: i32.const 16
; CHECK-NEXT: i32.sub
; CHECK-NEXT: local.tee 1
; CHECK-NEXT: global.set __stack_pointer
; CHECK-NEXT: local.get 1
; CHECK-NEXT: local.get 0
; CHECK-NEXT: call __fixdfti
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i64.load 8
; CHECK-NEXT: local.set 2
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i64.load 0
; CHECK-NEXT: local.set 3
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i32.const 16
; CHECK-NEXT: i32.add
; CHECK-NEXT: global.set __stack_pointer
; CHECK-NEXT: i64.const 0
; CHECK-NEXT: local.get 3
; CHECK-NEXT: i64.const 0
; CHECK-NEXT: local.get 2
; CHECK-NEXT: i64.const 1
; CHECK-NEXT: i64.lt_s
; CHECK-NEXT: local.tee 1
; CHECK-NEXT: i64.select
; CHECK-NEXT: local.get 2
; CHECK-NEXT: i64.const 1
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i64.select
; CHECK-NEXT: i64.const 0
; CHECK-NEXT: i64.lt_s
; CHECK-NEXT: i64.select
; CHECK-NEXT: # fallthrough-return
entry:
%conv = fptosi double %x to i128
%spec.store.select = call i128 @llvm.smin.i128(i128 %conv, i128 18446744073709551616)
%spec.store.select7 = call i128 @llvm.smax.i128(i128 %spec.store.select, i128 0)
%conv6 = trunc i128 %spec.store.select7 to i64
ret i64 %conv6
}
define i64 @stest_f32i64_mm(float %x) {
; CHECK-LABEL: stest_f32i64_mm:
; CHECK: .functype stest_f32i64_mm (f32) -> (i64)
; CHECK-NEXT: # %bb.0: # %entry
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i64.trunc_sat_f32_s
; CHECK-NEXT: # fallthrough-return
entry:
%conv = fptosi float %x to i128
%spec.store.select = call i128 @llvm.smin.i128(i128 %conv, i128 9223372036854775807)
%spec.store.select7 = call i128 @llvm.smax.i128(i128 %spec.store.select, i128 -9223372036854775808)
%conv6 = trunc i128 %spec.store.select7 to i64
ret i64 %conv6
}
define i64 @utest_f32i64_mm(float %x) {
; CHECK-LABEL: utest_f32i64_mm:
; CHECK: .functype utest_f32i64_mm (f32) -> (i64)
; CHECK-NEXT: .local i32, i64, i64
; CHECK-NEXT: # %bb.0: # %entry
; CHECK-NEXT: global.get __stack_pointer
; CHECK-NEXT: i32.const 16
; CHECK-NEXT: i32.sub
; CHECK-NEXT: local.tee 1
; CHECK-NEXT: global.set __stack_pointer
; CHECK-NEXT: local.get 1
; CHECK-NEXT: local.get 0
; CHECK-NEXT: call __fixunssfti
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i64.load 8
; CHECK-NEXT: local.set 2
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i64.load 0
; CHECK-NEXT: local.set 3
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i32.const 16
; CHECK-NEXT: i32.add
; CHECK-NEXT: global.set __stack_pointer
; CHECK-NEXT: local.get 3
; CHECK-NEXT: i64.const 0
; CHECK-NEXT: local.get 2
; CHECK-NEXT: i64.eqz
; CHECK-NEXT: i64.select
; CHECK-NEXT: # fallthrough-return
entry:
%conv = fptoui float %x to i128
%spec.store.select = call i128 @llvm.umin.i128(i128 %conv, i128 18446744073709551616)
%conv6 = trunc i128 %spec.store.select to i64
ret i64 %conv6
}
define i64 @ustest_f32i64_mm(float %x) {
; CHECK-LABEL: ustest_f32i64_mm:
; CHECK: .functype ustest_f32i64_mm (f32) -> (i64)
; CHECK-NEXT: .local i32, i64, i64
; CHECK-NEXT: # %bb.0: # %entry
; CHECK-NEXT: global.get __stack_pointer
; CHECK-NEXT: i32.const 16
; CHECK-NEXT: i32.sub
; CHECK-NEXT: local.tee 1
; CHECK-NEXT: global.set __stack_pointer
; CHECK-NEXT: local.get 1
; CHECK-NEXT: local.get 0
; CHECK-NEXT: call __fixsfti
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i64.load 8
; CHECK-NEXT: local.set 2
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i64.load 0
; CHECK-NEXT: local.set 3
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i32.const 16
; CHECK-NEXT: i32.add
; CHECK-NEXT: global.set __stack_pointer
; CHECK-NEXT: i64.const 0
; CHECK-NEXT: local.get 3
; CHECK-NEXT: i64.const 0
; CHECK-NEXT: local.get 2
; CHECK-NEXT: i64.const 1
; CHECK-NEXT: i64.lt_s
; CHECK-NEXT: local.tee 1
; CHECK-NEXT: i64.select
; CHECK-NEXT: local.get 2
; CHECK-NEXT: i64.const 1
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i64.select
; CHECK-NEXT: i64.const 0
; CHECK-NEXT: i64.lt_s
; CHECK-NEXT: i64.select
; CHECK-NEXT: # fallthrough-return
entry:
%conv = fptosi float %x to i128
%spec.store.select = call i128 @llvm.smin.i128(i128 %conv, i128 18446744073709551616)
%spec.store.select7 = call i128 @llvm.smax.i128(i128 %spec.store.select, i128 0)
%conv6 = trunc i128 %spec.store.select7 to i64
ret i64 %conv6
}
define i64 @stest_f16i64_mm(half %x) {
; CHECK-LABEL: stest_f16i64_mm:
; CHECK: .functype stest_f16i64_mm (f32) -> (i64)
; CHECK-NEXT: # %bb.0: # %entry
; CHECK-NEXT: local.get 0
; CHECK-NEXT: call __truncsfhf2
; CHECK-NEXT: call __extendhfsf2
; CHECK-NEXT: i64.trunc_sat_f32_s
; CHECK-NEXT: # fallthrough-return
entry:
%conv = fptosi half %x to i128
%spec.store.select = call i128 @llvm.smin.i128(i128 %conv, i128 9223372036854775807)
%spec.store.select7 = call i128 @llvm.smax.i128(i128 %spec.store.select, i128 -9223372036854775808)
%conv6 = trunc i128 %spec.store.select7 to i64
ret i64 %conv6
}
define i64 @utesth_f16i64_mm(half %x) {
; CHECK-LABEL: utesth_f16i64_mm:
; CHECK: .functype utesth_f16i64_mm (f32) -> (i64)
; CHECK-NEXT: .local i32, i64, i64
; CHECK-NEXT: # %bb.0: # %entry
; CHECK-NEXT: global.get __stack_pointer
; CHECK-NEXT: i32.const 16
; CHECK-NEXT: i32.sub
; CHECK-NEXT: local.tee 1
; CHECK-NEXT: global.set __stack_pointer
; CHECK-NEXT: local.get 1
; CHECK-NEXT: local.get 0
; CHECK-NEXT: call __truncsfhf2
; CHECK-NEXT: call __extendhfsf2
; CHECK-NEXT: call __fixunssfti
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i64.load 8
; CHECK-NEXT: local.set 2
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i64.load 0
; CHECK-NEXT: local.set 3
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i32.const 16
; CHECK-NEXT: i32.add
; CHECK-NEXT: global.set __stack_pointer
; CHECK-NEXT: local.get 3
; CHECK-NEXT: i64.const 0
; CHECK-NEXT: local.get 2
; CHECK-NEXT: i64.eqz
; CHECK-NEXT: i64.select
; CHECK-NEXT: # fallthrough-return
entry:
%conv = fptoui half %x to i128
%spec.store.select = call i128 @llvm.umin.i128(i128 %conv, i128 18446744073709551616)
%conv6 = trunc i128 %spec.store.select to i64
ret i64 %conv6
}
define i64 @ustest_f16i64_mm(half %x) {
; CHECK-LABEL: ustest_f16i64_mm:
; CHECK: .functype ustest_f16i64_mm (f32) -> (i64)
; CHECK-NEXT: .local i32, i64, i64
; CHECK-NEXT: # %bb.0: # %entry
; CHECK-NEXT: global.get __stack_pointer
; CHECK-NEXT: i32.const 16
; CHECK-NEXT: i32.sub
; CHECK-NEXT: local.tee 1
; CHECK-NEXT: global.set __stack_pointer
; CHECK-NEXT: local.get 1
; CHECK-NEXT: local.get 0
; CHECK-NEXT: call __truncsfhf2
; CHECK-NEXT: call __extendhfsf2
; CHECK-NEXT: call __fixsfti
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i64.load 8
; CHECK-NEXT: local.set 2
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i64.load 0
; CHECK-NEXT: local.set 3
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i32.const 16
; CHECK-NEXT: i32.add
; CHECK-NEXT: global.set __stack_pointer
; CHECK-NEXT: i64.const 0
; CHECK-NEXT: local.get 3
; CHECK-NEXT: i64.const 0
; CHECK-NEXT: local.get 2
; CHECK-NEXT: i64.const 1
; CHECK-NEXT: i64.lt_s
; CHECK-NEXT: local.tee 1
; CHECK-NEXT: i64.select
; CHECK-NEXT: local.get 2
; CHECK-NEXT: i64.const 1
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i64.select
; CHECK-NEXT: i64.const 0
; CHECK-NEXT: i64.lt_s
; CHECK-NEXT: i64.select
; CHECK-NEXT: # fallthrough-return
entry:
%conv = fptosi half %x to i128
%spec.store.select = call i128 @llvm.smin.i128(i128 %conv, i128 18446744073709551616)
%spec.store.select7 = call i128 @llvm.smax.i128(i128 %spec.store.select, i128 0)
%conv6 = trunc i128 %spec.store.select7 to i64
ret i64 %conv6
}
define i64 @utesth_f16i64_mm_cse(half %x) {
; CHECK-LABEL: utesth_f16i64_mm_cse:
; CHECK: .functype utesth_f16i64_mm_cse (f32) -> (i64)
; CHECK-NEXT: .local i32, i64
; CHECK-NEXT: # %bb.0: # %entry
; CHECK-NEXT: global.get __stack_pointer
; CHECK-NEXT: i32.const 16
; CHECK-NEXT: i32.sub
; CHECK-NEXT: local.tee 1
; CHECK-NEXT: global.set __stack_pointer
; CHECK-NEXT: local.get 1
; CHECK-NEXT: local.get 0
; CHECK-NEXT: call __truncsfhf2
; CHECK-NEXT: call __extendhfsf2
; CHECK-NEXT: call __fixunssfti
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i64.load 0
; CHECK-NEXT: local.set 2
; CHECK-NEXT: local.get 1
; CHECK-NEXT: i32.const 16
; CHECK-NEXT: i32.add
; CHECK-NEXT: global.set __stack_pointer
; CHECK-NEXT: local.get 2
; CHECK-NEXT: # fallthrough-return
entry:
%conv = fptoui half %x to i128
%conv6 = trunc i128 %conv to i64
ret i64 %conv6
}
declare i32 @llvm.smin.i32(i32, i32)
declare i32 @llvm.smax.i32(i32, i32)
declare i32 @llvm.umin.i32(i32, i32)
declare i64 @llvm.smin.i64(i64, i64)
declare i64 @llvm.smax.i64(i64, i64)
declare i64 @llvm.umin.i64(i64, i64)
declare i128 @llvm.smin.i128(i128, i128)
declare i128 @llvm.smax.i128(i128, i128)
declare i128 @llvm.umin.i128(i128, i128)