1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -mtriple=aarch64-linux-gnu -mattr=+sve < %s 2>%t | FileCheck %s 3; RUN: FileCheck --check-prefix=WARN --allow-empty %s <%t 4 5; If this check fails please read test/CodeGen/AArch64/README for instructions on how to resolve it. 6; WARN-NOT: warning 7 8; ST1B 9 10define void @st1b_lower_bound(<vscale x 16 x i8> %data, <vscale x 16 x i8>* %a) { 11; CHECK-LABEL: st1b_lower_bound: 12; CHECK: // %bb.0: 13; CHECK-NEXT: ptrue p0.b 14; CHECK-NEXT: st1b { z0.b }, p0, [x0, #-8, mul vl] 15; CHECK-NEXT: ret 16 %base = getelementptr <vscale x 16 x i8>, <vscale x 16 x i8>* %a, i64 -8 17 store <vscale x 16 x i8> %data, <vscale x 16 x i8>* %base 18 ret void 19} 20 21define void @st1b_inbound(<vscale x 16 x i8> %data, <vscale x 16 x i8>* %a) { 22; CHECK-LABEL: st1b_inbound: 23; CHECK: // %bb.0: 24; CHECK-NEXT: ptrue p0.b 25; CHECK-NEXT: st1b { z0.b }, p0, [x0, #1, mul vl] 26; CHECK-NEXT: ret 27 %base = getelementptr <vscale x 16 x i8>, <vscale x 16 x i8>* %a, i64 1 28 store <vscale x 16 x i8> %data, <vscale x 16 x i8>* %base 29 ret void 30} 31 32define void @st1b_upper_bound(<vscale x 16 x i8> %data, <vscale x 16 x i8>* %a) { 33; CHECK-LABEL: st1b_upper_bound: 34; CHECK: // %bb.0: 35; CHECK-NEXT: ptrue p0.b 36; CHECK-NEXT: st1b { z0.b }, p0, [x0, #7, mul vl] 37; CHECK-NEXT: ret 38 %base = getelementptr <vscale x 16 x i8>, <vscale x 16 x i8>* %a, i64 7 39 store <vscale x 16 x i8> %data, <vscale x 16 x i8>* %base 40 ret void 41} 42 43define void @st1b_out_of_upper_bound(<vscale x 16 x i8> %data, <vscale x 16 x i8>* %a) { 44; CHECK-LABEL: st1b_out_of_upper_bound: 45; CHECK: // %bb.0: 46; CHECK-NEXT: rdvl x8, #8 47; CHECK-NEXT: add x8, x0, x8 48; CHECK-NEXT: ptrue p0.b 49; CHECK-NEXT: st1b { z0.b }, p0, [x8] 50; CHECK-NEXT: ret 51 %base = getelementptr <vscale x 16 x i8>, <vscale x 16 x i8>* %a, i64 8 52 store <vscale x 16 x i8> %data, <vscale x 16 x i8>* %base 53 ret void 54} 55 56define void @st1b_out_of_lower_bound(<vscale x 16 x i8> %data, <vscale x 16 x i8>* %a) { 57; CHECK-LABEL: st1b_out_of_lower_bound: 58; CHECK: // %bb.0: 59; CHECK-NEXT: rdvl x8, #-9 60; CHECK-NEXT: add x8, x0, x8 61; CHECK-NEXT: ptrue p0.b 62; CHECK-NEXT: st1b { z0.b }, p0, [x8] 63; CHECK-NEXT: ret 64 %base = getelementptr <vscale x 16 x i8>, <vscale x 16 x i8>* %a, i64 -9 65 store <vscale x 16 x i8> %data, <vscale x 16 x i8>* %base 66 ret void 67} 68 69; ST1H 70 71define void @st1h_inbound(<vscale x 8 x i16> %data, <vscale x 8 x i16>* %a) { 72; CHECK-LABEL: st1h_inbound: 73; CHECK: // %bb.0: 74; CHECK-NEXT: ptrue p0.h 75; CHECK-NEXT: st1h { z0.h }, p0, [x0, #-6, mul vl] 76; CHECK-NEXT: ret 77 %base = getelementptr <vscale x 8 x i16>, <vscale x 8 x i16>* %a, i64 -6 78 store <vscale x 8 x i16> %data, <vscale x 8 x i16>* %base 79 ret void 80} 81 82; ST1W 83 84define void @st1w_inbound(<vscale x 4 x i32> %data, <vscale x 4 x i32>* %a) { 85; CHECK-LABEL: st1w_inbound: 86; CHECK: // %bb.0: 87; CHECK-NEXT: ptrue p0.s 88; CHECK-NEXT: st1w { z0.s }, p0, [x0, #2, mul vl] 89; CHECK-NEXT: ret 90 %base = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %a, i64 2 91 store <vscale x 4 x i32> %data, <vscale x 4 x i32>* %base 92 ret void 93} 94 95; ST1D 96 97define void @st1d_inbound(<vscale x 2 x i64> %data, <vscale x 2 x i64>* %a) { 98; CHECK-LABEL: st1d_inbound: 99; CHECK: // %bb.0: 100; CHECK-NEXT: ptrue p0.d 101; CHECK-NEXT: st1d { z0.d }, p0, [x0, #5, mul vl] 102; CHECK-NEXT: ret 103 %base = getelementptr <vscale x 2 x i64>, <vscale x 2 x i64>* %a, i64 5 104 store <vscale x 2 x i64> %data, <vscale x 2 x i64>* %base 105 ret void 106} 107 108 109; Splat stores of unpacked FP scalable vectors 110 111define void @store_nxv2f32(<vscale x 2 x float>* %out) { 112; CHECK-LABEL: store_nxv2f32: 113; CHECK: // %bb.0: 114; CHECK-NEXT: fmov z0.s, #1.00000000 115; CHECK-NEXT: ptrue p0.d 116; CHECK-NEXT: st1w { z0.d }, p0, [x0] 117; CHECK-NEXT: ret 118 %ins = insertelement <vscale x 2 x float> undef, float 1.0, i32 0 119 %splat = shufflevector <vscale x 2 x float> %ins, <vscale x 2 x float> undef, <vscale x 2 x i32> zeroinitializer 120 store <vscale x 2 x float> %splat, <vscale x 2 x float>* %out 121 ret void 122} 123 124define void @store_nxv4f16(<vscale x 4 x half>* %out) { 125; CHECK-LABEL: store_nxv4f16: 126; CHECK: // %bb.0: 127; CHECK-NEXT: fmov z0.h, #1.00000000 128; CHECK-NEXT: ptrue p0.s 129; CHECK-NEXT: st1h { z0.s }, p0, [x0] 130; CHECK-NEXT: ret 131 %ins = insertelement <vscale x 4 x half> undef, half 1.0, i32 0 132 %splat = shufflevector <vscale x 4 x half> %ins, <vscale x 4 x half> undef, <vscale x 4 x i32> zeroinitializer 133 store <vscale x 4 x half> %splat, <vscale x 4 x half>* %out 134 ret void 135} 136 137; Splat stores of unusual FP scalable vector types 138 139define void @store_nxv6f32(<vscale x 6 x float>* %out) { 140; CHECK-LABEL: store_nxv6f32: 141; CHECK: // %bb.0: 142; CHECK-NEXT: fmov z0.s, #1.00000000 143; CHECK-NEXT: ptrue p0.s 144; CHECK-NEXT: st1w { z0.s }, p0, [x0] 145; CHECK-NEXT: uunpklo z0.d, z0.s 146; CHECK-NEXT: ptrue p0.d 147; CHECK-NEXT: st1w { z0.d }, p0, [x0, #2, mul vl] 148; CHECK-NEXT: ret 149 %ins = insertelement <vscale x 6 x float> undef, float 1.0, i32 0 150 %splat = shufflevector <vscale x 6 x float> %ins, <vscale x 6 x float> undef, <vscale x 6 x i32> zeroinitializer 151 store <vscale x 6 x float> %splat, <vscale x 6 x float>* %out 152 ret void 153} 154 155define void @store_nxv12f16(<vscale x 12 x half>* %out) { 156; CHECK-LABEL: store_nxv12f16: 157; CHECK: // %bb.0: 158; CHECK-NEXT: fmov z0.h, #1.00000000 159; CHECK-NEXT: ptrue p0.h 160; CHECK-NEXT: st1h { z0.h }, p0, [x0] 161; CHECK-NEXT: uunpklo z0.s, z0.h 162; CHECK-NEXT: ptrue p0.s 163; CHECK-NEXT: st1h { z0.s }, p0, [x0, #2, mul vl] 164; CHECK-NEXT: ret 165 %ins = insertelement <vscale x 12 x half> undef, half 1.0, i32 0 166 %splat = shufflevector <vscale x 12 x half> %ins, <vscale x 12 x half> undef, <vscale x 12 x i32> zeroinitializer 167 store <vscale x 12 x half> %splat, <vscale x 12 x half>* %out 168 ret void 169} 170