llvm-project/llvm/test/CodeGen/AArch64/store-float-conversion.ll
Guy David 58d70dc62b
[AArch64] Keep floating-point conversion in SIMD (#147707)
Stores can be issued faster if the result is kept in the SIMD/FP
registers.
The `HasOneUse` guards against creating two floating point conversions,
if for example there's some arithmetic done on the converted value as
well. Another approach would be to inspect the user instructions during
lowering, but I don't see that type of check in the lowering too often.
2025-07-30 14:53:56 +03:00

132 lines
3.1 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
; RUN: llc -verify-machineinstrs -mtriple=aarch64 < %s | FileCheck %s
define void @f32_to_u8(float %f, ptr %dst) {
; CHECK-LABEL: f32_to_u8:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: fcvtzu s0, s0
; CHECK-NEXT: str b0, [x0]
; CHECK-NEXT: ret
entry:
%conv = fptoui float %f to i32
%trunc = trunc i32 %conv to i8
store i8 %trunc, ptr %dst
ret void
}
define void @f32_to_s8(float %f, ptr %dst) {
; CHECK-LABEL: f32_to_s8:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: fcvtzs s0, s0
; CHECK-NEXT: str b0, [x0]
; CHECK-NEXT: ret
entry:
%conv = fptosi float %f to i32
%trunc = trunc i32 %conv to i8
store i8 %trunc, ptr %dst
ret void
}
define void @f32_to_u16(float %f, ptr %dst) {
; CHECK-LABEL: f32_to_u16:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: fcvtzu s0, s0
; CHECK-NEXT: str h0, [x0]
; CHECK-NEXT: ret
entry:
%conv = fptoui float %f to i32
%trunc = trunc i32 %conv to i16
store i16 %trunc, ptr %dst
ret void
}
define void @f32_to_s16(float %f, ptr %dst) {
; CHECK-LABEL: f32_to_s16:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: fcvtzs s0, s0
; CHECK-NEXT: str h0, [x0]
; CHECK-NEXT: ret
entry:
%conv = fptosi float %f to i32
%trunc = trunc i32 %conv to i16
store i16 %trunc, ptr %dst
ret void
}
define void @f32_to_u32(float %f, ptr %dst) {
; CHECK-LABEL: f32_to_u32:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: fcvtzu s0, s0
; CHECK-NEXT: str s0, [x0]
; CHECK-NEXT: ret
entry:
%conv = fptoui float %f to i32
store i32 %conv, ptr %dst
ret void
}
define void @f32_to_s32(float %f, ptr %dst) {
; CHECK-LABEL: f32_to_s32:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: fcvtzs s0, s0
; CHECK-NEXT: str s0, [x0]
; CHECK-NEXT: ret
entry:
%conv = fptosi float %f to i32
store i32 %conv, ptr %dst
ret void
}
define void @f32_to_s64(float %f, ptr %dst) {
; CHECK-LABEL: f32_to_s64:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: fcvtzs w8, s0
; CHECK-NEXT: sxtw x8, w8
; CHECK-NEXT: str x8, [x0]
; CHECK-NEXT: ret
entry:
%conv = fptosi float %f to i32
%ext = sext i32 %conv to i64
store i64 %ext, ptr %dst
ret void
}
define void @f64_to_u64(double %d, ptr %dst) {
; CHECK-LABEL: f64_to_u64:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: fcvtzu d0, d0
; CHECK-NEXT: str d0, [x0]
; CHECK-NEXT: ret
entry:
%conv = fptoui double %d to i64
store i64 %conv, ptr %dst
ret void
}
define void @f64_to_s64(double %d, ptr %dst) {
; CHECK-LABEL: f64_to_s64:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: fcvtzs d0, d0
; CHECK-NEXT: str d0, [x0]
; CHECK-NEXT: ret
entry:
%conv = fptosi double %d to i64
store i64 %conv, ptr %dst
ret void
}
define i32 @f32_to_i32_multiple_uses(float %f, ptr %dst) {
; CHECK-LABEL: f32_to_i32_multiple_uses:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: fcvtzs w8, s0
; CHECK-NEXT: mov x9, x0
; CHECK-NEXT: mov w0, w8
; CHECK-NEXT: strb w8, [x9]
; CHECK-NEXT: ret
entry:
%conv = fptosi float %f to i32
%trunc = trunc i32 %conv to i8
store i8 %trunc, ptr %dst
ret i32 %conv
}