; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5 ; RUN: llc < %s -verify-machineinstrs -mattr=+sve -global-isel=0 | FileCheck %s ; RUN: llc < %s -verify-machineinstrs -mattr=+sme -global-isel=0 -force-streaming | FileCheck %s ; RUN: llc < %s -verify-machineinstrs -mattr=+sve -global-isel=0 -force-streaming-compatible | FileCheck %s target triple = "aarch64-unknown-linux-gnu" define void @test_str_lane_s32(ptr %a, %b) { ; CHECK-LABEL: test_str_lane_s32: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: mov z0.s, z0.s[3] ; CHECK-NEXT: str s0, [x0] ; CHECK-NEXT: ret entry: %0 = extractelement %b, i32 3 store i32 %0, ptr %a, align 4 ret void } define void @test_str_lane0_s32(ptr %a, %b) { ; CHECK-LABEL: test_str_lane0_s32: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: str s0, [x0] ; CHECK-NEXT: ret entry: %0 = extractelement %b, i32 0 store i32 %0, ptr %a, align 4 ret void } define void @test_str_lane_s64(ptr %a, %b) { ; CHECK-LABEL: test_str_lane_s64: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: mov z0.d, z0.d[1] ; CHECK-NEXT: str d0, [x0] ; CHECK-NEXT: ret entry: %0 = extractelement %b, i32 1 store i64 %0, ptr %a, align 8 ret void } define void @test_str_lane0_s64(ptr %a, %b) { ; CHECK-LABEL: test_str_lane0_s64: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: str d0, [x0] ; CHECK-NEXT: ret entry: %0 = extractelement %b, i32 0 store i64 %0, ptr %a, align 8 ret void } define void @test_str_lane_f32(ptr %a, %b) { ; CHECK-LABEL: test_str_lane_f32: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: mov z0.s, z0.s[3] ; CHECK-NEXT: str s0, [x0] ; CHECK-NEXT: ret entry: %0 = extractelement %b, i32 3 store float %0, ptr %a, align 4 ret void } define void @test_str_lane0_f32(ptr %a, %b) { ; CHECK-LABEL: test_str_lane0_f32: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: str s0, [x0] ; CHECK-NEXT: ret entry: %0 = extractelement %b, i32 0 store float %0, ptr %a, align 4 ret void } define void @test_str_lane_f64(ptr %a, %b) { ; CHECK-LABEL: test_str_lane_f64: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: mov z0.d, z0.d[1] ; CHECK-NEXT: str d0, [x0] ; CHECK-NEXT: ret entry: %0 = extractelement %b, i32 1 store double %0, ptr %a, align 8 ret void } define void @test_str_lane0_f64(ptr %a, %b) { ; CHECK-LABEL: test_str_lane0_f64: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: str d0, [x0] ; CHECK-NEXT: ret entry: %0 = extractelement %b, i32 0 store double %0, ptr %a, align 8 ret void } define void @test_str_lane_s8(ptr %a, %b) { ; CHECK-LABEL: test_str_lane_s8: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: mov z0.b, z0.b[7] ; CHECK-NEXT: str b0, [x0] ; CHECK-NEXT: ret entry: %0 = extractelement %b, i32 7 store i8 %0, ptr %a, align 1 ret void } define void @test_str_lane0_s8(ptr %a, %b) { ; CHECK-LABEL: test_str_lane0_s8: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: str b0, [x0] ; CHECK-NEXT: ret entry: %0 = extractelement %b, i32 0 store i8 %0, ptr %a, align 1 ret void } define void @test_str_lane_s16(ptr %a, %b) { ; CHECK-LABEL: test_str_lane_s16: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: mov z0.h, z0.h[3] ; CHECK-NEXT: str h0, [x0] ; CHECK-NEXT: ret entry: %0 = extractelement %b, i32 3 store i16 %0, ptr %a, align 2 ret void } define void @test_str_lane0_s16(ptr %a, %b) { ; CHECK-LABEL: test_str_lane0_s16: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: str h0, [x0] ; CHECK-NEXT: ret entry: %0 = extractelement %b, i32 0 store i16 %0, ptr %a, align 2 ret void } define void @test_str_reduction_i32_to_i32(ptr %ptr, %p0, %v) { ; CHECK-LABEL: test_str_reduction_i32_to_i32: ; CHECK: // %bb.0: ; CHECK-NEXT: uaddv d0, p0, z0.s ; CHECK-NEXT: str s0, [x0] ; CHECK-NEXT: ret %reduce = tail call i64 @llvm.aarch64.sve.uaddv.nxv4i32( %p0, %v) %trunc = trunc i64 %reduce to i32 store i32 %trunc, ptr %ptr, align 4 ret void } define void @test_str_reduction_i32_to_i64(ptr %ptr, %p0, %v) { ; CHECK-LABEL: test_str_reduction_i32_to_i64: ; CHECK: // %bb.0: ; CHECK-NEXT: uaddv d0, p0, z0.s ; CHECK-NEXT: str d0, [x0] ; CHECK-NEXT: ret %reduce = tail call i64 @llvm.aarch64.sve.uaddv.nxv4i32( %p0, %v) store i64 %reduce, ptr %ptr, align 8 ret void } define void @test_str_reduction_i32_to_i16(ptr %ptr, %p0, %v) { ; CHECK-LABEL: test_str_reduction_i32_to_i16: ; CHECK: // %bb.0: ; CHECK-NEXT: uaddv d0, p0, z0.s ; CHECK-NEXT: str h0, [x0] ; CHECK-NEXT: ret %reduce = tail call i64 @llvm.aarch64.sve.uaddv.nxv4i32( %p0, %v) %trunc = trunc i64 %reduce to i16 store i16 %trunc, ptr %ptr, align 2 ret void } define void @test_str_reduction_i32_to_i8(ptr %ptr, %p0, %v) { ; CHECK-LABEL: test_str_reduction_i32_to_i8: ; CHECK: // %bb.0: ; CHECK-NEXT: uaddv d0, p0, z0.s ; CHECK-NEXT: str b0, [x0] ; CHECK-NEXT: ret %reduce = tail call i64 @llvm.aarch64.sve.uaddv.nxv4i32( %p0, %v) %trunc = trunc i64 %reduce to i8 store i8 %trunc, ptr %ptr, align 1 ret void } define void @test_str_reduction_i32_to_i32_negative_offset(ptr %ptr, %p0, %v) { ; CHECK-LABEL: test_str_reduction_i32_to_i32_negative_offset: ; CHECK: // %bb.0: ; CHECK-NEXT: uaddv d0, p0, z0.s ; CHECK-NEXT: stur s0, [x0, #-32] ; CHECK-NEXT: ret %reduce = tail call i64 @llvm.aarch64.sve.uaddv.nxv4i32( %p0, %v) %trunc = trunc i64 %reduce to i32 %out_ptr = getelementptr inbounds i32, ptr %ptr, i64 -8 store i32 %trunc, ptr %out_ptr, align 4 ret void } define void @test_str_reduction_i32_to_i64_negative_offset(ptr %ptr, %p0, %v) { ; CHECK-LABEL: test_str_reduction_i32_to_i64_negative_offset: ; CHECK: // %bb.0: ; CHECK-NEXT: uaddv d0, p0, z0.s ; CHECK-NEXT: stur d0, [x0, #-64] ; CHECK-NEXT: ret %reduce = tail call i64 @llvm.aarch64.sve.uaddv.nxv4i32( %p0, %v) %out_ptr = getelementptr inbounds i64, ptr %ptr, i64 -8 store i64 %reduce, ptr %out_ptr, align 8 ret void } define void @test_str_reduction_i32_to_i16_negative_offset(ptr %ptr, %p0, %v) { ; CHECK-LABEL: test_str_reduction_i32_to_i16_negative_offset: ; CHECK: // %bb.0: ; CHECK-NEXT: uaddv d0, p0, z0.s ; CHECK-NEXT: stur h0, [x0, #-16] ; CHECK-NEXT: ret %reduce = tail call i64 @llvm.aarch64.sve.uaddv.nxv4i32( %p0, %v) %trunc = trunc i64 %reduce to i16 %out_ptr = getelementptr inbounds i16, ptr %ptr, i64 -8 store i16 %trunc, ptr %out_ptr, align 2 ret void } define void @test_str_reduction_i32_to_i8_negative_offset(ptr %ptr, %p0, %v) { ; CHECK-LABEL: test_str_reduction_i32_to_i8_negative_offset: ; CHECK: // %bb.0: ; CHECK-NEXT: uaddv d0, p0, z0.s ; CHECK-NEXT: stur b0, [x0, #-8] ; CHECK-NEXT: ret %reduce = tail call i64 @llvm.aarch64.sve.uaddv.nxv4i32( %p0, %v) %trunc = trunc i64 %reduce to i8 %out_ptr = getelementptr inbounds i8, ptr %ptr, i64 -8 store i8 %trunc, ptr %out_ptr, align 1 ret void } define void @test_str_lane_s32_negative_offset(ptr %a, %b) { ; CHECK-LABEL: test_str_lane_s32_negative_offset: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: mov z0.s, z0.s[3] ; CHECK-NEXT: stur s0, [x0, #-32] ; CHECK-NEXT: ret entry: %0 = extractelement %b, i32 3 %out_ptr = getelementptr inbounds i32, ptr %a, i64 -8 store i32 %0, ptr %out_ptr, align 4 ret void } define void @test_str_lane0_s32_negative_offset(ptr %a, %b) { ; CHECK-LABEL: test_str_lane0_s32_negative_offset: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: stur s0, [x0, #-32] ; CHECK-NEXT: ret entry: %0 = extractelement %b, i32 0 %out_ptr = getelementptr inbounds i32, ptr %a, i64 -8 store i32 %0, ptr %out_ptr, align 4 ret void } define void @test_str_lane_s64_negative_offset(ptr %a, %b) { ; CHECK-LABEL: test_str_lane_s64_negative_offset: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: mov z0.d, z0.d[1] ; CHECK-NEXT: stur d0, [x0, #-64] ; CHECK-NEXT: ret entry: %0 = extractelement %b, i32 1 %out_ptr = getelementptr inbounds i64, ptr %a, i64 -8 store i64 %0, ptr %out_ptr, align 8 ret void } define void @test_str_lane0_s64_negative_offset(ptr %a, %b) { ; CHECK-LABEL: test_str_lane0_s64_negative_offset: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: stur d0, [x0, #-64] ; CHECK-NEXT: ret entry: %0 = extractelement %b, i32 0 %out_ptr = getelementptr inbounds i64, ptr %a, i64 -8 store i64 %0, ptr %out_ptr, align 8 ret void } define void @test_str_lane_s8_negative_offset(ptr %a, %b) { ; CHECK-LABEL: test_str_lane_s8_negative_offset: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: mov z0.b, z0.b[7] ; CHECK-NEXT: stur b0, [x0, #-8] ; CHECK-NEXT: ret entry: %0 = extractelement %b, i32 7 %out_ptr = getelementptr inbounds i8, ptr %a, i64 -8 store i8 %0, ptr %out_ptr, align 1 ret void } define void @test_str_lane0_s8_negative_offset(ptr %a, %b) { ; CHECK-LABEL: test_str_lane0_s8_negative_offset: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: stur b0, [x0, #-8] ; CHECK-NEXT: ret entry: %0 = extractelement %b, i32 0 %out_ptr = getelementptr inbounds i8, ptr %a, i64 -8 store i8 %0, ptr %out_ptr, align 1 ret void } define void @test_str_lane_s16_negative_offset(ptr %a, %b) { ; CHECK-LABEL: test_str_lane_s16_negative_offset: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: mov z0.h, z0.h[3] ; CHECK-NEXT: stur h0, [x0, #-16] ; CHECK-NEXT: ret entry: %0 = extractelement %b, i32 3 %out_ptr = getelementptr inbounds i16, ptr %a, i64 -8 store i16 %0, ptr %out_ptr, align 2 ret void } define void @test_str_lane0_s16_negative_offset(ptr %a, %b) { ; CHECK-LABEL: test_str_lane0_s16_negative_offset: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: stur h0, [x0, #-16] ; CHECK-NEXT: ret entry: %0 = extractelement %b, i32 0 %out_ptr = getelementptr inbounds i16, ptr %a, i64 -8 store i16 %0, ptr %out_ptr, align 2 ret void } define void @test_str_trunc_lane_s32_to_s16(ptr %a, %b) { ; CHECK-LABEL: test_str_trunc_lane_s32_to_s16: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: mov z0.s, z0.s[3] ; CHECK-NEXT: str h0, [x0] ; CHECK-NEXT: ret entry: %0 = extractelement %b, i32 3 %trunc = trunc i32 %0 to i16 store i16 %trunc, ptr %a, align 2 ret void } define void @test_str_trunc_lane0_s32_to_s16(ptr %a, %b) { ; CHECK-LABEL: test_str_trunc_lane0_s32_to_s16: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: str h0, [x0] ; CHECK-NEXT: ret entry: %0 = extractelement %b, i32 0 %trunc = trunc i32 %0 to i16 store i16 %trunc, ptr %a, align 2 ret void } define void @test_str_trunc_lane_s32_to_s8(ptr %a, %b) { ; CHECK-LABEL: test_str_trunc_lane_s32_to_s8: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: mov z0.s, z0.s[3] ; CHECK-NEXT: str b0, [x0] ; CHECK-NEXT: ret entry: %0 = extractelement %b, i32 3 %trunc = trunc i32 %0 to i8 store i8 %trunc, ptr %a, align 1 ret void } define void @test_str_trunc_lane0_s32_to_s8(ptr %a, %b) { ; CHECK-LABEL: test_str_trunc_lane0_s32_to_s8: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: str b0, [x0] ; CHECK-NEXT: ret entry: %0 = extractelement %b, i32 0 %trunc = trunc i32 %0 to i8 store i8 %trunc, ptr %a, align 1 ret void } define void @test_str_trunc_lane_s64_to_s8(ptr %a, %b) { ; CHECK-LABEL: test_str_trunc_lane_s64_to_s8: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: mov z0.d, z0.d[3] ; CHECK-NEXT: str b0, [x0] ; CHECK-NEXT: ret entry: %0 = extractelement %b, i32 3 %trunc = trunc i64 %0 to i8 store i8 %trunc, ptr %a, align 1 ret void } define void @test_str_trunc_lane_s32_to_s16_negative_offset(ptr %a, %b) { ; CHECK-LABEL: test_str_trunc_lane_s32_to_s16_negative_offset: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: mov z0.s, z0.s[3] ; CHECK-NEXT: stur h0, [x0, #-16] ; CHECK-NEXT: ret entry: %0 = extractelement %b, i32 3 %trunc = trunc i32 %0 to i16 %out_ptr = getelementptr inbounds i16, ptr %a, i64 -8 store i16 %trunc, ptr %out_ptr, align 2 ret void } define void @test_str_trunc_lane0_s32_to_s16_negative_offset(ptr %a, %b) { ; CHECK-LABEL: test_str_trunc_lane0_s32_to_s16_negative_offset: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: stur h0, [x0, #-16] ; CHECK-NEXT: ret entry: %0 = extractelement %b, i32 0 %trunc = trunc i32 %0 to i16 %out_ptr = getelementptr inbounds i16, ptr %a, i64 -8 store i16 %trunc, ptr %out_ptr, align 2 ret void } define void @test_str_trunc_lane_s32_to_s8_negative_offset(ptr %a, %b) { ; CHECK-LABEL: test_str_trunc_lane_s32_to_s8_negative_offset: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: mov z0.s, z0.s[3] ; CHECK-NEXT: stur b0, [x0, #-8] ; CHECK-NEXT: ret entry: %0 = extractelement %b, i32 3 %trunc = trunc i32 %0 to i8 %out_ptr = getelementptr inbounds i8, ptr %a, i64 -8 store i8 %trunc, ptr %out_ptr, align 1 ret void } define void @test_str_trunc_lane0_s32_to_s8_negative_offset(ptr %a, %b) { ; CHECK-LABEL: test_str_trunc_lane0_s32_to_s8_negative_offset: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: stur b0, [x0, #-8] ; CHECK-NEXT: ret entry: %0 = extractelement %b, i32 0 %trunc = trunc i32 %0 to i8 %out_ptr = getelementptr inbounds i8, ptr %a, i64 -8 store i8 %trunc, ptr %out_ptr, align 1 ret void } define void @test_str_trunc_lane_s64_to_s8_negative_offset(ptr %a, %b) { ; CHECK-LABEL: test_str_trunc_lane_s64_to_s8_negative_offset: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: mov z0.d, z0.d[3] ; CHECK-NEXT: stur b0, [x0, #-8] ; CHECK-NEXT: ret entry: %0 = extractelement %b, i32 3 %trunc = trunc i64 %0 to i8 %out_ptr = getelementptr inbounds i8, ptr %a, i64 -8 store i8 %trunc, ptr %out_ptr, align 1 ret void }