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