[llvm] [AArch64][GlobalISel] Expand handling for sitofp and uitofp (PR #71282)
via llvm-commits
llvm-commits at lists.llvm.org
Sat Nov 4 05:31:51 PDT 2023
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-aarch64
Author: David Green (davemgreen)
<details>
<summary>Changes</summary>
Similar to #<!-- -->70635, this expands the handling of integer to fp conversions. The code is very similar to the float->integer conversions with types handled oppositely. There are some extra unhandled cases which require more handling for ASR operations.
---
Patch is 230.88 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/71282.diff
3 Files Affected:
- (modified) llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp (+3-1)
- (modified) llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp (+26-3)
- (added) llvm/test/CodeGen/AArch64/itofp.ll (+6195)
``````````diff
diff --git a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
index 00d9f3f7c30c95f..cde5bc7d9a981f1 100644
--- a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
@@ -5126,7 +5126,9 @@ LegalizerHelper::moreElementsVector(MachineInstr &MI, unsigned TypeIdx,
case TargetOpcode::G_FPTRUNC:
case TargetOpcode::G_FPEXT:
case TargetOpcode::G_FPTOSI:
- case TargetOpcode::G_FPTOUI: {
+ case TargetOpcode::G_FPTOUI:
+ case TargetOpcode::G_SITOFP:
+ case TargetOpcode::G_UITOFP: {
if (TypeIdx != 0)
return UnableToLegalize;
Observer.changingInstr(MI);
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
index 7edfa41d237836a..cd64be96e2d6b57 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
@@ -673,10 +673,33 @@ AArch64LegalizerInfo::AArch64LegalizerInfo(const AArch64Subtarget &ST)
getActionDefinitionsBuilder({G_SITOFP, G_UITOFP})
.legalForCartesianProduct({s32, s64, v2s64, v4s32, v2s32})
+ .legalIf([=](const LegalityQuery &Query) {
+ return HasFP16 &&
+ (Query.Types[0] == s16 || Query.Types[0] == v4s16 ||
+ Query.Types[0] == v8s16) &&
+ (Query.Types[1] == s32 || Query.Types[1] == s64 ||
+ Query.Types[1] == v4s16 || Query.Types[1] == v8s16);
+ })
+ .widenScalarToNextPow2(1)
.clampScalar(1, s32, s64)
- .minScalarSameAs(1, 0)
- .clampScalar(0, s32, s64)
- .widenScalarToNextPow2(0);
+ .widenScalarToNextPow2(0)
+ .clampScalarOrElt(0, MinFPScalar, s64)
+ .moreElementsToNextPow2(0)
+ .widenScalarIf(
+ [=](const LegalityQuery &Query) {
+ return Query.Types[0].getScalarSizeInBits() <
+ Query.Types[1].getScalarSizeInBits();
+ },
+ LegalizeMutations::changeElementSizeTo(0, 1))
+ .widenScalarIf(
+ [=](const LegalityQuery &Query) {
+ return Query.Types[0].getScalarSizeInBits() >
+ Query.Types[1].getScalarSizeInBits();
+ },
+ LegalizeMutations::changeElementSizeTo(1, 0))
+ .clampNumElements(0, v4s16, v8s16)
+ .clampNumElements(0, v2s32, v4s32)
+ .clampMaxNumElements(0, s64, 2);
// Control-flow
getActionDefinitionsBuilder(G_BRCOND)
diff --git a/llvm/test/CodeGen/AArch64/itofp.ll b/llvm/test/CodeGen/AArch64/itofp.ll
new file mode 100644
index 000000000000000..fa5902c65ce05a0
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/itofp.ll
@@ -0,0 +1,6195 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3
+; RUN: llc -mtriple=aarch64-none-eabi -verify-machineinstrs %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-SD,CHECK-SD-NOFP16
+; RUN: llc -mtriple=aarch64-none-eabi -mattr=+fullfp16 -verify-machineinstrs %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-SD,CHECK-SD-FP16
+; RUN: llc -mtriple=aarch64-none-eabi -global-isel -global-isel-abort=2 -verify-machineinstrs %s -o - 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-GI,CHECK-GI-NOFP16
+; RUN: llc -mtriple=aarch64-none-eabi -mattr=+fullfp16 -global-isel -global-isel-abort=2 -verify-machineinstrs %s -o - 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-GI,CHECK-GI-FP16
+
+; CHECK-GI: warning: Instruction selection used fallback path for stofp_v3i8_v3f64
+; CHECK-GI-NEXT: warning: Instruction selection used fallback path for utofp_v3i8_v3f64
+; CHECK-GI-NEXT: warning: Instruction selection used fallback path for stofp_v3i8_v3f32
+; CHECK-GI-NEXT: warning: Instruction selection used fallback path for utofp_v3i8_v3f32
+; CHECK-GI-NOFP16-NEXT: warning: Instruction selection used fallback path for stofp_v3i8_v3f16
+; CHECK-GI-NOFP16-NEXT: warning: Instruction selection used fallback path for utofp_v3i8_v3f16
+; CHECK-GI-FP16-NEXT: warning: Instruction selection used fallback path for stofp_v2i8_v2f16
+
+define double @stofp_i64_f64(i64 %a) {
+; CHECK-LABEL: stofp_i64_f64:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: scvtf d0, x0
+; CHECK-NEXT: ret
+entry:
+ %c = sitofp i64 %a to double
+ ret double %c
+}
+
+define double @utofp_i64_f64(i64 %a) {
+; CHECK-LABEL: utofp_i64_f64:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: ucvtf d0, x0
+; CHECK-NEXT: ret
+entry:
+ %c = uitofp i64 %a to double
+ ret double %c
+}
+
+define double @stofp_i32_f64(i32 %a) {
+; CHECK-LABEL: stofp_i32_f64:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: scvtf d0, w0
+; CHECK-NEXT: ret
+entry:
+ %c = sitofp i32 %a to double
+ ret double %c
+}
+
+define double @utofp_i32_f64(i32 %a) {
+; CHECK-LABEL: utofp_i32_f64:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: ucvtf d0, w0
+; CHECK-NEXT: ret
+entry:
+ %c = uitofp i32 %a to double
+ ret double %c
+}
+
+define double @stofp_i16_f64(i16 %a) {
+; CHECK-LABEL: stofp_i16_f64:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: sxth w8, w0
+; CHECK-NEXT: scvtf d0, w8
+; CHECK-NEXT: ret
+entry:
+ %c = sitofp i16 %a to double
+ ret double %c
+}
+
+define double @utofp_i16_f64(i16 %a) {
+; CHECK-LABEL: utofp_i16_f64:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: and w8, w0, #0xffff
+; CHECK-NEXT: ucvtf d0, w8
+; CHECK-NEXT: ret
+entry:
+ %c = uitofp i16 %a to double
+ ret double %c
+}
+
+define double @stofp_i8_f64(i8 %a) {
+; CHECK-LABEL: stofp_i8_f64:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: sxtb w8, w0
+; CHECK-NEXT: scvtf d0, w8
+; CHECK-NEXT: ret
+entry:
+ %c = sitofp i8 %a to double
+ ret double %c
+}
+
+define double @utofp_i8_f64(i8 %a) {
+; CHECK-LABEL: utofp_i8_f64:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: and w8, w0, #0xff
+; CHECK-NEXT: ucvtf d0, w8
+; CHECK-NEXT: ret
+entry:
+ %c = uitofp i8 %a to double
+ ret double %c
+}
+
+define float @stofp_i64_f32(i64 %a) {
+; CHECK-LABEL: stofp_i64_f32:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: scvtf s0, x0
+; CHECK-NEXT: ret
+entry:
+ %c = sitofp i64 %a to float
+ ret float %c
+}
+
+define float @utofp_i64_f32(i64 %a) {
+; CHECK-LABEL: utofp_i64_f32:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: ucvtf s0, x0
+; CHECK-NEXT: ret
+entry:
+ %c = uitofp i64 %a to float
+ ret float %c
+}
+
+define float @stofp_i32_f32(i32 %a) {
+; CHECK-LABEL: stofp_i32_f32:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: scvtf s0, w0
+; CHECK-NEXT: ret
+entry:
+ %c = sitofp i32 %a to float
+ ret float %c
+}
+
+define float @utofp_i32_f32(i32 %a) {
+; CHECK-LABEL: utofp_i32_f32:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: ucvtf s0, w0
+; CHECK-NEXT: ret
+entry:
+ %c = uitofp i32 %a to float
+ ret float %c
+}
+
+define float @stofp_i16_f32(i16 %a) {
+; CHECK-LABEL: stofp_i16_f32:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: sxth w8, w0
+; CHECK-NEXT: scvtf s0, w8
+; CHECK-NEXT: ret
+entry:
+ %c = sitofp i16 %a to float
+ ret float %c
+}
+
+define float @utofp_i16_f32(i16 %a) {
+; CHECK-LABEL: utofp_i16_f32:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: and w8, w0, #0xffff
+; CHECK-NEXT: ucvtf s0, w8
+; CHECK-NEXT: ret
+entry:
+ %c = uitofp i16 %a to float
+ ret float %c
+}
+
+define float @stofp_i8_f32(i8 %a) {
+; CHECK-LABEL: stofp_i8_f32:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: sxtb w8, w0
+; CHECK-NEXT: scvtf s0, w8
+; CHECK-NEXT: ret
+entry:
+ %c = sitofp i8 %a to float
+ ret float %c
+}
+
+define float @utofp_i8_f32(i8 %a) {
+; CHECK-LABEL: utofp_i8_f32:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: and w8, w0, #0xff
+; CHECK-NEXT: ucvtf s0, w8
+; CHECK-NEXT: ret
+entry:
+ %c = uitofp i8 %a to float
+ ret float %c
+}
+
+define half @stofp_i64_f16(i64 %a) {
+; CHECK-SD-NOFP16-LABEL: stofp_i64_f16:
+; CHECK-SD-NOFP16: // %bb.0: // %entry
+; CHECK-SD-NOFP16-NEXT: scvtf s0, x0
+; CHECK-SD-NOFP16-NEXT: fcvt h0, s0
+; CHECK-SD-NOFP16-NEXT: ret
+;
+; CHECK-SD-FP16-LABEL: stofp_i64_f16:
+; CHECK-SD-FP16: // %bb.0: // %entry
+; CHECK-SD-FP16-NEXT: scvtf h0, x0
+; CHECK-SD-FP16-NEXT: ret
+;
+; CHECK-GI-NOFP16-LABEL: stofp_i64_f16:
+; CHECK-GI-NOFP16: // %bb.0: // %entry
+; CHECK-GI-NOFP16-NEXT: scvtf s0, x0
+; CHECK-GI-NOFP16-NEXT: fcvt h0, s0
+; CHECK-GI-NOFP16-NEXT: ret
+;
+; CHECK-GI-FP16-LABEL: stofp_i64_f16:
+; CHECK-GI-FP16: // %bb.0: // %entry
+; CHECK-GI-FP16-NEXT: scvtf h0, x0
+; CHECK-GI-FP16-NEXT: ret
+entry:
+ %c = sitofp i64 %a to half
+ ret half %c
+}
+
+define half @utofp_i64_f16(i64 %a) {
+; CHECK-SD-NOFP16-LABEL: utofp_i64_f16:
+; CHECK-SD-NOFP16: // %bb.0: // %entry
+; CHECK-SD-NOFP16-NEXT: ucvtf s0, x0
+; CHECK-SD-NOFP16-NEXT: fcvt h0, s0
+; CHECK-SD-NOFP16-NEXT: ret
+;
+; CHECK-SD-FP16-LABEL: utofp_i64_f16:
+; CHECK-SD-FP16: // %bb.0: // %entry
+; CHECK-SD-FP16-NEXT: ucvtf h0, x0
+; CHECK-SD-FP16-NEXT: ret
+;
+; CHECK-GI-NOFP16-LABEL: utofp_i64_f16:
+; CHECK-GI-NOFP16: // %bb.0: // %entry
+; CHECK-GI-NOFP16-NEXT: ucvtf s0, x0
+; CHECK-GI-NOFP16-NEXT: fcvt h0, s0
+; CHECK-GI-NOFP16-NEXT: ret
+;
+; CHECK-GI-FP16-LABEL: utofp_i64_f16:
+; CHECK-GI-FP16: // %bb.0: // %entry
+; CHECK-GI-FP16-NEXT: ucvtf h0, x0
+; CHECK-GI-FP16-NEXT: ret
+entry:
+ %c = uitofp i64 %a to half
+ ret half %c
+}
+
+define half @stofp_i32_f16(i32 %a) {
+; CHECK-SD-NOFP16-LABEL: stofp_i32_f16:
+; CHECK-SD-NOFP16: // %bb.0: // %entry
+; CHECK-SD-NOFP16-NEXT: scvtf s0, w0
+; CHECK-SD-NOFP16-NEXT: fcvt h0, s0
+; CHECK-SD-NOFP16-NEXT: ret
+;
+; CHECK-SD-FP16-LABEL: stofp_i32_f16:
+; CHECK-SD-FP16: // %bb.0: // %entry
+; CHECK-SD-FP16-NEXT: scvtf h0, w0
+; CHECK-SD-FP16-NEXT: ret
+;
+; CHECK-GI-NOFP16-LABEL: stofp_i32_f16:
+; CHECK-GI-NOFP16: // %bb.0: // %entry
+; CHECK-GI-NOFP16-NEXT: scvtf s0, w0
+; CHECK-GI-NOFP16-NEXT: fcvt h0, s0
+; CHECK-GI-NOFP16-NEXT: ret
+;
+; CHECK-GI-FP16-LABEL: stofp_i32_f16:
+; CHECK-GI-FP16: // %bb.0: // %entry
+; CHECK-GI-FP16-NEXT: scvtf h0, w0
+; CHECK-GI-FP16-NEXT: ret
+entry:
+ %c = sitofp i32 %a to half
+ ret half %c
+}
+
+define half @utofp_i32_f16(i32 %a) {
+; CHECK-SD-NOFP16-LABEL: utofp_i32_f16:
+; CHECK-SD-NOFP16: // %bb.0: // %entry
+; CHECK-SD-NOFP16-NEXT: ucvtf s0, w0
+; CHECK-SD-NOFP16-NEXT: fcvt h0, s0
+; CHECK-SD-NOFP16-NEXT: ret
+;
+; CHECK-SD-FP16-LABEL: utofp_i32_f16:
+; CHECK-SD-FP16: // %bb.0: // %entry
+; CHECK-SD-FP16-NEXT: ucvtf h0, w0
+; CHECK-SD-FP16-NEXT: ret
+;
+; CHECK-GI-NOFP16-LABEL: utofp_i32_f16:
+; CHECK-GI-NOFP16: // %bb.0: // %entry
+; CHECK-GI-NOFP16-NEXT: ucvtf s0, w0
+; CHECK-GI-NOFP16-NEXT: fcvt h0, s0
+; CHECK-GI-NOFP16-NEXT: ret
+;
+; CHECK-GI-FP16-LABEL: utofp_i32_f16:
+; CHECK-GI-FP16: // %bb.0: // %entry
+; CHECK-GI-FP16-NEXT: ucvtf h0, w0
+; CHECK-GI-FP16-NEXT: ret
+entry:
+ %c = uitofp i32 %a to half
+ ret half %c
+}
+
+define half @stofp_i16_f16(i16 %a) {
+; CHECK-SD-NOFP16-LABEL: stofp_i16_f16:
+; CHECK-SD-NOFP16: // %bb.0: // %entry
+; CHECK-SD-NOFP16-NEXT: sxth w8, w0
+; CHECK-SD-NOFP16-NEXT: scvtf s0, w8
+; CHECK-SD-NOFP16-NEXT: fcvt h0, s0
+; CHECK-SD-NOFP16-NEXT: ret
+;
+; CHECK-SD-FP16-LABEL: stofp_i16_f16:
+; CHECK-SD-FP16: // %bb.0: // %entry
+; CHECK-SD-FP16-NEXT: sxth w8, w0
+; CHECK-SD-FP16-NEXT: scvtf h0, w8
+; CHECK-SD-FP16-NEXT: ret
+;
+; CHECK-GI-NOFP16-LABEL: stofp_i16_f16:
+; CHECK-GI-NOFP16: // %bb.0: // %entry
+; CHECK-GI-NOFP16-NEXT: sxth w8, w0
+; CHECK-GI-NOFP16-NEXT: scvtf s0, w8
+; CHECK-GI-NOFP16-NEXT: fcvt h0, s0
+; CHECK-GI-NOFP16-NEXT: ret
+;
+; CHECK-GI-FP16-LABEL: stofp_i16_f16:
+; CHECK-GI-FP16: // %bb.0: // %entry
+; CHECK-GI-FP16-NEXT: sxth w8, w0
+; CHECK-GI-FP16-NEXT: scvtf h0, w8
+; CHECK-GI-FP16-NEXT: ret
+entry:
+ %c = sitofp i16 %a to half
+ ret half %c
+}
+
+define half @utofp_i16_f16(i16 %a) {
+; CHECK-SD-NOFP16-LABEL: utofp_i16_f16:
+; CHECK-SD-NOFP16: // %bb.0: // %entry
+; CHECK-SD-NOFP16-NEXT: and w8, w0, #0xffff
+; CHECK-SD-NOFP16-NEXT: ucvtf s0, w8
+; CHECK-SD-NOFP16-NEXT: fcvt h0, s0
+; CHECK-SD-NOFP16-NEXT: ret
+;
+; CHECK-SD-FP16-LABEL: utofp_i16_f16:
+; CHECK-SD-FP16: // %bb.0: // %entry
+; CHECK-SD-FP16-NEXT: and w8, w0, #0xffff
+; CHECK-SD-FP16-NEXT: ucvtf h0, w8
+; CHECK-SD-FP16-NEXT: ret
+;
+; CHECK-GI-NOFP16-LABEL: utofp_i16_f16:
+; CHECK-GI-NOFP16: // %bb.0: // %entry
+; CHECK-GI-NOFP16-NEXT: and w8, w0, #0xffff
+; CHECK-GI-NOFP16-NEXT: ucvtf s0, w8
+; CHECK-GI-NOFP16-NEXT: fcvt h0, s0
+; CHECK-GI-NOFP16-NEXT: ret
+;
+; CHECK-GI-FP16-LABEL: utofp_i16_f16:
+; CHECK-GI-FP16: // %bb.0: // %entry
+; CHECK-GI-FP16-NEXT: and w8, w0, #0xffff
+; CHECK-GI-FP16-NEXT: ucvtf h0, w8
+; CHECK-GI-FP16-NEXT: ret
+entry:
+ %c = uitofp i16 %a to half
+ ret half %c
+}
+
+define half @stofp_i8_f16(i8 %a) {
+; CHECK-SD-NOFP16-LABEL: stofp_i8_f16:
+; CHECK-SD-NOFP16: // %bb.0: // %entry
+; CHECK-SD-NOFP16-NEXT: sxtb w8, w0
+; CHECK-SD-NOFP16-NEXT: scvtf s0, w8
+; CHECK-SD-NOFP16-NEXT: fcvt h0, s0
+; CHECK-SD-NOFP16-NEXT: ret
+;
+; CHECK-SD-FP16-LABEL: stofp_i8_f16:
+; CHECK-SD-FP16: // %bb.0: // %entry
+; CHECK-SD-FP16-NEXT: sxtb w8, w0
+; CHECK-SD-FP16-NEXT: scvtf h0, w8
+; CHECK-SD-FP16-NEXT: ret
+;
+; CHECK-GI-NOFP16-LABEL: stofp_i8_f16:
+; CHECK-GI-NOFP16: // %bb.0: // %entry
+; CHECK-GI-NOFP16-NEXT: sxtb w8, w0
+; CHECK-GI-NOFP16-NEXT: scvtf s0, w8
+; CHECK-GI-NOFP16-NEXT: fcvt h0, s0
+; CHECK-GI-NOFP16-NEXT: ret
+;
+; CHECK-GI-FP16-LABEL: stofp_i8_f16:
+; CHECK-GI-FP16: // %bb.0: // %entry
+; CHECK-GI-FP16-NEXT: sxtb w8, w0
+; CHECK-GI-FP16-NEXT: scvtf h0, w8
+; CHECK-GI-FP16-NEXT: ret
+entry:
+ %c = sitofp i8 %a to half
+ ret half %c
+}
+
+define half @utofp_i8_f16(i8 %a) {
+; CHECK-SD-NOFP16-LABEL: utofp_i8_f16:
+; CHECK-SD-NOFP16: // %bb.0: // %entry
+; CHECK-SD-NOFP16-NEXT: and w8, w0, #0xff
+; CHECK-SD-NOFP16-NEXT: ucvtf s0, w8
+; CHECK-SD-NOFP16-NEXT: fcvt h0, s0
+; CHECK-SD-NOFP16-NEXT: ret
+;
+; CHECK-SD-FP16-LABEL: utofp_i8_f16:
+; CHECK-SD-FP16: // %bb.0: // %entry
+; CHECK-SD-FP16-NEXT: and w8, w0, #0xff
+; CHECK-SD-FP16-NEXT: ucvtf h0, w8
+; CHECK-SD-FP16-NEXT: ret
+;
+; CHECK-GI-NOFP16-LABEL: utofp_i8_f16:
+; CHECK-GI-NOFP16: // %bb.0: // %entry
+; CHECK-GI-NOFP16-NEXT: and w8, w0, #0xff
+; CHECK-GI-NOFP16-NEXT: ucvtf s0, w8
+; CHECK-GI-NOFP16-NEXT: fcvt h0, s0
+; CHECK-GI-NOFP16-NEXT: ret
+;
+; CHECK-GI-FP16-LABEL: utofp_i8_f16:
+; CHECK-GI-FP16: // %bb.0: // %entry
+; CHECK-GI-FP16-NEXT: and w8, w0, #0xff
+; CHECK-GI-FP16-NEXT: ucvtf h0, w8
+; CHECK-GI-FP16-NEXT: ret
+entry:
+ %c = uitofp i8 %a to half
+ ret half %c
+}
+
+define <2 x double> @stofp_v2i64_v2f64(<2 x i64> %a) {
+; CHECK-LABEL: stofp_v2i64_v2f64:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: scvtf v0.2d, v0.2d
+; CHECK-NEXT: ret
+entry:
+ %c = sitofp <2 x i64> %a to <2 x double>
+ ret <2 x double> %c
+}
+
+define <2 x double> @utofp_v2i64_v2f64(<2 x i64> %a) {
+; CHECK-LABEL: utofp_v2i64_v2f64:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: ucvtf v0.2d, v0.2d
+; CHECK-NEXT: ret
+entry:
+ %c = uitofp <2 x i64> %a to <2 x double>
+ ret <2 x double> %c
+}
+
+define <3 x double> @stofp_v3i64_v3f64(<3 x i64> %a) {
+; CHECK-SD-LABEL: stofp_v3i64_v3f64:
+; CHECK-SD: // %bb.0: // %entry
+; CHECK-SD-NEXT: // kill: def $d0 killed $d0 def $q0
+; CHECK-SD-NEXT: // kill: def $d1 killed $d1 def $q1
+; CHECK-SD-NEXT: // kill: def $d2 killed $d2 def $q2
+; CHECK-SD-NEXT: mov v0.d[1], v1.d[0]
+; CHECK-SD-NEXT: scvtf v2.2d, v2.2d
+; CHECK-SD-NEXT: // kill: def $d2 killed $d2 killed $q2
+; CHECK-SD-NEXT: scvtf v0.2d, v0.2d
+; CHECK-SD-NEXT: ext v1.16b, v0.16b, v0.16b, #8
+; CHECK-SD-NEXT: // kill: def $d0 killed $d0 killed $q0
+; CHECK-SD-NEXT: // kill: def $d1 killed $d1 killed $q1
+; CHECK-SD-NEXT: ret
+;
+; CHECK-GI-LABEL: stofp_v3i64_v3f64:
+; CHECK-GI: // %bb.0: // %entry
+; CHECK-GI-NEXT: // kill: def $d0 killed $d0 def $q0
+; CHECK-GI-NEXT: // kill: def $d1 killed $d1 def $q1
+; CHECK-GI-NEXT: // kill: def $d2 killed $d2 def $q2
+; CHECK-GI-NEXT: mov v0.d[1], v1.d[0]
+; CHECK-GI-NEXT: scvtf v2.2d, v2.2d
+; CHECK-GI-NEXT: // kill: def $d2 killed $d2 killed $q2
+; CHECK-GI-NEXT: scvtf v0.2d, v0.2d
+; CHECK-GI-NEXT: mov d1, v0.d[1]
+; CHECK-GI-NEXT: // kill: def $d0 killed $d0 killed $q0
+; CHECK-GI-NEXT: ret
+entry:
+ %c = sitofp <3 x i64> %a to <3 x double>
+ ret <3 x double> %c
+}
+
+define <3 x double> @utofp_v3i64_v3f64(<3 x i64> %a) {
+; CHECK-SD-LABEL: utofp_v3i64_v3f64:
+; CHECK-SD: // %bb.0: // %entry
+; CHECK-SD-NEXT: // kill: def $d0 killed $d0 def $q0
+; CHECK-SD-NEXT: // kill: def $d1 killed $d1 def $q1
+; CHECK-SD-NEXT: // kill: def $d2 killed $d2 def $q2
+; CHECK-SD-NEXT: mov v0.d[1], v1.d[0]
+; CHECK-SD-NEXT: ucvtf v2.2d, v2.2d
+; CHECK-SD-NEXT: // kill: def $d2 killed $d2 killed $q2
+; CHECK-SD-NEXT: ucvtf v0.2d, v0.2d
+; CHECK-SD-NEXT: ext v1.16b, v0.16b, v0.16b, #8
+; CHECK-SD-NEXT: // kill: def $d0 killed $d0 killed $q0
+; CHECK-SD-NEXT: // kill: def $d1 killed $d1 killed $q1
+; CHECK-SD-NEXT: ret
+;
+; CHECK-GI-LABEL: utofp_v3i64_v3f64:
+; CHECK-GI: // %bb.0: // %entry
+; CHECK-GI-NEXT: // kill: def $d0 killed $d0 def $q0
+; CHECK-GI-NEXT: // kill: def $d1 killed $d1 def $q1
+; CHECK-GI-NEXT: // kill: def $d2 killed $d2 def $q2
+; CHECK-GI-NEXT: mov v0.d[1], v1.d[0]
+; CHECK-GI-NEXT: ucvtf v2.2d, v2.2d
+; CHECK-GI-NEXT: // kill: def $d2 killed $d2 killed $q2
+; CHECK-GI-NEXT: ucvtf v0.2d, v0.2d
+; CHECK-GI-NEXT: mov d1, v0.d[1]
+; CHECK-GI-NEXT: // kill: def $d0 killed $d0 killed $q0
+; CHECK-GI-NEXT: ret
+entry:
+ %c = uitofp <3 x i64> %a to <3 x double>
+ ret <3 x double> %c
+}
+
+define <4 x double> @stofp_v4i64_v4f64(<4 x i64> %a) {
+; CHECK-LABEL: stofp_v4i64_v4f64:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: scvtf v0.2d, v0.2d
+; CHECK-NEXT: scvtf v1.2d, v1.2d
+; CHECK-NEXT: ret
+entry:
+ %c = sitofp <4 x i64> %a to <4 x double>
+ ret <4 x double> %c
+}
+
+define <4 x double> @utofp_v4i64_v4f64(<4 x i64> %a) {
+; CHECK-LABEL: utofp_v4i64_v4f64:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: ucvtf v0.2d, v0.2d
+; CHECK-NEXT: ucvtf v1.2d, v1.2d
+; CHECK-NEXT: ret
+entry:
+ %c = uitofp <4 x i64> %a to <4 x double>
+ ret <4 x double> %c
+}
+
+define <8 x double> @stofp_v8i64_v8f64(<8 x i64> %a) {
+; CHECK-LABEL: stofp_v8i64_v8f64:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: scvtf v0.2d, v0.2d
+; CHECK-NEXT: scvtf v1.2d, v1.2d
+; CHECK-NEXT: scvtf v2.2d, v2.2d
+; CHECK-NEXT: scvtf v3.2d, v3.2d
+; CHECK-NEXT: ret
+entry:
+ %c = sitofp <8 x i64> %a to <8 x double>
+ ret <8 x double> %c
+}
+
+define <8 x double> @utofp_v8i64_v8f64(<8 x i64> %a) {
+; CHECK-LABEL: utofp_v8i64_v8f64:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: ucvtf v0.2d, v0.2d
+; CHECK-NEXT: ucvtf v1.2d, v1.2d
+; CHECK-NEXT: ucvtf v2.2d, v2.2d
+; CHECK-NEXT: ucvtf v3.2d, v3.2d
+; CHECK-NEXT: ret
+entry:
+ %c = uitofp <8 x i64> %a to <8 x double>
+ ret <8 x double> %c
+}
+
+define <16 x double> @stofp_v16i64_v16f64(<16 x i64> %a) {
+; CHECK-LABEL: stofp_v16i64_v16f64:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: scvtf v0.2d, v0.2d
+; CHECK-NEXT: scvtf v1.2d, v1.2d
+; CHECK-NEXT: scvtf v2.2d, v2.2d
+; CHECK-NEXT: scvtf v3.2d, v3.2d
+; CHECK-NEXT: scvtf v4.2d, v4.2d
+; CHECK-NEXT: scvtf v5.2d, v5.2d
+; CHECK-NEXT: scvtf v6.2d, v6.2d
+; CHECK-NEXT: scvtf v7.2d, v7.2d
+; CHECK-NEXT: ret
+entry:
+ %c = sitofp <16 x i64> %a to <16 x double>
+ ret <16 x double> %c
+}
+
+define <16 x double> @utofp_v16i64_v16f64(<16 x i64> %a) {
+; CHECK-LABEL: utofp_v16i64_v16f64:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: ucvtf v0.2d, v0.2d
+; CHECK-NEXT: ucvtf v1.2d, v1.2d
+; CHECK-NEXT: ucvtf v2.2d, v2.2d
+; CHECK-NEXT: ucvtf v3.2d, v3.2d
+; CHECK-NEXT: ucvtf v4.2d, v4.2d
+; CHECK-NEXT: ucvtf v5.2d, v5.2d
+; CHECK-NEXT: ucvtf v6.2d, v6.2d
+; CH...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/71282
More information about the llvm-commits
mailing list