1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -verify-machineinstrs < %s | FileCheck --check-prefix=CHECK --check-prefix=CHECK-SELDAG %s 3; RUN: llc -verify-machineinstrs -O0 < %s | FileCheck --check-prefix=CHECK --check-prefix=CHECK-FASTISEL %s 4 5target triple = "aarch64-unknown-linux-gnu" 6 7; 8; VECTOR_REVERSE - PPR 9; 10 11define <vscale x 2 x i1> @reverse_nxv2i1(<vscale x 2 x i1> %a) #0 { 12; CHECK-LABEL: reverse_nxv2i1: 13; CHECK: // %bb.0: 14; CHECK-NEXT: rev p0.d, p0.d 15; CHECK-NEXT: ret 16 17 %res = call <vscale x 2 x i1> @llvm.vector.reverse.nxv2i1(<vscale x 2 x i1> %a) 18 ret <vscale x 2 x i1> %res 19} 20 21define <vscale x 4 x i1> @reverse_nxv4i1(<vscale x 4 x i1> %a) #0 { 22; CHECK-LABEL: reverse_nxv4i1: 23; CHECK: // %bb.0: 24; CHECK-NEXT: rev p0.s, p0.s 25; CHECK-NEXT: ret 26 27 %res = call <vscale x 4 x i1> @llvm.vector.reverse.nxv4i1(<vscale x 4 x i1> %a) 28 ret <vscale x 4 x i1> %res 29} 30 31define <vscale x 8 x i1> @reverse_nxv8i1(<vscale x 8 x i1> %a) #0 { 32; CHECK-LABEL: reverse_nxv8i1: 33; CHECK: // %bb.0: 34; CHECK-NEXT: rev p0.h, p0.h 35; CHECK-NEXT: ret 36 37 %res = call <vscale x 8 x i1> @llvm.vector.reverse.nxv8i1(<vscale x 8 x i1> %a) 38 ret <vscale x 8 x i1> %res 39} 40 41define <vscale x 16 x i1> @reverse_nxv16i1(<vscale x 16 x i1> %a) #0 { 42; CHECK-LABEL: reverse_nxv16i1: 43; CHECK: // %bb.0: 44; CHECK-NEXT: rev p0.b, p0.b 45; CHECK-NEXT: ret 46 47 %res = call <vscale x 16 x i1> @llvm.vector.reverse.nxv16i1(<vscale x 16 x i1> %a) 48 ret <vscale x 16 x i1> %res 49} 50 51; Verify splitvec type legalisation works as expected. 52define <vscale x 32 x i1> @reverse_nxv32i1(<vscale x 32 x i1> %a) #0 { 53; CHECK-SELDAG-LABEL: reverse_nxv32i1: 54; CHECK-SELDAG: // %bb.0: 55; CHECK-SELDAG-NEXT: rev p2.b, p1.b 56; CHECK-SELDAG-NEXT: rev p1.b, p0.b 57; CHECK-SELDAG-NEXT: mov p0.b, p2.b 58; CHECK-SELDAG-NEXT: ret 59; 60; CHECK-FASTISEL-LABEL: reverse_nxv32i1: 61; CHECK-FASTISEL: // %bb.0: 62; CHECK-FASTISEL-NEXT: str x29, [sp, #-16]! // 8-byte Folded Spill 63; CHECK-FASTISEL-NEXT: addvl sp, sp, #-1 64; CHECK-FASTISEL-NEXT: str p1, [sp, #7, mul vl] // 2-byte Folded Spill 65; CHECK-FASTISEL-NEXT: mov p1.b, p0.b 66; CHECK-FASTISEL-NEXT: ldr p0, [sp, #7, mul vl] // 2-byte Folded Reload 67; CHECK-FASTISEL-NEXT: rev p0.b, p0.b 68; CHECK-FASTISEL-NEXT: rev p1.b, p1.b 69; CHECK-FASTISEL-NEXT: addvl sp, sp, #1 70; CHECK-FASTISEL-NEXT: ldr x29, [sp], #16 // 8-byte Folded Reload 71; CHECK-FASTISEL-NEXT: ret 72 73 %res = call <vscale x 32 x i1> @llvm.vector.reverse.nxv32i1(<vscale x 32 x i1> %a) 74 ret <vscale x 32 x i1> %res 75} 76 77; 78; VECTOR_REVERSE - ZPR 79; 80 81define <vscale x 16 x i8> @reverse_nxv16i8(<vscale x 16 x i8> %a) #0 { 82; CHECK-LABEL: reverse_nxv16i8: 83; CHECK: // %bb.0: 84; CHECK-NEXT: rev z0.b, z0.b 85; CHECK-NEXT: ret 86 87 %res = call <vscale x 16 x i8> @llvm.vector.reverse.nxv16i8(<vscale x 16 x i8> %a) 88 ret <vscale x 16 x i8> %res 89} 90 91define <vscale x 8 x i16> @reverse_nxv8i16(<vscale x 8 x i16> %a) #0 { 92; CHECK-LABEL: reverse_nxv8i16: 93; CHECK: // %bb.0: 94; CHECK-NEXT: rev z0.h, z0.h 95; CHECK-NEXT: ret 96 97 %res = call <vscale x 8 x i16> @llvm.vector.reverse.nxv8i16(<vscale x 8 x i16> %a) 98 ret <vscale x 8 x i16> %res 99} 100 101define <vscale x 4 x i32> @reverse_nxv4i32(<vscale x 4 x i32> %a) #0 { 102; CHECK-LABEL: reverse_nxv4i32: 103; CHECK: // %bb.0: 104; CHECK-NEXT: rev z0.s, z0.s 105; CHECK-NEXT: ret 106 107 %res = call <vscale x 4 x i32> @llvm.vector.reverse.nxv4i32(<vscale x 4 x i32> %a) 108 ret <vscale x 4 x i32> %res 109} 110 111define <vscale x 2 x i64> @reverse_nxv2i64(<vscale x 2 x i64> %a) #0 { 112; CHECK-LABEL: reverse_nxv2i64: 113; CHECK: // %bb.0: 114; CHECK-NEXT: rev z0.d, z0.d 115; CHECK-NEXT: ret 116 117 %res = call <vscale x 2 x i64> @llvm.vector.reverse.nxv2i64(<vscale x 2 x i64> %a) 118 ret <vscale x 2 x i64> %res 119} 120 121define <vscale x 2 x half> @reverse_nxv2f16(<vscale x 2 x half> %a) #0 { 122; CHECK-LABEL: reverse_nxv2f16: 123; CHECK: // %bb.0: 124; CHECK-NEXT: rev z0.d, z0.d 125; CHECK-NEXT: ret 126 127 %res = call <vscale x 2 x half> @llvm.vector.reverse.nxv2f16(<vscale x 2 x half> %a) 128 ret <vscale x 2 x half> %res 129} 130 131define <vscale x 4 x half> @reverse_nxv4f16(<vscale x 4 x half> %a) #0 { 132; CHECK-LABEL: reverse_nxv4f16: 133; CHECK: // %bb.0: 134; CHECK-NEXT: rev z0.s, z0.s 135; CHECK-NEXT: ret 136 137 %res = call <vscale x 4 x half> @llvm.vector.reverse.nxv4f16(<vscale x 4 x half> %a) 138 ret <vscale x 4 x half> %res 139} 140 141define <vscale x 8 x half> @reverse_nxv8f16(<vscale x 8 x half> %a) #0 { 142; CHECK-LABEL: reverse_nxv8f16: 143; CHECK: // %bb.0: 144; CHECK-NEXT: rev z0.h, z0.h 145; CHECK-NEXT: ret 146 147 %res = call <vscale x 8 x half> @llvm.vector.reverse.nxv8f16(<vscale x 8 x half> %a) 148 ret <vscale x 8 x half> %res 149} 150 151define <vscale x 2 x bfloat> @reverse_nxv2bf16(<vscale x 2 x bfloat> %a) #1 { 152; CHECK-LABEL: reverse_nxv2bf16: 153; CHECK: // %bb.0: 154; CHECK-NEXT: rev z0.d, z0.d 155; CHECK-NEXT: ret 156 157 %res = call <vscale x 2 x bfloat> @llvm.vector.reverse.nxv2bf16(<vscale x 2 x bfloat> %a) 158 ret <vscale x 2 x bfloat> %res 159} 160 161define <vscale x 4 x bfloat> @reverse_nxv4bf16(<vscale x 4 x bfloat> %a) #1 { 162; CHECK-LABEL: reverse_nxv4bf16: 163; CHECK: // %bb.0: 164; CHECK-NEXT: rev z0.s, z0.s 165; CHECK-NEXT: ret 166 167 %res = call <vscale x 4 x bfloat> @llvm.vector.reverse.nxv4bf16(<vscale x 4 x bfloat> %a) 168 ret <vscale x 4 x bfloat> %res 169} 170 171define <vscale x 8 x bfloat> @reverse_nxv8bf16(<vscale x 8 x bfloat> %a) #1 { 172; CHECK-LABEL: reverse_nxv8bf16: 173; CHECK: // %bb.0: 174; CHECK-NEXT: rev z0.h, z0.h 175; CHECK-NEXT: ret 176 177 %res = call <vscale x 8 x bfloat> @llvm.vector.reverse.nxv8bf16(<vscale x 8 x bfloat> %a) 178 ret <vscale x 8 x bfloat> %res 179} 180 181define <vscale x 2 x float> @reverse_nxv2f32(<vscale x 2 x float> %a) #0 { 182; CHECK-LABEL: reverse_nxv2f32: 183; CHECK: // %bb.0: 184; CHECK-NEXT: rev z0.d, z0.d 185; CHECK-NEXT: ret 186 187 %res = call <vscale x 2 x float> @llvm.vector.reverse.nxv2f32(<vscale x 2 x float> %a) ret <vscale x 2 x float> %res 188} 189 190define <vscale x 4 x float> @reverse_nxv4f32(<vscale x 4 x float> %a) #0 { 191; CHECK-LABEL: reverse_nxv4f32: 192; CHECK: // %bb.0: 193; CHECK-NEXT: rev z0.s, z0.s 194; CHECK-NEXT: ret 195 196 %res = call <vscale x 4 x float> @llvm.vector.reverse.nxv4f32(<vscale x 4 x float> %a) ret <vscale x 4 x float> %res 197} 198 199define <vscale x 2 x double> @reverse_nxv2f64(<vscale x 2 x double> %a) #0 { 200; CHECK-LABEL: reverse_nxv2f64: 201; CHECK: // %bb.0: 202; CHECK-NEXT: rev z0.d, z0.d 203; CHECK-NEXT: ret 204 205 %res = call <vscale x 2 x double> @llvm.vector.reverse.nxv2f64(<vscale x 2 x double> %a) 206 ret <vscale x 2 x double> %res 207} 208 209; Verify promote type legalisation works as expected. 210define <vscale x 2 x i8> @reverse_nxv2i8(<vscale x 2 x i8> %a) #0 { 211; CHECK-LABEL: reverse_nxv2i8: 212; CHECK: // %bb.0: 213; CHECK-NEXT: rev z0.d, z0.d 214; CHECK-NEXT: ret 215 216 %res = call <vscale x 2 x i8> @llvm.vector.reverse.nxv2i8(<vscale x 2 x i8> %a) 217 ret <vscale x 2 x i8> %res 218} 219 220; Verify splitvec type legalisation works as expected. 221define <vscale x 8 x i32> @reverse_nxv8i32(<vscale x 8 x i32> %a) #0 { 222; CHECK-SELDAG-LABEL: reverse_nxv8i32: 223; CHECK-SELDAG: // %bb.0: 224; CHECK-SELDAG-NEXT: rev z2.s, z1.s 225; CHECK-SELDAG-NEXT: rev z1.s, z0.s 226; CHECK-SELDAG-NEXT: mov z0.d, z2.d 227; CHECK-SELDAG-NEXT: ret 228; 229; CHECK-FASTISEL-LABEL: reverse_nxv8i32: 230; CHECK-FASTISEL: // %bb.0: 231; CHECK-FASTISEL-NEXT: str x29, [sp, #-16]! // 8-byte Folded Spill 232; CHECK-FASTISEL-NEXT: addvl sp, sp, #-1 233; CHECK-FASTISEL-NEXT: str z1, [sp] // 16-byte Folded Spill 234; CHECK-FASTISEL-NEXT: mov z1.d, z0.d 235; CHECK-FASTISEL-NEXT: ldr z0, [sp] // 16-byte Folded Reload 236; CHECK-FASTISEL-NEXT: rev z0.s, z0.s 237; CHECK-FASTISEL-NEXT: rev z1.s, z1.s 238; CHECK-FASTISEL-NEXT: addvl sp, sp, #1 239; CHECK-FASTISEL-NEXT: ldr x29, [sp], #16 // 8-byte Folded Reload 240; CHECK-FASTISEL-NEXT: ret 241 242 %res = call <vscale x 8 x i32> @llvm.vector.reverse.nxv8i32(<vscale x 8 x i32> %a) 243 ret <vscale x 8 x i32> %res 244} 245 246; Verify splitvec type legalisation works as expected. 247define <vscale x 16 x float> @reverse_nxv16f32(<vscale x 16 x float> %a) #0 { 248; CHECK-SELDAG-LABEL: reverse_nxv16f32: 249; CHECK-SELDAG: // %bb.0: 250; CHECK-SELDAG-NEXT: rev z5.s, z3.s 251; CHECK-SELDAG-NEXT: rev z4.s, z2.s 252; CHECK-SELDAG-NEXT: rev z2.s, z1.s 253; CHECK-SELDAG-NEXT: rev z3.s, z0.s 254; CHECK-SELDAG-NEXT: mov z0.d, z5.d 255; CHECK-SELDAG-NEXT: mov z1.d, z4.d 256; CHECK-SELDAG-NEXT: ret 257; 258; CHECK-FASTISEL-LABEL: reverse_nxv16f32: 259; CHECK-FASTISEL: // %bb.0: 260; CHECK-FASTISEL-NEXT: str x29, [sp, #-16]! // 8-byte Folded Spill 261; CHECK-FASTISEL-NEXT: addvl sp, sp, #-2 262; CHECK-FASTISEL-NEXT: str z3, [sp, #1, mul vl] // 16-byte Folded Spill 263; CHECK-FASTISEL-NEXT: str z2, [sp] // 16-byte Folded Spill 264; CHECK-FASTISEL-NEXT: mov z2.d, z1.d 265; CHECK-FASTISEL-NEXT: ldr z1, [sp] // 16-byte Folded Reload 266; CHECK-FASTISEL-NEXT: mov z3.d, z0.d 267; CHECK-FASTISEL-NEXT: ldr z0, [sp, #1, mul vl] // 16-byte Folded Reload 268; CHECK-FASTISEL-NEXT: rev z0.s, z0.s 269; CHECK-FASTISEL-NEXT: rev z1.s, z1.s 270; CHECK-FASTISEL-NEXT: rev z2.s, z2.s 271; CHECK-FASTISEL-NEXT: rev z3.s, z3.s 272; CHECK-FASTISEL-NEXT: addvl sp, sp, #2 273; CHECK-FASTISEL-NEXT: ldr x29, [sp], #16 // 8-byte Folded Reload 274; CHECK-FASTISEL-NEXT: ret 275 276 %res = call <vscale x 16 x float> @llvm.vector.reverse.nxv16f32(<vscale x 16 x float> %a) 277 ret <vscale x 16 x float> %res 278} 279 280 281declare <vscale x 2 x i1> @llvm.vector.reverse.nxv2i1(<vscale x 2 x i1>) 282declare <vscale x 4 x i1> @llvm.vector.reverse.nxv4i1(<vscale x 4 x i1>) 283declare <vscale x 8 x i1> @llvm.vector.reverse.nxv8i1(<vscale x 8 x i1>) 284declare <vscale x 16 x i1> @llvm.vector.reverse.nxv16i1(<vscale x 16 x i1>) 285declare <vscale x 32 x i1> @llvm.vector.reverse.nxv32i1(<vscale x 32 x i1>) 286declare <vscale x 2 x i8> @llvm.vector.reverse.nxv2i8(<vscale x 2 x i8>) 287declare <vscale x 16 x i8> @llvm.vector.reverse.nxv16i8(<vscale x 16 x i8>) 288declare <vscale x 8 x i16> @llvm.vector.reverse.nxv8i16(<vscale x 8 x i16>) 289declare <vscale x 4 x i32> @llvm.vector.reverse.nxv4i32(<vscale x 4 x i32>) 290declare <vscale x 8 x i32> @llvm.vector.reverse.nxv8i32(<vscale x 8 x i32>) 291declare <vscale x 2 x i64> @llvm.vector.reverse.nxv2i64(<vscale x 2 x i64>) 292declare <vscale x 2 x half> @llvm.vector.reverse.nxv2f16(<vscale x 2 x half>) 293declare <vscale x 4 x half> @llvm.vector.reverse.nxv4f16(<vscale x 4 x half>) 294declare <vscale x 8 x half> @llvm.vector.reverse.nxv8f16(<vscale x 8 x half>) 295declare <vscale x 2 x bfloat> @llvm.vector.reverse.nxv2bf16(<vscale x 2 x bfloat>) 296declare <vscale x 4 x bfloat> @llvm.vector.reverse.nxv4bf16(<vscale x 4 x bfloat>) 297declare <vscale x 8 x bfloat> @llvm.vector.reverse.nxv8bf16(<vscale x 8 x bfloat>) 298declare <vscale x 2 x float> @llvm.vector.reverse.nxv2f32(<vscale x 2 x float>) 299declare <vscale x 4 x float> @llvm.vector.reverse.nxv4f32(<vscale x 4 x float>) 300declare <vscale x 16 x float> @llvm.vector.reverse.nxv16f32(<vscale x 16 x float>) 301declare <vscale x 2 x double> @llvm.vector.reverse.nxv2f64(<vscale x 2 x double>) 302 303 304attributes #0 = { nounwind "target-features"="+sve" } 305attributes #1 = { nounwind "target-features"="+sve,+bf16" } 306