[WebAssembly][GlobalISel] Implement basic floating point instructions (#194798)
Adds `RegBankSelect` support for floats, and adds legalization of most basic FP instructions. Split from #157161
This commit is contained in:
@@ -28,12 +28,19 @@ WebAssemblyLegalizerInfo::WebAssemblyLegalizerInfo(
|
||||
const LLT i32 = LLT::integer(32);
|
||||
const LLT i64 = LLT::integer(64);
|
||||
|
||||
const LLT f32 = LLT::floatIEEE(32);
|
||||
const LLT f64 = LLT::floatIEEE(64);
|
||||
|
||||
const LLT s32 = LLT::scalar(32);
|
||||
const LLT s64 = LLT::scalar(64);
|
||||
|
||||
getActionDefinitionsBuilder({G_CONSTANT, G_IMPLICIT_DEF, G_ADD, G_SUB, G_MUL,
|
||||
G_UDIV, G_SDIV, G_UREM, G_SREM, G_AND, G_OR,
|
||||
G_XOR})
|
||||
getActionDefinitionsBuilder(G_IMPLICIT_DEF)
|
||||
.legalFor({i32, i64, f32, f64})
|
||||
.widenScalarToNextPow2(0)
|
||||
.clampScalar(0, s32, s64);
|
||||
|
||||
getActionDefinitionsBuilder({G_CONSTANT, G_ADD, G_SUB, G_MUL, G_UDIV, G_SDIV,
|
||||
G_UREM, G_SREM, G_AND, G_OR, G_XOR})
|
||||
.legalFor({i32, i64})
|
||||
.widenScalarToNextPow2(0)
|
||||
.clampScalar(0, s32, s64);
|
||||
@@ -74,6 +81,28 @@ WebAssemblyLegalizerInfo::WebAssemblyLegalizerInfo(
|
||||
.clampScalar(0, s32, s64)
|
||||
.lower();
|
||||
|
||||
getActionDefinitionsBuilder({G_FCONSTANT, G_FABS, G_FNEG, G_FCEIL, G_FFLOOR,
|
||||
G_INTRINSIC_TRUNC, G_FNEARBYINT, G_FRINT,
|
||||
G_INTRINSIC_ROUNDEVEN, G_FSQRT, G_FADD, G_FSUB,
|
||||
G_FMUL, G_FDIV})
|
||||
.legalFor({f32, f64})
|
||||
.minScalar(0, s32);
|
||||
|
||||
getActionDefinitionsBuilder(G_FCOPYSIGN)
|
||||
.legalFor({f32, f64})
|
||||
.minScalar(0, s32)
|
||||
.scalarSameSizeAs(1, 0);
|
||||
|
||||
getActionDefinitionsBuilder(G_FPEXT)
|
||||
.legalFor({{f64, f32}})
|
||||
.clampScalar(0, s64, s64)
|
||||
.clampScalar(1, s32, s32);
|
||||
|
||||
getActionDefinitionsBuilder(G_FPTRUNC)
|
||||
.legalFor({{f32, f64}})
|
||||
.clampScalar(0, s32, s32)
|
||||
.clampScalar(1, s64, s64);
|
||||
|
||||
getLegacyLegalizerInfo().computeTables();
|
||||
}
|
||||
|
||||
|
||||
@@ -28,11 +28,15 @@ enum PartialMappingIdx {
|
||||
PMI_None = -1,
|
||||
PMI_I32 = 1,
|
||||
PMI_I64,
|
||||
PMI_F32,
|
||||
PMI_F64,
|
||||
PMI_Min = PMI_I32,
|
||||
};
|
||||
|
||||
const RegisterBankInfo::PartialMapping PartMappings[]{{0, 32, I32RegBank},
|
||||
{0, 64, I64RegBank}};
|
||||
{0, 64, I64RegBank},
|
||||
{0, 32, F32RegBank},
|
||||
{0, 64, F64RegBank}};
|
||||
|
||||
} // namespace WebAssembly
|
||||
} // namespace llvm
|
||||
@@ -79,6 +83,12 @@ WebAssemblyRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
|
||||
} else if (OpSize[Idx] == 64) {
|
||||
OpRegBankIdx[Idx] = WebAssembly::PMI_I64;
|
||||
}
|
||||
} else if (Ty.isFloatIEEE()) {
|
||||
if (OpSize[Idx] == 32) {
|
||||
OpRegBankIdx[Idx] = WebAssembly::PMI_F32;
|
||||
} else if (OpSize[Idx] == 64) {
|
||||
OpRegBankIdx[Idx] = WebAssembly::PMI_F64;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
; 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"
|
||||
|
||||
declare float @llvm.fabs.f32(float)
|
||||
declare double @llvm.fabs.f64(double)
|
||||
|
||||
define float @fabs_f32(float %x) {
|
||||
; CHECK-LABEL: fabs_f32:
|
||||
; CHECK: .functype fabs_f32 (f32) -> (f32)
|
||||
; CHECK-NEXT: # %bb.0:
|
||||
; CHECK-NEXT: local.get $push1=, 0
|
||||
; CHECK-NEXT: f32.abs $push0=, $pop1
|
||||
; CHECK-NEXT: return $pop0
|
||||
%a = call float @llvm.fabs.f32(float %x)
|
||||
ret float %a
|
||||
}
|
||||
|
||||
define double @fabs_f64(double %x) {
|
||||
; CHECK-LABEL: fabs_f64:
|
||||
; CHECK: .functype fabs_f64 (f64) -> (f64)
|
||||
; CHECK-NEXT: # %bb.0:
|
||||
; CHECK-NEXT: local.get $push1=, 0
|
||||
; CHECK-NEXT: f64.abs $push0=, $pop1
|
||||
; CHECK-NEXT: return $pop0
|
||||
%a = call double @llvm.fabs.f64(double %x)
|
||||
ret double %a
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
; 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 @fadd_f32(float %x, float %y) {
|
||||
; CHECK-LABEL: fadd_f32:
|
||||
; CHECK: .functype fadd_f32 (f32, f32) -> (f32)
|
||||
; CHECK-NEXT: # %bb.0:
|
||||
; CHECK-NEXT: local.get $push2=, 0
|
||||
; CHECK-NEXT: local.get $push1=, 1
|
||||
; CHECK-NEXT: f32.add $push0=, $pop2, $pop1
|
||||
; CHECK-NEXT: return $pop0
|
||||
%a = fadd float %x, %y
|
||||
ret float %a
|
||||
}
|
||||
|
||||
define double @fadd_f64(double %x, double %y) {
|
||||
; CHECK-LABEL: fadd_f64:
|
||||
; CHECK: .functype fadd_f64 (f64, f64) -> (f64)
|
||||
; CHECK-NEXT: # %bb.0:
|
||||
; CHECK-NEXT: local.get $push2=, 0
|
||||
; CHECK-NEXT: local.get $push1=, 1
|
||||
; CHECK-NEXT: f64.add $push0=, $pop2, $pop1
|
||||
; CHECK-NEXT: return $pop0
|
||||
%a = fadd double %x, %y
|
||||
ret double %a
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
; 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"
|
||||
|
||||
declare float @llvm.ceil.f32(float)
|
||||
declare double @llvm.ceil.f64(double)
|
||||
|
||||
define float @fceil_f32(float %x) {
|
||||
; CHECK-LABEL: fceil_f32:
|
||||
; CHECK: .functype fceil_f32 (f32) -> (f32)
|
||||
; CHECK-NEXT: # %bb.0:
|
||||
; CHECK-NEXT: local.get $push1=, 0
|
||||
; CHECK-NEXT: f32.ceil $push0=, $pop1
|
||||
; CHECK-NEXT: return $pop0
|
||||
%a = call float @llvm.ceil.f32(float %x)
|
||||
ret float %a
|
||||
}
|
||||
|
||||
define double @fceil_f64(double %x) {
|
||||
; CHECK-LABEL: fceil_f64:
|
||||
; CHECK: .functype fceil_f64 (f64) -> (f64)
|
||||
; CHECK-NEXT: # %bb.0:
|
||||
; CHECK-NEXT: local.get $push1=, 0
|
||||
; CHECK-NEXT: f64.ceil $push0=, $pop1
|
||||
; CHECK-NEXT: return $pop0
|
||||
%a = call double @llvm.ceil.f64(double %x)
|
||||
ret double %a
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
; 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 @const_f32() {
|
||||
; CHECK-LABEL: const_f32:
|
||||
; CHECK: .functype const_f32 () -> (f32)
|
||||
; CHECK-NEXT: # %bb.0:
|
||||
; CHECK-NEXT: f32.const $push0=, 0x1.91eb86p1
|
||||
; CHECK-NEXT: return $pop0
|
||||
ret float 3.14
|
||||
}
|
||||
|
||||
define double @const_f64() {
|
||||
; CHECK-LABEL: const_f64:
|
||||
; CHECK: .functype const_f64 () -> (f64)
|
||||
; CHECK-NEXT: # %bb.0:
|
||||
; CHECK-NEXT: f64.const $push0=, 0x1.91eb851eb851fp2
|
||||
; CHECK-NEXT: return $pop0
|
||||
ret double 6.28
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
; 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"
|
||||
|
||||
declare float @llvm.copysign.f32(float, float)
|
||||
declare double @llvm.copysign.f64(double, double)
|
||||
|
||||
define float @fcopysign_f32(float %x, float %y) {
|
||||
; CHECK-LABEL: fcopysign_f32:
|
||||
; CHECK: .functype fcopysign_f32 (f32, f32) -> (f32)
|
||||
; CHECK-NEXT: # %bb.0:
|
||||
; CHECK-NEXT: local.get $push2=, 0
|
||||
; CHECK-NEXT: local.get $push1=, 1
|
||||
; CHECK-NEXT: f32.copysign $push0=, $pop2, $pop1
|
||||
; CHECK-NEXT: return $pop0
|
||||
%a = call float @llvm.copysign.f32(float %x, float %y)
|
||||
ret float %a
|
||||
}
|
||||
|
||||
define double @fcopysign_f64(double %x, double %y) {
|
||||
; CHECK-LABEL: fcopysign_f64:
|
||||
; CHECK: .functype fcopysign_f64 (f64, f64) -> (f64)
|
||||
; CHECK-NEXT: # %bb.0:
|
||||
; CHECK-NEXT: local.get $push2=, 0
|
||||
; CHECK-NEXT: local.get $push1=, 1
|
||||
; CHECK-NEXT: f64.copysign $push0=, $pop2, $pop1
|
||||
; CHECK-NEXT: return $pop0
|
||||
%a = call double @llvm.copysign.f64(double %x, double %y)
|
||||
ret double %a
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6
|
||||
# RUN: llc -mtriple=wasm32-unknown-unknown -run-pass=legalizer,regbankselect,instruction-select %s -o - | FileCheck %s
|
||||
|
||||
---
|
||||
name: fcopysign_f32_from_f64
|
||||
tracksRegLiveness: true
|
||||
body: |
|
||||
bb.1.entry:
|
||||
liveins: $arguments
|
||||
|
||||
; CHECK-LABEL: name: fcopysign_f32_from_f64
|
||||
; CHECK: liveins: $arguments
|
||||
; CHECK-NEXT: {{ $}}
|
||||
; CHECK-NEXT: [[ARGUMENT_f32_:%[0-9]+]]:f32 = ARGUMENT_f32 0, implicit $arguments
|
||||
; CHECK-NEXT: [[ARGUMENT_f64_:%[0-9]+]]:f64 = ARGUMENT_f64 1, implicit $arguments
|
||||
; CHECK-NEXT: [[F32_DEMOTE_F64_:%[0-9]+]]:f32 = F32_DEMOTE_F64 [[ARGUMENT_f64_]], implicit-def dead $arguments
|
||||
; CHECK-NEXT: [[COPYSIGN_F32_:%[0-9]+]]:f32 = COPYSIGN_F32 [[ARGUMENT_f32_]], [[F32_DEMOTE_F64_]], implicit-def dead $arguments
|
||||
; CHECK-NEXT: RETURN [[COPYSIGN_F32_]], implicit-def $arguments
|
||||
%0:f32(f32) = ARGUMENT_f32 0, implicit $arguments
|
||||
%1:f64(f64) = ARGUMENT_f64 1, implicit $arguments
|
||||
%2:_(f32) = G_FCOPYSIGN %0, %1(f64)
|
||||
RETURN %2(f32), implicit-def $arguments
|
||||
...
|
||||
|
||||
---
|
||||
name: fcopysign_f64_from_f32
|
||||
tracksRegLiveness: true
|
||||
body: |
|
||||
bb.1.entry:
|
||||
liveins: $arguments
|
||||
|
||||
; CHECK-LABEL: name: fcopysign_f64_from_f32
|
||||
; CHECK: liveins: $arguments
|
||||
; CHECK-NEXT: {{ $}}
|
||||
; CHECK-NEXT: [[ARGUMENT_f64_:%[0-9]+]]:f64 = ARGUMENT_f64 0, implicit $arguments
|
||||
; CHECK-NEXT: [[ARGUMENT_f32_:%[0-9]+]]:f32 = ARGUMENT_f32 1, implicit $arguments
|
||||
; CHECK-NEXT: [[F64_PROMOTE_F32_:%[0-9]+]]:f64 = F64_PROMOTE_F32 [[ARGUMENT_f32_]], implicit-def dead $arguments
|
||||
; CHECK-NEXT: [[COPYSIGN_F64_:%[0-9]+]]:f64 = COPYSIGN_F64 [[ARGUMENT_f64_]], [[F64_PROMOTE_F32_]], implicit-def dead $arguments
|
||||
; CHECK-NEXT: RETURN [[COPYSIGN_F64_]], implicit-def $arguments
|
||||
%0:f64(f64) = ARGUMENT_f64 0, implicit $arguments
|
||||
%1:f32(f32) = ARGUMENT_f32 1, implicit $arguments
|
||||
%2:_(f64) = G_FCOPYSIGN %0, %1(f32)
|
||||
RETURN %2(f64), implicit-def $arguments
|
||||
...
|
||||
@@ -0,0 +1,28 @@
|
||||
; 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 @fdiv_f32(float %x, float %y) {
|
||||
; CHECK-LABEL: fdiv_f32:
|
||||
; CHECK: .functype fdiv_f32 (f32, f32) -> (f32)
|
||||
; CHECK-NEXT: # %bb.0:
|
||||
; CHECK-NEXT: local.get $push2=, 0
|
||||
; CHECK-NEXT: local.get $push1=, 1
|
||||
; CHECK-NEXT: f32.div $push0=, $pop2, $pop1
|
||||
; CHECK-NEXT: return $pop0
|
||||
%a = fdiv float %x, %y
|
||||
ret float %a
|
||||
}
|
||||
|
||||
define double @fdiv_f64(double %x, double %y) {
|
||||
; CHECK-LABEL: fdiv_f64:
|
||||
; CHECK: .functype fdiv_f64 (f64, f64) -> (f64)
|
||||
; CHECK-NEXT: # %bb.0:
|
||||
; CHECK-NEXT: local.get $push2=, 0
|
||||
; CHECK-NEXT: local.get $push1=, 1
|
||||
; CHECK-NEXT: f64.div $push0=, $pop2, $pop1
|
||||
; CHECK-NEXT: return $pop0
|
||||
%a = fdiv double %x, %y
|
||||
ret double %a
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
; 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"
|
||||
|
||||
declare float @llvm.floor.f32(float)
|
||||
declare double @llvm.floor.f64(double)
|
||||
|
||||
define float @ffloor_f32(float %x) {
|
||||
; CHECK-LABEL: ffloor_f32:
|
||||
; CHECK: .functype ffloor_f32 (f32) -> (f32)
|
||||
; CHECK-NEXT: # %bb.0:
|
||||
; CHECK-NEXT: local.get $push1=, 0
|
||||
; CHECK-NEXT: f32.floor $push0=, $pop1
|
||||
; CHECK-NEXT: return $pop0
|
||||
%a = call float @llvm.floor.f32(float %x)
|
||||
ret float %a
|
||||
}
|
||||
|
||||
define double @ffloor_f64(double %x) {
|
||||
; CHECK-LABEL: ffloor_f64:
|
||||
; CHECK: .functype ffloor_f64 (f64) -> (f64)
|
||||
; CHECK-NEXT: # %bb.0:
|
||||
; CHECK-NEXT: local.get $push1=, 0
|
||||
; CHECK-NEXT: f64.floor $push0=, $pop1
|
||||
; CHECK-NEXT: return $pop0
|
||||
%a = call double @llvm.floor.f64(double %x)
|
||||
ret double %a
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
; 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 @fmul_f32(float %x, float %y) {
|
||||
; CHECK-LABEL: fmul_f32:
|
||||
; CHECK: .functype fmul_f32 (f32, f32) -> (f32)
|
||||
; CHECK-NEXT: # %bb.0:
|
||||
; CHECK-NEXT: local.get $push2=, 0
|
||||
; CHECK-NEXT: local.get $push1=, 1
|
||||
; CHECK-NEXT: f32.mul $push0=, $pop2, $pop1
|
||||
; CHECK-NEXT: return $pop0
|
||||
%a = fmul float %x, %y
|
||||
ret float %a
|
||||
}
|
||||
|
||||
define double @fmul_f64(double %x, double %y) {
|
||||
; CHECK-LABEL: fmul_f64:
|
||||
; CHECK: .functype fmul_f64 (f64, f64) -> (f64)
|
||||
; CHECK-NEXT: # %bb.0:
|
||||
; CHECK-NEXT: local.get $push2=, 0
|
||||
; CHECK-NEXT: local.get $push1=, 1
|
||||
; CHECK-NEXT: f64.mul $push0=, $pop2, $pop1
|
||||
; CHECK-NEXT: return $pop0
|
||||
%a = fmul double %x, %y
|
||||
ret double %a
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
; 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"
|
||||
|
||||
declare float @llvm.nearbyint.f32(float)
|
||||
declare double @llvm.nearbyint.f64(double)
|
||||
|
||||
define float @fnearbyint_f32(float %x) {
|
||||
; CHECK-LABEL: fnearbyint_f32:
|
||||
; CHECK: .functype fnearbyint_f32 (f32) -> (f32)
|
||||
; CHECK-NEXT: # %bb.0:
|
||||
; CHECK-NEXT: local.get $push1=, 0
|
||||
; CHECK-NEXT: f32.nearest $push0=, $pop1
|
||||
; CHECK-NEXT: return $pop0
|
||||
%a = call float @llvm.nearbyint.f32(float %x)
|
||||
ret float %a
|
||||
}
|
||||
|
||||
define double @fnearbyint_f64(double %x) {
|
||||
; CHECK-LABEL: fnearbyint_f64:
|
||||
; CHECK: .functype fnearbyint_f64 (f64) -> (f64)
|
||||
; CHECK-NEXT: # %bb.0:
|
||||
; CHECK-NEXT: local.get $push1=, 0
|
||||
; CHECK-NEXT: f64.nearest $push0=, $pop1
|
||||
; CHECK-NEXT: return $pop0
|
||||
%a = call double @llvm.nearbyint.f64(double %x)
|
||||
ret double %a
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6
|
||||
# RUN: llc -mtriple=wasm32-unknown-unknown -run-pass=legalizer,regbankselect,instruction-select %s -o - | FileCheck %s
|
||||
|
||||
---
|
||||
name: fneg_f32
|
||||
tracksRegLiveness: true
|
||||
body: |
|
||||
bb.1.entry:
|
||||
liveins: $arguments
|
||||
|
||||
; CHECK-LABEL: name: fneg_f32
|
||||
; CHECK: liveins: $arguments
|
||||
; CHECK-NEXT: {{ $}}
|
||||
; CHECK-NEXT: [[ARGUMENT_f32_:%[0-9]+]]:f32 = ARGUMENT_f32 0, implicit $arguments
|
||||
; CHECK-NEXT: [[NEG_F32_:%[0-9]+]]:f32 = NEG_F32 [[ARGUMENT_f32_]], implicit-def dead $arguments
|
||||
; CHECK-NEXT: RETURN [[NEG_F32_]], implicit-def $arguments
|
||||
%0:f32(f32) = ARGUMENT_f32 0, implicit $arguments
|
||||
%1:_(f32) = G_FNEG %0
|
||||
RETURN %1(f32), implicit-def $arguments
|
||||
...
|
||||
---
|
||||
name: fneg_f64
|
||||
tracksRegLiveness: true
|
||||
body: |
|
||||
bb.1.entry:
|
||||
liveins: $arguments
|
||||
|
||||
; CHECK-LABEL: name: fneg_f64
|
||||
; CHECK: liveins: $arguments
|
||||
; CHECK-NEXT: {{ $}}
|
||||
; CHECK-NEXT: [[ARGUMENT_f64_:%[0-9]+]]:f64 = ARGUMENT_f64 0, implicit $arguments
|
||||
; CHECK-NEXT: [[NEG_F64_:%[0-9]+]]:f64 = NEG_F64 [[ARGUMENT_f64_]], implicit-def dead $arguments
|
||||
; CHECK-NEXT: RETURN [[NEG_F64_]], implicit-def $arguments
|
||||
%0:f64(f64) = ARGUMENT_f64 0, implicit $arguments
|
||||
%1:_(f64) = G_FNEG %0
|
||||
RETURN %1(f64), implicit-def $arguments
|
||||
...
|
||||
@@ -0,0 +1,15 @@
|
||||
; 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 double @fpext_f32_to_f64(float %x) {
|
||||
; CHECK-LABEL: fpext_f32_to_f64:
|
||||
; CHECK: .functype fpext_f32_to_f64 (f32) -> (f64)
|
||||
; CHECK-NEXT: # %bb.0:
|
||||
; CHECK-NEXT: local.get $push1=, 0
|
||||
; CHECK-NEXT: f64.promote_f32 $push0=, $pop1
|
||||
; CHECK-NEXT: return $pop0
|
||||
%a = fpext float %x to double
|
||||
ret double %a
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
; 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 @fptrunc_f64_to_f32(double %x) {
|
||||
; CHECK-LABEL: fptrunc_f64_to_f32:
|
||||
; CHECK: .functype fptrunc_f64_to_f32 (f64) -> (f32)
|
||||
; CHECK-NEXT: # %bb.0:
|
||||
; CHECK-NEXT: local.get $push1=, 0
|
||||
; CHECK-NEXT: f32.demote_f64 $push0=, $pop1
|
||||
; CHECK-NEXT: return $pop0
|
||||
%a = fptrunc double %x to float
|
||||
ret float %a
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
; 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"
|
||||
|
||||
declare float @llvm.rint.f32(float)
|
||||
declare double @llvm.rint.f64(double)
|
||||
|
||||
define float @frint_f32(float %x) {
|
||||
; CHECK-LABEL: frint_f32:
|
||||
; CHECK: .functype frint_f32 (f32) -> (f32)
|
||||
; CHECK-NEXT: # %bb.0:
|
||||
; CHECK-NEXT: local.get $push1=, 0
|
||||
; CHECK-NEXT: f32.nearest $push0=, $pop1
|
||||
; CHECK-NEXT: return $pop0
|
||||
%a = call float @llvm.rint.f32(float %x)
|
||||
ret float %a
|
||||
}
|
||||
|
||||
define double @frint_f64(double %x) {
|
||||
; CHECK-LABEL: frint_f64:
|
||||
; CHECK: .functype frint_f64 (f64) -> (f64)
|
||||
; CHECK-NEXT: # %bb.0:
|
||||
; CHECK-NEXT: local.get $push1=, 0
|
||||
; CHECK-NEXT: f64.nearest $push0=, $pop1
|
||||
; CHECK-NEXT: return $pop0
|
||||
%a = call double @llvm.rint.f64(double %x)
|
||||
ret double %a
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
; 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"
|
||||
|
||||
declare float @llvm.sqrt.f32(float)
|
||||
declare double @llvm.sqrt.f64(double)
|
||||
|
||||
define float @fsqrt_f32(float %x) {
|
||||
; CHECK-LABEL: fsqrt_f32:
|
||||
; CHECK: .functype fsqrt_f32 (f32) -> (f32)
|
||||
; CHECK-NEXT: # %bb.0:
|
||||
; CHECK-NEXT: local.get $push1=, 0
|
||||
; CHECK-NEXT: f32.sqrt $push0=, $pop1
|
||||
; CHECK-NEXT: return $pop0
|
||||
%a = call float @llvm.sqrt.f32(float %x)
|
||||
ret float %a
|
||||
}
|
||||
|
||||
define double @fsqrt_f64(double %x) {
|
||||
; CHECK-LABEL: fsqrt_f64:
|
||||
; CHECK: .functype fsqrt_f64 (f64) -> (f64)
|
||||
; CHECK-NEXT: # %bb.0:
|
||||
; CHECK-NEXT: local.get $push1=, 0
|
||||
; CHECK-NEXT: f64.sqrt $push0=, $pop1
|
||||
; CHECK-NEXT: return $pop0
|
||||
%a = call double @llvm.sqrt.f64(double %x)
|
||||
ret double %a
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
; 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 @fsub_f32(float %x, float %y) {
|
||||
; CHECK-LABEL: fsub_f32:
|
||||
; CHECK: .functype fsub_f32 (f32, f32) -> (f32)
|
||||
; CHECK-NEXT: # %bb.0:
|
||||
; CHECK-NEXT: local.get $push2=, 0
|
||||
; CHECK-NEXT: local.get $push1=, 1
|
||||
; CHECK-NEXT: f32.sub $push0=, $pop2, $pop1
|
||||
; CHECK-NEXT: return $pop0
|
||||
%a = fsub float %x, %y
|
||||
ret float %a
|
||||
}
|
||||
|
||||
define double @fsub_f64(double %x, double %y) {
|
||||
; CHECK-LABEL: fsub_f64:
|
||||
; CHECK: .functype fsub_f64 (f64, f64) -> (f64)
|
||||
; CHECK-NEXT: # %bb.0:
|
||||
; CHECK-NEXT: local.get $push2=, 0
|
||||
; CHECK-NEXT: local.get $push1=, 1
|
||||
; CHECK-NEXT: f64.sub $push0=, $pop2, $pop1
|
||||
; CHECK-NEXT: return $pop0
|
||||
%a = fsub double %x, %y
|
||||
ret double %a
|
||||
}
|
||||
@@ -66,3 +66,35 @@ body: |
|
||||
%0:_(i64) = G_IMPLICIT_DEF
|
||||
RETURN %0(i64), implicit-def $arguments
|
||||
...
|
||||
|
||||
---
|
||||
name: implicit_def_f32
|
||||
tracksRegLiveness: true
|
||||
body: |
|
||||
bb.1.entry:
|
||||
liveins: $arguments
|
||||
|
||||
; CHECK-LABEL: name: implicit_def_f32
|
||||
; CHECK: liveins: $arguments
|
||||
; CHECK-NEXT: {{ $}}
|
||||
; CHECK-NEXT: [[DEF:%[0-9]+]]:f32 = IMPLICIT_DEF
|
||||
; CHECK-NEXT: RETURN [[DEF]], implicit-def $arguments
|
||||
%0:_(f32) = G_IMPLICIT_DEF
|
||||
RETURN %0(f32), implicit-def $arguments
|
||||
...
|
||||
|
||||
---
|
||||
name: implicit_def_f64
|
||||
tracksRegLiveness: true
|
||||
body: |
|
||||
bb.1.entry:
|
||||
liveins: $arguments
|
||||
|
||||
; CHECK-LABEL: name: implicit_def_f64
|
||||
; CHECK: liveins: $arguments
|
||||
; CHECK-NEXT: {{ $}}
|
||||
; CHECK-NEXT: [[DEF:%[0-9]+]]:f64 = IMPLICIT_DEF
|
||||
; CHECK-NEXT: RETURN [[DEF]], implicit-def $arguments
|
||||
%0:_(f64) = G_IMPLICIT_DEF
|
||||
RETURN %0(f64), implicit-def $arguments
|
||||
...
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
; 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"
|
||||
|
||||
declare float @llvm.round.f32(float)
|
||||
declare double @llvm.roundeven.f64(double)
|
||||
|
||||
define float @intrinsic_roundeven_f32(float %x) {
|
||||
; CHECK-LABEL: intrinsic_roundeven_f32:
|
||||
; CHECK: .functype intrinsic_roundeven_f32 (f32) -> (f32)
|
||||
; CHECK-NEXT: # %bb.0:
|
||||
; CHECK-NEXT: local.get $push1=, 0
|
||||
; CHECK-NEXT: f32.nearest $push0=, $pop1
|
||||
; CHECK-NEXT: return $pop0
|
||||
%a = call float @llvm.roundeven.f32(float %x)
|
||||
ret float %a
|
||||
}
|
||||
|
||||
define double @intrinsic_roundeven_f64(double %x) {
|
||||
; CHECK-LABEL: intrinsic_roundeven_f64:
|
||||
; CHECK: .functype intrinsic_roundeven_f64 (f64) -> (f64)
|
||||
; CHECK-NEXT: # %bb.0:
|
||||
; CHECK-NEXT: local.get $push1=, 0
|
||||
; CHECK-NEXT: f64.nearest $push0=, $pop1
|
||||
; CHECK-NEXT: return $pop0
|
||||
%a = call double @llvm.roundeven.f64(double %x)
|
||||
ret double %a
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
; 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"
|
||||
|
||||
declare float @llvm.trunc.f32(float)
|
||||
declare double @llvm.trunc.f64(double)
|
||||
|
||||
define float @intrinsic_trunc_f32(float %x) {
|
||||
; CHECK-LABEL: intrinsic_trunc_f32:
|
||||
; CHECK: .functype intrinsic_trunc_f32 (f32) -> (f32)
|
||||
; CHECK-NEXT: # %bb.0:
|
||||
; CHECK-NEXT: local.get $push1=, 0
|
||||
; CHECK-NEXT: f32.trunc $push0=, $pop1
|
||||
; CHECK-NEXT: return $pop0
|
||||
%a = call float @llvm.trunc.f32(float %x)
|
||||
ret float %a
|
||||
}
|
||||
|
||||
define double @intrinsic_trunc_f64(double %x) {
|
||||
; CHECK-LABEL: intrinsic_trunc_f64:
|
||||
; CHECK: .functype intrinsic_trunc_f64 (f64) -> (f64)
|
||||
; CHECK-NEXT: # %bb.0:
|
||||
; CHECK-NEXT: local.get $push1=, 0
|
||||
; CHECK-NEXT: f64.trunc $push0=, $pop1
|
||||
; CHECK-NEXT: return $pop0
|
||||
%a = call double @llvm.trunc.f64(double %x)
|
||||
ret double %a
|
||||
}
|
||||
Reference in New Issue
Block a user