diff options
author | Thomas Lively <tlively@google.com> | 2018-10-11 00:01:25 +0000 |
---|---|---|
committer | Thomas Lively <tlively@google.com> | 2018-10-11 00:01:25 +0000 |
commit | 2ebacb107bfebc7b60b238edea538570ad44cef9 (patch) | |
tree | e2dcbd81ba4e02e85be7096afe91d40b1ea5dce3 /llvm/lib | |
parent | 7b2b0185ba6c4b21906310183e92e8b32f43a0d7 (diff) | |
download | bcm5719-llvm-2ebacb107bfebc7b60b238edea538570ad44cef9.tar.gz bcm5719-llvm-2ebacb107bfebc7b60b238edea538570ad44cef9.zip |
[WebAssembly] Saturating float to int intrinsics
Summary:
Although the saturating float to int instructions are already
emitted from normal IR, the fpto{s,u}i instructions produce poison
values if the argument cannot fit in the result type. These intrinsics
are therefore necessary to get guaranteed defined saturating behavior.
Reviewers: aheejin, dschuff
Subscribers: sbc100, jgravelle-google, sunfish, llvm-commits
Differential Revision: https://reviews.llvm.org/D53004
llvm-svn: 344204
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Target/WebAssembly/WebAssemblyInstrConv.td | 18 | ||||
-rw-r--r-- | llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td | 10 |
2 files changed, 28 insertions, 0 deletions
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrConv.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrConv.td index e9ba52799ee..0d772c743a7 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrConv.td +++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrConv.td @@ -97,6 +97,24 @@ defm I64_TRUNC_U_SAT_F64 : I<(outs I64:$dst), (ins F64:$src), (outs), (ins), "i64.trunc_u:sat/f64", 0xfc07>, Requires<[HasNontrappingFPToInt]>; +// Lower llvm.wasm.trunc.saturate.* to saturating instructions +def : Pat<(int_wasm_trunc_saturate_signed F32:$src), + (I32_TRUNC_S_SAT_F32 F32:$src)>; +def : Pat<(int_wasm_trunc_saturate_unsigned F32:$src), + (I32_TRUNC_U_SAT_F32 F32:$src)>; +def : Pat<(int_wasm_trunc_saturate_signed F64:$src), + (I32_TRUNC_S_SAT_F64 F64:$src)>; +def : Pat<(int_wasm_trunc_saturate_unsigned F64:$src), + (I32_TRUNC_U_SAT_F64 F64:$src)>; +def : Pat<(int_wasm_trunc_saturate_signed F32:$src), + (I64_TRUNC_S_SAT_F32 F32:$src)>; +def : Pat<(int_wasm_trunc_saturate_unsigned F32:$src), + (I64_TRUNC_U_SAT_F32 F32:$src)>; +def : Pat<(int_wasm_trunc_saturate_signed F64:$src), + (I64_TRUNC_S_SAT_F64 F64:$src)>; +def : Pat<(int_wasm_trunc_saturate_unsigned F64:$src), + (I64_TRUNC_U_SAT_F64 F64:$src)>; + // Conversion from floating point to integer pseudo-instructions which don't // trap on overflow or invalid. let usesCustomInserter = 1, isCodeGenOnly = 1 in { diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td index 90bdc17890b..4fffd979cd6 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td +++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td @@ -782,6 +782,16 @@ defm "" : SIMDConvert<v4i32, v4f32, fp_to_uint, "i32x4.trunc_sat_u/f32x4", 148>; defm "" : SIMDConvert<v2i64, v2f64, fp_to_sint, "i64x2.trunc_sat_s/f64x2", 149>; defm "" : SIMDConvert<v2i64, v2f64, fp_to_uint, "i64x2.trunc_sat_u/f64x2", 150>; +// Lower llvm.wasm.trunc.saturate.* to saturating instructions +def : Pat<(v4i32 (int_wasm_trunc_saturate_signed (v4f32 V128:$src))), + (fp_to_sint_v4i32_v4f32 (v4f32 V128:$src))>; +def : Pat<(v4i32 (int_wasm_trunc_saturate_unsigned (v4f32 V128:$src))), + (fp_to_uint_v4i32_v4f32 (v4f32 V128:$src))>; +def : Pat<(v2i64 (int_wasm_trunc_saturate_signed (v2f64 V128:$src))), + (fp_to_sint_v2i64_v2f64 (v2f64 V128:$src))>; +def : Pat<(v2i64 (int_wasm_trunc_saturate_unsigned (v2f64 V128:$src))), + (fp_to_uint_v2i64_v2f64 (v2f64 V128:$src))>; + // Bitcasts are nops // Matching bitcast t1 to t1 causes strange errors, so avoid repeating types foreach t1 = [v16i8, v8i16, v4i32, v2i64, v4f32, v2f64] in |