; 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 }