[llvm] [WebAssembly][GlobalISel] Implement conversion/cast ops between integer and floating-point (PR #197255)
Demetrius Kanios via llvm-commits
llvm-commits at lists.llvm.org
Tue Jun 30 00:29:44 PDT 2026
https://github.com/QuantumSegfault updated https://github.com/llvm/llvm-project/pull/197255
>From 8c4f9e31c96d885bd13db2a1212ffad46392b61b Mon Sep 17 00:00:00 2001
From: Demetrius Kanios <demetrius at kanios.net>
Date: Mon, 11 May 2026 22:34:37 -0700
Subject: [PATCH] Implement int <=> fp ops
---
.../GISel/WebAssemblyLegalizerInfo.cpp | 28 ++
.../GlobalISel/instructions/bitcast.ll | 48 +++
.../GlobalISel/instructions/fptosi.ll | 301 ++++++++++++++++
.../GlobalISel/instructions/fptoui.ll | 325 ++++++++++++++++++
.../GlobalISel/instructions/sitofp.ll | 96 ++++++
.../GlobalISel/instructions/uitofp.ll | 100 ++++++
6 files changed, 898 insertions(+)
create mode 100644 llvm/test/CodeGen/WebAssembly/GlobalISel/instructions/bitcast.ll
create mode 100644 llvm/test/CodeGen/WebAssembly/GlobalISel/instructions/fptosi.ll
create mode 100644 llvm/test/CodeGen/WebAssembly/GlobalISel/instructions/fptoui.ll
create mode 100644 llvm/test/CodeGen/WebAssembly/GlobalISel/instructions/sitofp.ll
create mode 100644 llvm/test/CodeGen/WebAssembly/GlobalISel/instructions/uitofp.ll
diff --git a/llvm/lib/Target/WebAssembly/GISel/WebAssemblyLegalizerInfo.cpp b/llvm/lib/Target/WebAssembly/GISel/WebAssemblyLegalizerInfo.cpp
index fb499d0db1733..3b78e542cabfb 100644
--- a/llvm/lib/Target/WebAssembly/GISel/WebAssemblyLegalizerInfo.cpp
+++ b/llvm/lib/Target/WebAssembly/GISel/WebAssemblyLegalizerInfo.cpp
@@ -103,6 +103,34 @@ WebAssemblyLegalizerInfo::WebAssemblyLegalizerInfo(
.clampScalar(0, s32, s32)
.clampScalar(1, s64, s64);
+ getActionDefinitionsBuilder(G_BITCAST)
+ .legalFor({{i32, f32}, {f32, i32}, {i64, f64}, {f64, i64}})
+ .clampScalar(0, s32, s64)
+ .clampScalar(1, s32, s64);
+
+ getActionDefinitionsBuilder({G_FPTOSI, G_FPTOUI})
+ .legalForCartesianProduct({i32, i64}, {f32, f64})
+ .clampScalar(0, s32, s64)
+ .minScalar(1, s32);
+
+ // TODO: once comparison ops are in place
+ /*if (ST.hasNontrappingFPToInt()) {
+ getActionDefinitionsBuilder({G_FPTOSI_SAT, G_FPTOUI_SAT})
+ .legalForCartesianProduct({i32, i64}, {f32, f64})
+ .clampScalar(0, s32, s64)
+ .minScalar(1, s32);
+ } else {
+ getActionDefinitionsBuilder({G_FPTOSI_SAT, G_FPTOUI_SAT})
+ .lowerForCartesianProduct({i32, i64}, {f32, f64})
+ .clampScalar(0, s32, s64)
+ .minScalar(1, s32);
+ }*/
+
+ getActionDefinitionsBuilder({G_SITOFP, G_UITOFP})
+ .legalForCartesianProduct({f32, f64}, {i32, i64})
+ .minScalar(0, s32)
+ .clampScalar(1, s32, s64);
+
getLegacyLegalizerInfo().computeTables();
}
diff --git a/llvm/test/CodeGen/WebAssembly/GlobalISel/instructions/bitcast.ll b/llvm/test/CodeGen/WebAssembly/GlobalISel/instructions/bitcast.ll
new file mode 100644
index 0000000000000..6c210e6a4e58f
--- /dev/null
+++ b/llvm/test/CodeGen/WebAssembly/GlobalISel/instructions/bitcast.ll
@@ -0,0 +1,48 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc < %s -O0 --global-isel -disable-wasm-fallthrough-return-opt -wasm-keep-registers | FileCheck %s
+
+target triple = "wasm32-unknown-unknown"
+
+define float @bitcast_i32_to_f32(i32 %x) {
+; CHECK-LABEL: bitcast_i32_to_f32:
+; CHECK: .functype bitcast_i32_to_f32 (i32) -> (f32)
+; CHECK-NEXT: # %bb.0:
+; CHECK-NEXT: local.get $push1=, 0
+; CHECK-NEXT: f32.reinterpret_i32 $push0=, $pop1
+; CHECK-NEXT: return $pop0
+ %a = bitcast i32 %x to float
+ ret float %a
+}
+
+define i32 @bitcast_f32_to_i32(float %x) {
+; CHECK-LABEL: bitcast_f32_to_i32:
+; CHECK: .functype bitcast_f32_to_i32 (f32) -> (i32)
+; CHECK-NEXT: # %bb.0:
+; CHECK-NEXT: local.get $push1=, 0
+; CHECK-NEXT: i32.reinterpret_f32 $push0=, $pop1
+; CHECK-NEXT: return $pop0
+ %a = bitcast float %x to i32
+ ret i32 %a
+}
+
+define double @bitcast_i64_to_f64(i64 %x) {
+; CHECK-LABEL: bitcast_i64_to_f64:
+; CHECK: .functype bitcast_i64_to_f64 (i64) -> (f64)
+; CHECK-NEXT: # %bb.0:
+; CHECK-NEXT: local.get $push1=, 0
+; CHECK-NEXT: f64.reinterpret_i64 $push0=, $pop1
+; CHECK-NEXT: return $pop0
+ %a = bitcast i64 %x to double
+ ret double %a
+}
+
+define i64 @bitcast_f64_to_i64(double %x) {
+; CHECK-LABEL: bitcast_f64_to_i64:
+; CHECK: .functype bitcast_f64_to_i64 (f64) -> (i64)
+; CHECK-NEXT: # %bb.0:
+; CHECK-NEXT: local.get $push1=, 0
+; CHECK-NEXT: i64.reinterpret_f64 $push0=, $pop1
+; CHECK-NEXT: return $pop0
+ %a = bitcast double %x to i64
+ ret i64 %a
+}
diff --git a/llvm/test/CodeGen/WebAssembly/GlobalISel/instructions/fptosi.ll b/llvm/test/CodeGen/WebAssembly/GlobalISel/instructions/fptosi.ll
new file mode 100644
index 0000000000000..04a714e0ead76
--- /dev/null
+++ b/llvm/test/CodeGen/WebAssembly/GlobalISel/instructions/fptosi.ll
@@ -0,0 +1,301 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc < %s -O0 --global-isel -disable-wasm-fallthrough-return-opt -wasm-keep-registers -mattr=-nontrapping-fptoint | FileCheck %s -check-prefix=TRAPPING
+; RUN: llc < %s -O0 --global-isel -disable-wasm-fallthrough-return-opt -wasm-keep-registers -mattr=+nontrapping-fptoint | FileCheck %s -check-prefix=NONTRAPPING
+
+target triple = "wasm32-unknown-unknown"
+
+define i8 @fptosi_f32_to_i8(float %x) {
+; TRAPPING-LABEL: fptosi_f32_to_i8:
+; TRAPPING: .functype fptosi_f32_to_i8 (f32) -> (i32)
+; TRAPPING-NEXT: .local i32
+; TRAPPING-NEXT: # %bb.0:
+; TRAPPING-NEXT: block
+; TRAPPING-NEXT: block
+; TRAPPING-NEXT: local.get $push5=, 0
+; TRAPPING-NEXT: f32.abs $push1=, $pop5
+; TRAPPING-NEXT: f32.const $push2=, 0x1p31
+; TRAPPING-NEXT: f32.lt $push3=, $pop1, $pop2
+; TRAPPING-NEXT: i32.eqz $push4=, $pop3
+; TRAPPING-NEXT: br_if 0, $pop4 # 0: down to label1
+; TRAPPING-NEXT: # %bb.1:
+; TRAPPING-NEXT: local.get $push6=, 0
+; TRAPPING-NEXT: i32.trunc_f32_s $push7=, $pop6
+; TRAPPING-NEXT: local.set 1, $pop7
+; TRAPPING-NEXT: br 1 # 1: down to label0
+; TRAPPING-NEXT: .LBB0_2:
+; TRAPPING-NEXT: end_block # label1:
+; TRAPPING-NEXT: i32.const $push8=, -2147483648
+; TRAPPING-NEXT: local.set 1, $pop8
+; TRAPPING-NEXT: .LBB0_3:
+; TRAPPING-NEXT: end_block # label0:
+; TRAPPING-NEXT: local.get $push0=, 1
+; TRAPPING-NEXT: return $pop0
+;
+; NONTRAPPING-LABEL: fptosi_f32_to_i8:
+; NONTRAPPING: .functype fptosi_f32_to_i8 (f32) -> (i32)
+; NONTRAPPING-NEXT: # %bb.0:
+; NONTRAPPING-NEXT: local.get $push1=, 0
+; NONTRAPPING-NEXT: i32.trunc_sat_f32_s $push0=, $pop1
+; NONTRAPPING-NEXT: return $pop0
+ %a = fptosi float %x to i8
+ ret i8 %a
+}
+
+define i16 @fptosi_f32_to_i16(float %x) {
+; TRAPPING-LABEL: fptosi_f32_to_i16:
+; TRAPPING: .functype fptosi_f32_to_i16 (f32) -> (i32)
+; TRAPPING-NEXT: .local i32
+; TRAPPING-NEXT: # %bb.0:
+; TRAPPING-NEXT: block
+; TRAPPING-NEXT: block
+; TRAPPING-NEXT: local.get $push5=, 0
+; TRAPPING-NEXT: f32.abs $push1=, $pop5
+; TRAPPING-NEXT: f32.const $push2=, 0x1p31
+; TRAPPING-NEXT: f32.lt $push3=, $pop1, $pop2
+; TRAPPING-NEXT: i32.eqz $push4=, $pop3
+; TRAPPING-NEXT: br_if 0, $pop4 # 0: down to label3
+; TRAPPING-NEXT: # %bb.1:
+; TRAPPING-NEXT: local.get $push6=, 0
+; TRAPPING-NEXT: i32.trunc_f32_s $push7=, $pop6
+; TRAPPING-NEXT: local.set 1, $pop7
+; TRAPPING-NEXT: br 1 # 1: down to label2
+; TRAPPING-NEXT: .LBB1_2:
+; TRAPPING-NEXT: end_block # label3:
+; TRAPPING-NEXT: i32.const $push8=, -2147483648
+; TRAPPING-NEXT: local.set 1, $pop8
+; TRAPPING-NEXT: .LBB1_3:
+; TRAPPING-NEXT: end_block # label2:
+; TRAPPING-NEXT: local.get $push0=, 1
+; TRAPPING-NEXT: return $pop0
+;
+; NONTRAPPING-LABEL: fptosi_f32_to_i16:
+; NONTRAPPING: .functype fptosi_f32_to_i16 (f32) -> (i32)
+; NONTRAPPING-NEXT: # %bb.0:
+; NONTRAPPING-NEXT: local.get $push1=, 0
+; NONTRAPPING-NEXT: i32.trunc_sat_f32_s $push0=, $pop1
+; NONTRAPPING-NEXT: return $pop0
+ %a = fptosi float %x to i16
+ ret i16 %a
+}
+
+define i32 @fptosi_f32_to_i32(float %x) {
+; TRAPPING-LABEL: fptosi_f32_to_i32:
+; TRAPPING: .functype fptosi_f32_to_i32 (f32) -> (i32)
+; TRAPPING-NEXT: .local i32
+; TRAPPING-NEXT: # %bb.0:
+; TRAPPING-NEXT: block
+; TRAPPING-NEXT: block
+; TRAPPING-NEXT: local.get $push5=, 0
+; TRAPPING-NEXT: f32.abs $push1=, $pop5
+; TRAPPING-NEXT: f32.const $push2=, 0x1p31
+; TRAPPING-NEXT: f32.lt $push3=, $pop1, $pop2
+; TRAPPING-NEXT: i32.eqz $push4=, $pop3
+; TRAPPING-NEXT: br_if 0, $pop4 # 0: down to label5
+; TRAPPING-NEXT: # %bb.1:
+; TRAPPING-NEXT: local.get $push6=, 0
+; TRAPPING-NEXT: i32.trunc_f32_s $push7=, $pop6
+; TRAPPING-NEXT: local.set 1, $pop7
+; TRAPPING-NEXT: br 1 # 1: down to label4
+; TRAPPING-NEXT: .LBB2_2:
+; TRAPPING-NEXT: end_block # label5:
+; TRAPPING-NEXT: i32.const $push8=, -2147483648
+; TRAPPING-NEXT: local.set 1, $pop8
+; TRAPPING-NEXT: .LBB2_3:
+; TRAPPING-NEXT: end_block # label4:
+; TRAPPING-NEXT: local.get $push0=, 1
+; TRAPPING-NEXT: return $pop0
+;
+; NONTRAPPING-LABEL: fptosi_f32_to_i32:
+; NONTRAPPING: .functype fptosi_f32_to_i32 (f32) -> (i32)
+; NONTRAPPING-NEXT: # %bb.0:
+; NONTRAPPING-NEXT: local.get $push1=, 0
+; NONTRAPPING-NEXT: i32.trunc_sat_f32_s $push0=, $pop1
+; NONTRAPPING-NEXT: return $pop0
+ %a = fptosi float %x to i32
+ ret i32 %a
+}
+
+define i64 @fptosi_f32_to_i64(float %x) {
+; TRAPPING-LABEL: fptosi_f32_to_i64:
+; TRAPPING: .functype fptosi_f32_to_i64 (f32) -> (i64)
+; TRAPPING-NEXT: .local i64
+; TRAPPING-NEXT: # %bb.0:
+; TRAPPING-NEXT: block
+; TRAPPING-NEXT: block
+; TRAPPING-NEXT: local.get $push5=, 0
+; TRAPPING-NEXT: f32.abs $push1=, $pop5
+; TRAPPING-NEXT: f32.const $push2=, 0x1p63
+; TRAPPING-NEXT: f32.lt $push3=, $pop1, $pop2
+; TRAPPING-NEXT: i32.eqz $push4=, $pop3
+; TRAPPING-NEXT: br_if 0, $pop4 # 0: down to label7
+; TRAPPING-NEXT: # %bb.1:
+; TRAPPING-NEXT: local.get $push6=, 0
+; TRAPPING-NEXT: i64.trunc_f32_s $push7=, $pop6
+; TRAPPING-NEXT: local.set 1, $pop7
+; TRAPPING-NEXT: br 1 # 1: down to label6
+; TRAPPING-NEXT: .LBB3_2:
+; TRAPPING-NEXT: end_block # label7:
+; TRAPPING-NEXT: i64.const $push8=, -9223372036854775808
+; TRAPPING-NEXT: local.set 1, $pop8
+; TRAPPING-NEXT: .LBB3_3:
+; TRAPPING-NEXT: end_block # label6:
+; TRAPPING-NEXT: local.get $push0=, 1
+; TRAPPING-NEXT: return $pop0
+;
+; NONTRAPPING-LABEL: fptosi_f32_to_i64:
+; NONTRAPPING: .functype fptosi_f32_to_i64 (f32) -> (i64)
+; NONTRAPPING-NEXT: # %bb.0:
+; NONTRAPPING-NEXT: local.get $push1=, 0
+; NONTRAPPING-NEXT: i64.trunc_sat_f32_s $push0=, $pop1
+; NONTRAPPING-NEXT: return $pop0
+ %a = fptosi float %x to i64
+ ret i64 %a
+}
+
+define i8 @fptosi_f64_to_i8(double %x) {
+; TRAPPING-LABEL: fptosi_f64_to_i8:
+; TRAPPING: .functype fptosi_f64_to_i8 (f64) -> (i32)
+; TRAPPING-NEXT: .local i32
+; TRAPPING-NEXT: # %bb.0:
+; TRAPPING-NEXT: block
+; TRAPPING-NEXT: block
+; TRAPPING-NEXT: local.get $push5=, 0
+; TRAPPING-NEXT: f64.abs $push1=, $pop5
+; TRAPPING-NEXT: f64.const $push2=, 0x1p31
+; TRAPPING-NEXT: f64.lt $push3=, $pop1, $pop2
+; TRAPPING-NEXT: i32.eqz $push4=, $pop3
+; TRAPPING-NEXT: br_if 0, $pop4 # 0: down to label9
+; TRAPPING-NEXT: # %bb.1:
+; TRAPPING-NEXT: local.get $push6=, 0
+; TRAPPING-NEXT: i32.trunc_f64_s $push7=, $pop6
+; TRAPPING-NEXT: local.set 1, $pop7
+; TRAPPING-NEXT: br 1 # 1: down to label8
+; TRAPPING-NEXT: .LBB4_2:
+; TRAPPING-NEXT: end_block # label9:
+; TRAPPING-NEXT: i32.const $push8=, -2147483648
+; TRAPPING-NEXT: local.set 1, $pop8
+; TRAPPING-NEXT: .LBB4_3:
+; TRAPPING-NEXT: end_block # label8:
+; TRAPPING-NEXT: local.get $push0=, 1
+; TRAPPING-NEXT: return $pop0
+;
+; NONTRAPPING-LABEL: fptosi_f64_to_i8:
+; NONTRAPPING: .functype fptosi_f64_to_i8 (f64) -> (i32)
+; NONTRAPPING-NEXT: # %bb.0:
+; NONTRAPPING-NEXT: local.get $push1=, 0
+; NONTRAPPING-NEXT: i32.trunc_sat_f64_s $push0=, $pop1
+; NONTRAPPING-NEXT: return $pop0
+ %a = fptosi double %x to i8
+ ret i8 %a
+}
+
+define i16 @fptosi_f64_to_i16(double %x) {
+; TRAPPING-LABEL: fptosi_f64_to_i16:
+; TRAPPING: .functype fptosi_f64_to_i16 (f64) -> (i32)
+; TRAPPING-NEXT: .local i32
+; TRAPPING-NEXT: # %bb.0:
+; TRAPPING-NEXT: block
+; TRAPPING-NEXT: block
+; TRAPPING-NEXT: local.get $push5=, 0
+; TRAPPING-NEXT: f64.abs $push1=, $pop5
+; TRAPPING-NEXT: f64.const $push2=, 0x1p31
+; TRAPPING-NEXT: f64.lt $push3=, $pop1, $pop2
+; TRAPPING-NEXT: i32.eqz $push4=, $pop3
+; TRAPPING-NEXT: br_if 0, $pop4 # 0: down to label11
+; TRAPPING-NEXT: # %bb.1:
+; TRAPPING-NEXT: local.get $push6=, 0
+; TRAPPING-NEXT: i32.trunc_f64_s $push7=, $pop6
+; TRAPPING-NEXT: local.set 1, $pop7
+; TRAPPING-NEXT: br 1 # 1: down to label10
+; TRAPPING-NEXT: .LBB5_2:
+; TRAPPING-NEXT: end_block # label11:
+; TRAPPING-NEXT: i32.const $push8=, -2147483648
+; TRAPPING-NEXT: local.set 1, $pop8
+; TRAPPING-NEXT: .LBB5_3:
+; TRAPPING-NEXT: end_block # label10:
+; TRAPPING-NEXT: local.get $push0=, 1
+; TRAPPING-NEXT: return $pop0
+;
+; NONTRAPPING-LABEL: fptosi_f64_to_i16:
+; NONTRAPPING: .functype fptosi_f64_to_i16 (f64) -> (i32)
+; NONTRAPPING-NEXT: # %bb.0:
+; NONTRAPPING-NEXT: local.get $push1=, 0
+; NONTRAPPING-NEXT: i32.trunc_sat_f64_s $push0=, $pop1
+; NONTRAPPING-NEXT: return $pop0
+ %a = fptosi double %x to i16
+ ret i16 %a
+}
+
+define i32 @fptosi_f64_to_i32(double %x) {
+; TRAPPING-LABEL: fptosi_f64_to_i32:
+; TRAPPING: .functype fptosi_f64_to_i32 (f64) -> (i32)
+; TRAPPING-NEXT: .local i32
+; TRAPPING-NEXT: # %bb.0:
+; TRAPPING-NEXT: block
+; TRAPPING-NEXT: block
+; TRAPPING-NEXT: local.get $push5=, 0
+; TRAPPING-NEXT: f64.abs $push1=, $pop5
+; TRAPPING-NEXT: f64.const $push2=, 0x1p31
+; TRAPPING-NEXT: f64.lt $push3=, $pop1, $pop2
+; TRAPPING-NEXT: i32.eqz $push4=, $pop3
+; TRAPPING-NEXT: br_if 0, $pop4 # 0: down to label13
+; TRAPPING-NEXT: # %bb.1:
+; TRAPPING-NEXT: local.get $push6=, 0
+; TRAPPING-NEXT: i32.trunc_f64_s $push7=, $pop6
+; TRAPPING-NEXT: local.set 1, $pop7
+; TRAPPING-NEXT: br 1 # 1: down to label12
+; TRAPPING-NEXT: .LBB6_2:
+; TRAPPING-NEXT: end_block # label13:
+; TRAPPING-NEXT: i32.const $push8=, -2147483648
+; TRAPPING-NEXT: local.set 1, $pop8
+; TRAPPING-NEXT: .LBB6_3:
+; TRAPPING-NEXT: end_block # label12:
+; TRAPPING-NEXT: local.get $push0=, 1
+; TRAPPING-NEXT: return $pop0
+;
+; NONTRAPPING-LABEL: fptosi_f64_to_i32:
+; NONTRAPPING: .functype fptosi_f64_to_i32 (f64) -> (i32)
+; NONTRAPPING-NEXT: # %bb.0:
+; NONTRAPPING-NEXT: local.get $push1=, 0
+; NONTRAPPING-NEXT: i32.trunc_sat_f64_s $push0=, $pop1
+; NONTRAPPING-NEXT: return $pop0
+ %a = fptosi double %x to i32
+ ret i32 %a
+}
+
+define i64 @fptosi_f64_to_i64(double %x) {
+; TRAPPING-LABEL: fptosi_f64_to_i64:
+; TRAPPING: .functype fptosi_f64_to_i64 (f64) -> (i64)
+; TRAPPING-NEXT: .local i64
+; TRAPPING-NEXT: # %bb.0:
+; TRAPPING-NEXT: block
+; TRAPPING-NEXT: block
+; TRAPPING-NEXT: local.get $push5=, 0
+; TRAPPING-NEXT: f64.abs $push1=, $pop5
+; TRAPPING-NEXT: f64.const $push2=, 0x1p63
+; TRAPPING-NEXT: f64.lt $push3=, $pop1, $pop2
+; TRAPPING-NEXT: i32.eqz $push4=, $pop3
+; TRAPPING-NEXT: br_if 0, $pop4 # 0: down to label15
+; TRAPPING-NEXT: # %bb.1:
+; TRAPPING-NEXT: local.get $push6=, 0
+; TRAPPING-NEXT: i64.trunc_f64_s $push7=, $pop6
+; TRAPPING-NEXT: local.set 1, $pop7
+; TRAPPING-NEXT: br 1 # 1: down to label14
+; TRAPPING-NEXT: .LBB7_2:
+; TRAPPING-NEXT: end_block # label15:
+; TRAPPING-NEXT: i64.const $push8=, -9223372036854775808
+; TRAPPING-NEXT: local.set 1, $pop8
+; TRAPPING-NEXT: .LBB7_3:
+; TRAPPING-NEXT: end_block # label14:
+; TRAPPING-NEXT: local.get $push0=, 1
+; TRAPPING-NEXT: return $pop0
+;
+; NONTRAPPING-LABEL: fptosi_f64_to_i64:
+; NONTRAPPING: .functype fptosi_f64_to_i64 (f64) -> (i64)
+; NONTRAPPING-NEXT: # %bb.0:
+; NONTRAPPING-NEXT: local.get $push1=, 0
+; NONTRAPPING-NEXT: i64.trunc_sat_f64_s $push0=, $pop1
+; NONTRAPPING-NEXT: return $pop0
+ %a = fptosi double %x to i64
+ ret i64 %a
+}
diff --git a/llvm/test/CodeGen/WebAssembly/GlobalISel/instructions/fptoui.ll b/llvm/test/CodeGen/WebAssembly/GlobalISel/instructions/fptoui.ll
new file mode 100644
index 0000000000000..2ac18875763ee
--- /dev/null
+++ b/llvm/test/CodeGen/WebAssembly/GlobalISel/instructions/fptoui.ll
@@ -0,0 +1,325 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc < %s -O0 --global-isel -disable-wasm-fallthrough-return-opt -wasm-keep-registers -mattr=-nontrapping-fptoint | FileCheck %s -check-prefix=TRAPPING
+; RUN: llc < %s -O0 --global-isel -disable-wasm-fallthrough-return-opt -wasm-keep-registers -mattr=+nontrapping-fptoint | FileCheck %s -check-prefix=NONTRAPPING
+
+target triple = "wasm32-unknown-unknown"
+
+define i8 @fptoui_f32_to_i8(float %x) {
+; TRAPPING-LABEL: fptoui_f32_to_i8:
+; TRAPPING: .functype fptoui_f32_to_i8 (f32) -> (i32)
+; TRAPPING-NEXT: .local i32
+; TRAPPING-NEXT: # %bb.0:
+; TRAPPING-NEXT: block
+; TRAPPING-NEXT: block
+; TRAPPING-NEXT: local.get $push7=, 0
+; TRAPPING-NEXT: f32.const $push1=, 0x1p32
+; TRAPPING-NEXT: f32.lt $push2=, $pop7, $pop1
+; TRAPPING-NEXT: local.get $push8=, 0
+; TRAPPING-NEXT: f32.const $push4=, 0x0p0
+; TRAPPING-NEXT: f32.ge $push5=, $pop8, $pop4
+; TRAPPING-NEXT: i32.and $push6=, $pop2, $pop5
+; TRAPPING-NEXT: i32.eqz $push3=, $pop6
+; TRAPPING-NEXT: br_if 0, $pop3 # 0: down to label1
+; TRAPPING-NEXT: # %bb.1:
+; TRAPPING-NEXT: local.get $push9=, 0
+; TRAPPING-NEXT: i32.trunc_f32_u $push10=, $pop9
+; TRAPPING-NEXT: local.set 1, $pop10
+; TRAPPING-NEXT: br 1 # 1: down to label0
+; TRAPPING-NEXT: .LBB0_2:
+; TRAPPING-NEXT: end_block # label1:
+; TRAPPING-NEXT: i32.const $push11=, 0
+; TRAPPING-NEXT: local.set 1, $pop11
+; TRAPPING-NEXT: .LBB0_3:
+; TRAPPING-NEXT: end_block # label0:
+; TRAPPING-NEXT: local.get $push0=, 1
+; TRAPPING-NEXT: return $pop0
+;
+; NONTRAPPING-LABEL: fptoui_f32_to_i8:
+; NONTRAPPING: .functype fptoui_f32_to_i8 (f32) -> (i32)
+; NONTRAPPING-NEXT: # %bb.0:
+; NONTRAPPING-NEXT: local.get $push1=, 0
+; NONTRAPPING-NEXT: i32.trunc_sat_f32_u $push0=, $pop1
+; NONTRAPPING-NEXT: return $pop0
+ %a = fptoui float %x to i8
+ ret i8 %a
+}
+
+define i16 @fptoui_f32_to_i16(float %x) {
+; TRAPPING-LABEL: fptoui_f32_to_i16:
+; TRAPPING: .functype fptoui_f32_to_i16 (f32) -> (i32)
+; TRAPPING-NEXT: .local i32
+; TRAPPING-NEXT: # %bb.0:
+; TRAPPING-NEXT: block
+; TRAPPING-NEXT: block
+; TRAPPING-NEXT: local.get $push7=, 0
+; TRAPPING-NEXT: f32.const $push1=, 0x1p32
+; TRAPPING-NEXT: f32.lt $push2=, $pop7, $pop1
+; TRAPPING-NEXT: local.get $push8=, 0
+; TRAPPING-NEXT: f32.const $push4=, 0x0p0
+; TRAPPING-NEXT: f32.ge $push5=, $pop8, $pop4
+; TRAPPING-NEXT: i32.and $push6=, $pop2, $pop5
+; TRAPPING-NEXT: i32.eqz $push3=, $pop6
+; TRAPPING-NEXT: br_if 0, $pop3 # 0: down to label3
+; TRAPPING-NEXT: # %bb.1:
+; TRAPPING-NEXT: local.get $push9=, 0
+; TRAPPING-NEXT: i32.trunc_f32_u $push10=, $pop9
+; TRAPPING-NEXT: local.set 1, $pop10
+; TRAPPING-NEXT: br 1 # 1: down to label2
+; TRAPPING-NEXT: .LBB1_2:
+; TRAPPING-NEXT: end_block # label3:
+; TRAPPING-NEXT: i32.const $push11=, 0
+; TRAPPING-NEXT: local.set 1, $pop11
+; TRAPPING-NEXT: .LBB1_3:
+; TRAPPING-NEXT: end_block # label2:
+; TRAPPING-NEXT: local.get $push0=, 1
+; TRAPPING-NEXT: return $pop0
+;
+; NONTRAPPING-LABEL: fptoui_f32_to_i16:
+; NONTRAPPING: .functype fptoui_f32_to_i16 (f32) -> (i32)
+; NONTRAPPING-NEXT: # %bb.0:
+; NONTRAPPING-NEXT: local.get $push1=, 0
+; NONTRAPPING-NEXT: i32.trunc_sat_f32_u $push0=, $pop1
+; NONTRAPPING-NEXT: return $pop0
+ %a = fptoui float %x to i16
+ ret i16 %a
+}
+
+define i32 @fptoui_f32_to_i32(float %x) {
+; TRAPPING-LABEL: fptoui_f32_to_i32:
+; TRAPPING: .functype fptoui_f32_to_i32 (f32) -> (i32)
+; TRAPPING-NEXT: .local i32
+; TRAPPING-NEXT: # %bb.0:
+; TRAPPING-NEXT: block
+; TRAPPING-NEXT: block
+; TRAPPING-NEXT: local.get $push7=, 0
+; TRAPPING-NEXT: f32.const $push1=, 0x1p32
+; TRAPPING-NEXT: f32.lt $push2=, $pop7, $pop1
+; TRAPPING-NEXT: local.get $push8=, 0
+; TRAPPING-NEXT: f32.const $push4=, 0x0p0
+; TRAPPING-NEXT: f32.ge $push5=, $pop8, $pop4
+; TRAPPING-NEXT: i32.and $push6=, $pop2, $pop5
+; TRAPPING-NEXT: i32.eqz $push3=, $pop6
+; TRAPPING-NEXT: br_if 0, $pop3 # 0: down to label5
+; TRAPPING-NEXT: # %bb.1:
+; TRAPPING-NEXT: local.get $push9=, 0
+; TRAPPING-NEXT: i32.trunc_f32_u $push10=, $pop9
+; TRAPPING-NEXT: local.set 1, $pop10
+; TRAPPING-NEXT: br 1 # 1: down to label4
+; TRAPPING-NEXT: .LBB2_2:
+; TRAPPING-NEXT: end_block # label5:
+; TRAPPING-NEXT: i32.const $push11=, 0
+; TRAPPING-NEXT: local.set 1, $pop11
+; TRAPPING-NEXT: .LBB2_3:
+; TRAPPING-NEXT: end_block # label4:
+; TRAPPING-NEXT: local.get $push0=, 1
+; TRAPPING-NEXT: return $pop0
+;
+; NONTRAPPING-LABEL: fptoui_f32_to_i32:
+; NONTRAPPING: .functype fptoui_f32_to_i32 (f32) -> (i32)
+; NONTRAPPING-NEXT: # %bb.0:
+; NONTRAPPING-NEXT: local.get $push1=, 0
+; NONTRAPPING-NEXT: i32.trunc_sat_f32_u $push0=, $pop1
+; NONTRAPPING-NEXT: return $pop0
+ %a = fptoui float %x to i32
+ ret i32 %a
+}
+
+define i64 @fptoui_f32_to_i64(float %x) {
+; TRAPPING-LABEL: fptoui_f32_to_i64:
+; TRAPPING: .functype fptoui_f32_to_i64 (f32) -> (i64)
+; TRAPPING-NEXT: .local i64
+; TRAPPING-NEXT: # %bb.0:
+; TRAPPING-NEXT: block
+; TRAPPING-NEXT: block
+; TRAPPING-NEXT: local.get $push7=, 0
+; TRAPPING-NEXT: f32.const $push1=, 0x1p64
+; TRAPPING-NEXT: f32.lt $push2=, $pop7, $pop1
+; TRAPPING-NEXT: local.get $push8=, 0
+; TRAPPING-NEXT: f32.const $push4=, 0x0p0
+; TRAPPING-NEXT: f32.ge $push5=, $pop8, $pop4
+; TRAPPING-NEXT: i32.and $push6=, $pop2, $pop5
+; TRAPPING-NEXT: i32.eqz $push3=, $pop6
+; TRAPPING-NEXT: br_if 0, $pop3 # 0: down to label7
+; TRAPPING-NEXT: # %bb.1:
+; TRAPPING-NEXT: local.get $push9=, 0
+; TRAPPING-NEXT: i64.trunc_f32_u $push10=, $pop9
+; TRAPPING-NEXT: local.set 1, $pop10
+; TRAPPING-NEXT: br 1 # 1: down to label6
+; TRAPPING-NEXT: .LBB3_2:
+; TRAPPING-NEXT: end_block # label7:
+; TRAPPING-NEXT: i64.const $push11=, 0
+; TRAPPING-NEXT: local.set 1, $pop11
+; TRAPPING-NEXT: .LBB3_3:
+; TRAPPING-NEXT: end_block # label6:
+; TRAPPING-NEXT: local.get $push0=, 1
+; TRAPPING-NEXT: return $pop0
+;
+; NONTRAPPING-LABEL: fptoui_f32_to_i64:
+; NONTRAPPING: .functype fptoui_f32_to_i64 (f32) -> (i64)
+; NONTRAPPING-NEXT: # %bb.0:
+; NONTRAPPING-NEXT: local.get $push1=, 0
+; NONTRAPPING-NEXT: i64.trunc_sat_f32_u $push0=, $pop1
+; NONTRAPPING-NEXT: return $pop0
+ %a = fptoui float %x to i64
+ ret i64 %a
+}
+
+define i8 @fptoui_f64_to_i8(double %x) {
+; TRAPPING-LABEL: fptoui_f64_to_i8:
+; TRAPPING: .functype fptoui_f64_to_i8 (f64) -> (i32)
+; TRAPPING-NEXT: .local i32
+; TRAPPING-NEXT: # %bb.0:
+; TRAPPING-NEXT: block
+; TRAPPING-NEXT: block
+; TRAPPING-NEXT: local.get $push7=, 0
+; TRAPPING-NEXT: f64.const $push1=, 0x1p32
+; TRAPPING-NEXT: f64.lt $push2=, $pop7, $pop1
+; TRAPPING-NEXT: local.get $push8=, 0
+; TRAPPING-NEXT: f64.const $push4=, 0x0p0
+; TRAPPING-NEXT: f64.ge $push5=, $pop8, $pop4
+; TRAPPING-NEXT: i32.and $push6=, $pop2, $pop5
+; TRAPPING-NEXT: i32.eqz $push3=, $pop6
+; TRAPPING-NEXT: br_if 0, $pop3 # 0: down to label9
+; TRAPPING-NEXT: # %bb.1:
+; TRAPPING-NEXT: local.get $push9=, 0
+; TRAPPING-NEXT: i32.trunc_f64_u $push10=, $pop9
+; TRAPPING-NEXT: local.set 1, $pop10
+; TRAPPING-NEXT: br 1 # 1: down to label8
+; TRAPPING-NEXT: .LBB4_2:
+; TRAPPING-NEXT: end_block # label9:
+; TRAPPING-NEXT: i32.const $push11=, 0
+; TRAPPING-NEXT: local.set 1, $pop11
+; TRAPPING-NEXT: .LBB4_3:
+; TRAPPING-NEXT: end_block # label8:
+; TRAPPING-NEXT: local.get $push0=, 1
+; TRAPPING-NEXT: return $pop0
+;
+; NONTRAPPING-LABEL: fptoui_f64_to_i8:
+; NONTRAPPING: .functype fptoui_f64_to_i8 (f64) -> (i32)
+; NONTRAPPING-NEXT: # %bb.0:
+; NONTRAPPING-NEXT: local.get $push1=, 0
+; NONTRAPPING-NEXT: i32.trunc_sat_f64_u $push0=, $pop1
+; NONTRAPPING-NEXT: return $pop0
+ %a = fptoui double %x to i8
+ ret i8 %a
+}
+
+define i16 @fptoui_f64_to_i16(double %x) {
+; TRAPPING-LABEL: fptoui_f64_to_i16:
+; TRAPPING: .functype fptoui_f64_to_i16 (f64) -> (i32)
+; TRAPPING-NEXT: .local i32
+; TRAPPING-NEXT: # %bb.0:
+; TRAPPING-NEXT: block
+; TRAPPING-NEXT: block
+; TRAPPING-NEXT: local.get $push7=, 0
+; TRAPPING-NEXT: f64.const $push1=, 0x1p32
+; TRAPPING-NEXT: f64.lt $push2=, $pop7, $pop1
+; TRAPPING-NEXT: local.get $push8=, 0
+; TRAPPING-NEXT: f64.const $push4=, 0x0p0
+; TRAPPING-NEXT: f64.ge $push5=, $pop8, $pop4
+; TRAPPING-NEXT: i32.and $push6=, $pop2, $pop5
+; TRAPPING-NEXT: i32.eqz $push3=, $pop6
+; TRAPPING-NEXT: br_if 0, $pop3 # 0: down to label11
+; TRAPPING-NEXT: # %bb.1:
+; TRAPPING-NEXT: local.get $push9=, 0
+; TRAPPING-NEXT: i32.trunc_f64_u $push10=, $pop9
+; TRAPPING-NEXT: local.set 1, $pop10
+; TRAPPING-NEXT: br 1 # 1: down to label10
+; TRAPPING-NEXT: .LBB5_2:
+; TRAPPING-NEXT: end_block # label11:
+; TRAPPING-NEXT: i32.const $push11=, 0
+; TRAPPING-NEXT: local.set 1, $pop11
+; TRAPPING-NEXT: .LBB5_3:
+; TRAPPING-NEXT: end_block # label10:
+; TRAPPING-NEXT: local.get $push0=, 1
+; TRAPPING-NEXT: return $pop0
+;
+; NONTRAPPING-LABEL: fptoui_f64_to_i16:
+; NONTRAPPING: .functype fptoui_f64_to_i16 (f64) -> (i32)
+; NONTRAPPING-NEXT: # %bb.0:
+; NONTRAPPING-NEXT: local.get $push1=, 0
+; NONTRAPPING-NEXT: i32.trunc_sat_f64_u $push0=, $pop1
+; NONTRAPPING-NEXT: return $pop0
+ %a = fptoui double %x to i16
+ ret i16 %a
+}
+
+define i32 @fptoui_f64_to_i32(double %x) {
+; TRAPPING-LABEL: fptoui_f64_to_i32:
+; TRAPPING: .functype fptoui_f64_to_i32 (f64) -> (i32)
+; TRAPPING-NEXT: .local i32
+; TRAPPING-NEXT: # %bb.0:
+; TRAPPING-NEXT: block
+; TRAPPING-NEXT: block
+; TRAPPING-NEXT: local.get $push7=, 0
+; TRAPPING-NEXT: f64.const $push1=, 0x1p32
+; TRAPPING-NEXT: f64.lt $push2=, $pop7, $pop1
+; TRAPPING-NEXT: local.get $push8=, 0
+; TRAPPING-NEXT: f64.const $push4=, 0x0p0
+; TRAPPING-NEXT: f64.ge $push5=, $pop8, $pop4
+; TRAPPING-NEXT: i32.and $push6=, $pop2, $pop5
+; TRAPPING-NEXT: i32.eqz $push3=, $pop6
+; TRAPPING-NEXT: br_if 0, $pop3 # 0: down to label13
+; TRAPPING-NEXT: # %bb.1:
+; TRAPPING-NEXT: local.get $push9=, 0
+; TRAPPING-NEXT: i32.trunc_f64_u $push10=, $pop9
+; TRAPPING-NEXT: local.set 1, $pop10
+; TRAPPING-NEXT: br 1 # 1: down to label12
+; TRAPPING-NEXT: .LBB6_2:
+; TRAPPING-NEXT: end_block # label13:
+; TRAPPING-NEXT: i32.const $push11=, 0
+; TRAPPING-NEXT: local.set 1, $pop11
+; TRAPPING-NEXT: .LBB6_3:
+; TRAPPING-NEXT: end_block # label12:
+; TRAPPING-NEXT: local.get $push0=, 1
+; TRAPPING-NEXT: return $pop0
+;
+; NONTRAPPING-LABEL: fptoui_f64_to_i32:
+; NONTRAPPING: .functype fptoui_f64_to_i32 (f64) -> (i32)
+; NONTRAPPING-NEXT: # %bb.0:
+; NONTRAPPING-NEXT: local.get $push1=, 0
+; NONTRAPPING-NEXT: i32.trunc_sat_f64_u $push0=, $pop1
+; NONTRAPPING-NEXT: return $pop0
+ %a = fptoui double %x to i32
+ ret i32 %a
+}
+
+define i64 @fptoui_f64_to_i64(double %x) {
+; TRAPPING-LABEL: fptoui_f64_to_i64:
+; TRAPPING: .functype fptoui_f64_to_i64 (f64) -> (i64)
+; TRAPPING-NEXT: .local i64
+; TRAPPING-NEXT: # %bb.0:
+; TRAPPING-NEXT: block
+; TRAPPING-NEXT: block
+; TRAPPING-NEXT: local.get $push7=, 0
+; TRAPPING-NEXT: f64.const $push1=, 0x1p64
+; TRAPPING-NEXT: f64.lt $push2=, $pop7, $pop1
+; TRAPPING-NEXT: local.get $push8=, 0
+; TRAPPING-NEXT: f64.const $push4=, 0x0p0
+; TRAPPING-NEXT: f64.ge $push5=, $pop8, $pop4
+; TRAPPING-NEXT: i32.and $push6=, $pop2, $pop5
+; TRAPPING-NEXT: i32.eqz $push3=, $pop6
+; TRAPPING-NEXT: br_if 0, $pop3 # 0: down to label15
+; TRAPPING-NEXT: # %bb.1:
+; TRAPPING-NEXT: local.get $push9=, 0
+; TRAPPING-NEXT: i64.trunc_f64_u $push10=, $pop9
+; TRAPPING-NEXT: local.set 1, $pop10
+; TRAPPING-NEXT: br 1 # 1: down to label14
+; TRAPPING-NEXT: .LBB7_2:
+; TRAPPING-NEXT: end_block # label15:
+; TRAPPING-NEXT: i64.const $push11=, 0
+; TRAPPING-NEXT: local.set 1, $pop11
+; TRAPPING-NEXT: .LBB7_3:
+; TRAPPING-NEXT: end_block # label14:
+; TRAPPING-NEXT: local.get $push0=, 1
+; TRAPPING-NEXT: return $pop0
+;
+; NONTRAPPING-LABEL: fptoui_f64_to_i64:
+; NONTRAPPING: .functype fptoui_f64_to_i64 (f64) -> (i64)
+; NONTRAPPING-NEXT: # %bb.0:
+; NONTRAPPING-NEXT: local.get $push1=, 0
+; NONTRAPPING-NEXT: i64.trunc_sat_f64_u $push0=, $pop1
+; NONTRAPPING-NEXT: return $pop0
+ %a = fptoui double %x to i64
+ ret i64 %a
+}
diff --git a/llvm/test/CodeGen/WebAssembly/GlobalISel/instructions/sitofp.ll b/llvm/test/CodeGen/WebAssembly/GlobalISel/instructions/sitofp.ll
new file mode 100644
index 0000000000000..44aa82934831a
--- /dev/null
+++ b/llvm/test/CodeGen/WebAssembly/GlobalISel/instructions/sitofp.ll
@@ -0,0 +1,96 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc < %s -O0 --global-isel -disable-wasm-fallthrough-return-opt -wasm-keep-registers | FileCheck %s
+
+target triple = "wasm32-unknown-unknown"
+
+define float @sitofp_i8_to_f32(i8 %x) {
+; CHECK-LABEL: sitofp_i8_to_f32:
+; CHECK: .functype sitofp_i8_to_f32 (i32) -> (f32)
+; CHECK-NEXT: # %bb.0:
+; CHECK-NEXT: local.get $push2=, 0
+; CHECK-NEXT: i32.extend8_s $push1=, $pop2
+; CHECK-NEXT: f32.convert_i32_s $push0=, $pop1
+; CHECK-NEXT: return $pop0
+ %a = sitofp i8 %x to float
+ ret float %a
+}
+
+define float @sitofp_i16_to_f32(i16 %x) {
+; CHECK-LABEL: sitofp_i16_to_f32:
+; CHECK: .functype sitofp_i16_to_f32 (i32) -> (f32)
+; CHECK-NEXT: # %bb.0:
+; CHECK-NEXT: local.get $push2=, 0
+; CHECK-NEXT: i32.extend16_s $push1=, $pop2
+; CHECK-NEXT: f32.convert_i32_s $push0=, $pop1
+; CHECK-NEXT: return $pop0
+ %a = sitofp i16 %x to float
+ ret float %a
+}
+
+define float @sitofp_i32_to_f32(i32 %x) {
+; CHECK-LABEL: sitofp_i32_to_f32:
+; CHECK: .functype sitofp_i32_to_f32 (i32) -> (f32)
+; CHECK-NEXT: # %bb.0:
+; CHECK-NEXT: local.get $push1=, 0
+; CHECK-NEXT: f32.convert_i32_s $push0=, $pop1
+; CHECK-NEXT: return $pop0
+ %a = sitofp i32 %x to float
+ ret float %a
+}
+
+define float @sitofp_i64_to_f32(i64 %x) {
+; CHECK-LABEL: sitofp_i64_to_f32:
+; CHECK: .functype sitofp_i64_to_f32 (i64) -> (f32)
+; CHECK-NEXT: # %bb.0:
+; CHECK-NEXT: local.get $push1=, 0
+; CHECK-NEXT: f32.convert_i64_s $push0=, $pop1
+; CHECK-NEXT: return $pop0
+ %a = sitofp i64 %x to float
+ ret float %a
+}
+
+define double @sitofp_i8_to_f64(i8 %x) {
+; CHECK-LABEL: sitofp_i8_to_f64:
+; CHECK: .functype sitofp_i8_to_f64 (i32) -> (f64)
+; CHECK-NEXT: # %bb.0:
+; CHECK-NEXT: local.get $push2=, 0
+; CHECK-NEXT: i32.extend8_s $push1=, $pop2
+; CHECK-NEXT: f64.convert_i32_s $push0=, $pop1
+; CHECK-NEXT: return $pop0
+ %a = sitofp i8 %x to double
+ ret double %a
+}
+
+define double @sitofp_i16_to_f64(i16 %x) {
+; CHECK-LABEL: sitofp_i16_to_f64:
+; CHECK: .functype sitofp_i16_to_f64 (i32) -> (f64)
+; CHECK-NEXT: # %bb.0:
+; CHECK-NEXT: local.get $push2=, 0
+; CHECK-NEXT: i32.extend16_s $push1=, $pop2
+; CHECK-NEXT: f64.convert_i32_s $push0=, $pop1
+; CHECK-NEXT: return $pop0
+ %a = sitofp i16 %x to double
+ ret double %a
+}
+
+define double @sitofp_i32_to_f64(i32 %x) {
+; CHECK-LABEL: sitofp_i32_to_f64:
+; CHECK: .functype sitofp_i32_to_f64 (i32) -> (f64)
+; CHECK-NEXT: # %bb.0:
+; CHECK-NEXT: local.get $push1=, 0
+; CHECK-NEXT: f64.convert_i32_s $push0=, $pop1
+; CHECK-NEXT: return $pop0
+ %a = sitofp i32 %x to double
+ ret double %a
+}
+
+define double @sitofp_i64_to_f64(i64 %x) {
+; CHECK-LABEL: sitofp_i64_to_f64:
+; CHECK: .functype sitofp_i64_to_f64 (i64) -> (f64)
+; CHECK-NEXT: # %bb.0:
+; CHECK-NEXT: local.get $push1=, 0
+; CHECK-NEXT: f64.convert_i64_s $push0=, $pop1
+; CHECK-NEXT: return $pop0
+ %a = sitofp i64 %x to double
+ ret double %a
+}
diff --git a/llvm/test/CodeGen/WebAssembly/GlobalISel/instructions/uitofp.ll b/llvm/test/CodeGen/WebAssembly/GlobalISel/instructions/uitofp.ll
new file mode 100644
index 0000000000000..2348135ef2a4e
--- /dev/null
+++ b/llvm/test/CodeGen/WebAssembly/GlobalISel/instructions/uitofp.ll
@@ -0,0 +1,100 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc < %s -O0 --global-isel -disable-wasm-fallthrough-return-opt -wasm-keep-registers | FileCheck %s
+
+target triple = "wasm32-unknown-unknown"
+
+define float @uitofp_i8_to_f32(i8 %x) {
+; CHECK-LABEL: uitofp_i8_to_f32:
+; CHECK: .functype uitofp_i8_to_f32 (i32) -> (f32)
+; CHECK-NEXT: # %bb.0:
+; CHECK-NEXT: local.get $push3=, 0
+; CHECK-NEXT: i32.const $push2=, 255
+; CHECK-NEXT: i32.and $push1=, $pop3, $pop2
+; CHECK-NEXT: f32.convert_i32_u $push0=, $pop1
+; CHECK-NEXT: return $pop0
+ %a = uitofp i8 %x to float
+ ret float %a
+}
+
+define float @uitofp_i16_to_f32(i16 %x) {
+; CHECK-LABEL: uitofp_i16_to_f32:
+; CHECK: .functype uitofp_i16_to_f32 (i32) -> (f32)
+; CHECK-NEXT: # %bb.0:
+; CHECK-NEXT: local.get $push3=, 0
+; CHECK-NEXT: i32.const $push2=, 65535
+; CHECK-NEXT: i32.and $push1=, $pop3, $pop2
+; CHECK-NEXT: f32.convert_i32_u $push0=, $pop1
+; CHECK-NEXT: return $pop0
+ %a = uitofp i16 %x to float
+ ret float %a
+}
+
+define float @uitofp_i32_to_f32(i32 %x) {
+; CHECK-LABEL: uitofp_i32_to_f32:
+; CHECK: .functype uitofp_i32_to_f32 (i32) -> (f32)
+; CHECK-NEXT: # %bb.0:
+; CHECK-NEXT: local.get $push1=, 0
+; CHECK-NEXT: f32.convert_i32_u $push0=, $pop1
+; CHECK-NEXT: return $pop0
+ %a = uitofp i32 %x to float
+ ret float %a
+}
+
+define float @uitofp_i64_to_f32(i64 %x) {
+; CHECK-LABEL: uitofp_i64_to_f32:
+; CHECK: .functype uitofp_i64_to_f32 (i64) -> (f32)
+; CHECK-NEXT: # %bb.0:
+; CHECK-NEXT: local.get $push1=, 0
+; CHECK-NEXT: f32.convert_i64_u $push0=, $pop1
+; CHECK-NEXT: return $pop0
+ %a = uitofp i64 %x to float
+ ret float %a
+}
+
+define double @uitofp_i8_to_f64(i8 %x) {
+; CHECK-LABEL: uitofp_i8_to_f64:
+; CHECK: .functype uitofp_i8_to_f64 (i32) -> (f64)
+; CHECK-NEXT: # %bb.0:
+; CHECK-NEXT: local.get $push3=, 0
+; CHECK-NEXT: i32.const $push2=, 255
+; CHECK-NEXT: i32.and $push1=, $pop3, $pop2
+; CHECK-NEXT: f64.convert_i32_u $push0=, $pop1
+; CHECK-NEXT: return $pop0
+ %a = uitofp i8 %x to double
+ ret double %a
+}
+
+define double @uitofp_i16_to_f64(i16 %x) {
+; CHECK-LABEL: uitofp_i16_to_f64:
+; CHECK: .functype uitofp_i16_to_f64 (i32) -> (f64)
+; CHECK-NEXT: # %bb.0:
+; CHECK-NEXT: local.get $push3=, 0
+; CHECK-NEXT: i32.const $push2=, 65535
+; CHECK-NEXT: i32.and $push1=, $pop3, $pop2
+; CHECK-NEXT: f64.convert_i32_u $push0=, $pop1
+; CHECK-NEXT: return $pop0
+ %a = uitofp i16 %x to double
+ ret double %a
+}
+
+define double @uitofp_i32_to_f64(i32 %x) {
+; CHECK-LABEL: uitofp_i32_to_f64:
+; CHECK: .functype uitofp_i32_to_f64 (i32) -> (f64)
+; CHECK-NEXT: # %bb.0:
+; CHECK-NEXT: local.get $push1=, 0
+; CHECK-NEXT: f64.convert_i32_u $push0=, $pop1
+; CHECK-NEXT: return $pop0
+ %a = uitofp i32 %x to double
+ ret double %a
+}
+
+define double @uitofp_i64_to_f64(i64 %x) {
+; CHECK-LABEL: uitofp_i64_to_f64:
+; CHECK: .functype uitofp_i64_to_f64 (i64) -> (f64)
+; CHECK-NEXT: # %bb.0:
+; CHECK-NEXT: local.get $push1=, 0
+; CHECK-NEXT: f64.convert_i64_u $push0=, $pop1
+; CHECK-NEXT: return $pop0
+ %a = uitofp i64 %x to double
+ ret double %a
+}
More information about the llvm-commits
mailing list