blob: bccbf489601aae6619da4fada062220a044bd2ad [file]
; 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 ptr @f32_to_s8_inc(float %f, ptr %dst) {
; CHECK-LABEL: f32_to_s8_inc:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: fcvtzs s0, s0
; CHECK-NEXT: st1 { v0.b }[0], [x0], #1
; CHECK-NEXT: ret
entry:
%conv = fptosi float %f to i32
%trunc = trunc i32 %conv to i8
%next = getelementptr i8, ptr %dst, i64 1
store i8 %trunc, ptr %dst
ret ptr %next
}
define ptr @f32_to_u8_inc(float %f, ptr %dst) {
; CHECK-LABEL: f32_to_u8_inc:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: fcvtzu s0, s0
; CHECK-NEXT: st1 { v0.b }[0], [x0], #1
; CHECK-NEXT: ret
entry:
%conv = fptoui float %f to i32
%trunc = trunc i32 %conv to i8
%next = getelementptr i8, ptr %dst, i64 1
store i8 %trunc, ptr %dst
ret ptr %next
}
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 ptr @f32_to_s16_inc(float %f, ptr %dst) {
; CHECK-LABEL: f32_to_s16_inc:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: fcvtzs s0, s0
; CHECK-NEXT: st1 { v0.h }[0], [x0], #2
; CHECK-NEXT: ret
entry:
%conv = fptosi float %f to i32
%trunc = trunc i32 %conv to i16
%next = getelementptr i16, ptr %dst, i64 1
store i16 %trunc, ptr %dst
ret ptr %next
}
define ptr @f32_to_u16_inc(float %f, ptr %dst) {
; CHECK-LABEL: f32_to_u16_inc:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: fcvtzu s0, s0
; CHECK-NEXT: st1 { v0.h }[0], [x0], #2
; CHECK-NEXT: ret
entry:
%conv = fptoui float %f to i32
%trunc = trunc i32 %conv to i16
%next = getelementptr i16, ptr %dst, i64 1
store i16 %trunc, ptr %dst
ret ptr %next
}
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 ptr @f32_to_s32_inc(float %f, ptr %dst) {
; CHECK-LABEL: f32_to_s32_inc:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: fcvtzs s0, s0
; CHECK-NEXT: st1 { v0.s }[0], [x0], #4
; CHECK-NEXT: ret
entry:
%conv = fptosi float %f to i32
%next = getelementptr i32, ptr %dst, i64 1
store i32 %conv, ptr %dst
ret ptr %next
}
define ptr @f32_to_u32_inc(float %f, ptr %dst) {
; CHECK-LABEL: f32_to_u32_inc:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: fcvtzu s0, s0
; CHECK-NEXT: st1 { v0.s }[0], [x0], #4
; CHECK-NEXT: ret
entry:
%conv = fptoui float %f to i32
%next = getelementptr i32, ptr %dst, i64 1
store i32 %conv, ptr %dst
ret ptr %next
}
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 ptr @f64_to_s64_inc(double %d, ptr %dst) {
; CHECK-LABEL: f64_to_s64_inc:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: fcvtzs d0, d0
; CHECK-NEXT: st1 { v0.d }[0], [x0], #8
; CHECK-NEXT: ret
entry:
%conv = fptosi double %d to i64
%next = getelementptr i64, ptr %dst, i64 1
store i64 %conv, ptr %dst
ret ptr %next
}
define ptr @f64_to_u64_inc(double %d, ptr %dst) {
; CHECK-LABEL: f64_to_u64_inc:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: fcvtzu d0, d0
; CHECK-NEXT: st1 { v0.d }[0], [x0], #8
; CHECK-NEXT: ret
entry:
%conv = fptoui double %d to i64
%next = getelementptr i64, ptr %dst, i64 1
store i64 %conv, ptr %dst
ret ptr %next
}
define void @f64_to_u8(double %d, ptr %dst) {
; CHECK-LABEL: f64_to_u8:
; CHECK: // %bb.0:
; CHECK-NEXT: fcvtzu d0, d0
; CHECK-NEXT: str b0, [x0]
; CHECK-NEXT: ret
%conv = fptoui double %d to i64
%trunc = trunc i64 %conv to i8
store i8 %trunc, ptr %dst
ret void
}
define void @f64_to_s8(double %d, ptr %dst) {
; CHECK-LABEL: f64_to_s8:
; CHECK: // %bb.0:
; CHECK-NEXT: fcvtzs d0, d0
; CHECK-NEXT: str b0, [x0]
; CHECK-NEXT: ret
%conv = fptosi double %d to i64
%trunc = trunc i64 %conv to i8
store i8 %trunc, ptr %dst
ret void
}
define ptr @f64_to_s8_inc(double %d, ptr %dst) {
; CHECK-LABEL: f64_to_s8_inc:
; CHECK: // %bb.0:
; CHECK-NEXT: fcvtzs d0, d0
; CHECK-NEXT: st1 { v0.b }[0], [x0], #1
; CHECK-NEXT: ret
%conv = fptosi double %d to i64
%trunc = trunc i64 %conv to i8
store i8 %trunc, ptr %dst
%next = getelementptr i8, ptr %dst, i64 1
ret ptr %next
}
define ptr @f64_to_u8_inc(double %d, ptr %dst) {
; CHECK-LABEL: f64_to_u8_inc:
; CHECK: // %bb.0:
; CHECK-NEXT: fcvtzu d0, d0
; CHECK-NEXT: st1 { v0.b }[0], [x0], #1
; CHECK-NEXT: ret
%conv = fptoui double %d to i64
%trunc = trunc i64 %conv to i8
store i8 %trunc, ptr %dst
%next = getelementptr i8, ptr %dst, i64 1
ret ptr %next
}
define void @f64_to_u16(double %d, ptr %dst) {
; CHECK-LABEL: f64_to_u16:
; CHECK: // %bb.0:
; CHECK-NEXT: fcvtzu d0, d0
; CHECK-NEXT: str h0, [x0]
; CHECK-NEXT: ret
%conv = fptoui double %d to i64
%trunc = trunc i64 %conv to i16
store i16 %trunc, ptr %dst
ret void
}
define void @f64_to_s16(double %d, ptr %dst) {
; CHECK-LABEL: f64_to_s16:
; CHECK: // %bb.0:
; CHECK-NEXT: fcvtzs d0, d0
; CHECK-NEXT: str h0, [x0]
; CHECK-NEXT: ret
%conv = fptosi double %d to i64
%trunc = trunc i64 %conv to i16
store i16 %trunc, ptr %dst
ret void
}
define ptr @f64_to_s16_inc(double %d, ptr %dst) {
; CHECK-LABEL: f64_to_s16_inc:
; CHECK: // %bb.0:
; CHECK-NEXT: fcvtzs d0, d0
; CHECK-NEXT: st1 { v0.h }[0], [x0], #2
; CHECK-NEXT: ret
%conv = fptosi double %d to i64
%trunc = trunc i64 %conv to i16
%next = getelementptr i16, ptr %dst, i64 1
store i16 %trunc, ptr %dst
ret ptr %next
}
define ptr @f64_to_u16_inc(double %d, ptr %dst) {
; CHECK-LABEL: f64_to_u16_inc:
; CHECK: // %bb.0:
; CHECK-NEXT: fcvtzu d0, d0
; CHECK-NEXT: st1 { v0.h }[0], [x0], #2
; CHECK-NEXT: ret
%conv = fptoui double %d to i64
%trunc = trunc i64 %conv to i16
%next = getelementptr i16, ptr %dst, i64 1
store i16 %trunc, ptr %dst
ret ptr %next
}
define void @f64_to_s32(double %d, ptr %dst) {
; CHECK-LABEL: f64_to_s32:
; CHECK: // %bb.0:
; CHECK-NEXT: fcvtzs d0, d0
; CHECK-NEXT: str s0, [x0]
; CHECK-NEXT: ret
%conv = fptosi double %d to i64
%trunc = trunc i64 %conv to i32
store i32 %trunc, ptr %dst
ret void
}
define ptr @f64_to_s32_inc(double %d, ptr %dst) {
; CHECK-LABEL: f64_to_s32_inc:
; CHECK: // %bb.0:
; CHECK-NEXT: fcvtzs d0, d0
; CHECK-NEXT: st1 { v0.s }[0], [x0], #4
; CHECK-NEXT: ret
%conv = fptosi double %d to i64
%trunc = trunc i64 %conv to i32
%next = getelementptr i32, ptr %dst, i64 1
store i32 %trunc, ptr %dst
ret ptr %next
}
define ptr @f64_to_u32_inc(double %d, ptr %dst) {
; CHECK-LABEL: f64_to_u32_inc:
; CHECK: // %bb.0:
; CHECK-NEXT: fcvtzu d0, d0
; CHECK-NEXT: st1 { v0.s }[0], [x0], #4
; CHECK-NEXT: ret
%conv = fptoui double %d to i64
%trunc = trunc i64 %conv to i32
%next = getelementptr i32, ptr %dst, i64 1
store i32 %trunc, ptr %dst
ret ptr %next
}
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
}
; Negative test: extracting from lane 1 must go through GPR.
define ptr @v4i32_lane1_to_i8_inc(<4 x i32> %v, ptr %dst) {
; CHECK-LABEL: v4i32_lane1_to_i8_inc:
; CHECK: // %bb.0:
; CHECK-NEXT: mov w8, v0.s[1]
; CHECK-NEXT: strb w8, [x0], #1
; CHECK-NEXT: ret
%elt = extractelement <4 x i32> %v, i32 1
%trunc = trunc i32 %elt to i8
store i8 %trunc, ptr %dst
%next = getelementptr i8, ptr %dst, i64 1
ret ptr %next
}