1670 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc -aarch64-sve-vector-bits-min=256 < %s | FileCheck %s -check-prefixes=CHECK,VBITS_GE_2563; RUN: llc -aarch64-sve-vector-bits-min=512 < %s | FileCheck %s -check-prefixes=CHECK,VBITS_GE_5124; RUN: llc -aarch64-sve-vector-bits-min=2048 < %s | FileCheck %s -check-prefixes=CHECK,VBITS_GE_5125 6target triple = "aarch64-unknown-linux-gnu"7 8;9; FADDA10;11 12; No single instruction NEON support. Use SVE.13define half @fadda_v4f16(half %start, <4 x half> %a) vscale_range(1,0) #0 {14; CHECK-LABEL: fadda_v4f16:15; CHECK: // %bb.0:16; CHECK-NEXT: ptrue p0.h, vl417; CHECK-NEXT: // kill: def $h0 killed $h0 def $z018; CHECK-NEXT: // kill: def $d1 killed $d1 def $z119; CHECK-NEXT: fadda h0, p0, h0, z1.h20; CHECK-NEXT: // kill: def $h0 killed $h0 killed $z021; CHECK-NEXT: ret22 %res = call half @llvm.vector.reduce.fadd.v4f16(half %start, <4 x half> %a)23 ret half %res24}25 26; No single instruction NEON support. Use SVE.27define half @fadda_v8f16(half %start, <8 x half> %a) vscale_range(1,0) #0 {28; CHECK-LABEL: fadda_v8f16:29; CHECK: // %bb.0:30; CHECK-NEXT: ptrue p0.h, vl831; CHECK-NEXT: // kill: def $h0 killed $h0 def $z032; CHECK-NEXT: // kill: def $q1 killed $q1 def $z133; CHECK-NEXT: fadda h0, p0, h0, z1.h34; CHECK-NEXT: // kill: def $h0 killed $h0 killed $z035; CHECK-NEXT: ret36 %res = call half @llvm.vector.reduce.fadd.v8f16(half %start, <8 x half> %a)37 ret half %res38}39 40define half @fadda_v16f16(half %start, ptr %a) vscale_range(2,0) #0 {41; CHECK-LABEL: fadda_v16f16:42; CHECK: // %bb.0:43; CHECK-NEXT: ptrue p0.h, vl1644; CHECK-NEXT: // kill: def $h0 killed $h0 def $z045; CHECK-NEXT: ld1h { z1.h }, p0/z, [x0]46; CHECK-NEXT: fadda h0, p0, h0, z1.h47; CHECK-NEXT: // kill: def $h0 killed $h0 killed $z048; CHECK-NEXT: ret49 %op = load <16 x half>, ptr %a50 %res = call half @llvm.vector.reduce.fadd.v16f16(half %start, <16 x half> %op)51 ret half %res52}53 54define half @fadda_v32f16(half %start, ptr %a) #0 {55; VBITS_GE_256-LABEL: fadda_v32f16:56; VBITS_GE_256: // %bb.0:57; VBITS_GE_256-NEXT: ptrue p0.h, vl1658; VBITS_GE_256-NEXT: // kill: def $h0 killed $h0 def $z059; VBITS_GE_256-NEXT: mov x8, #16 // =0x1060; VBITS_GE_256-NEXT: ld1h { z1.h }, p0/z, [x0]61; VBITS_GE_256-NEXT: fadda h0, p0, h0, z1.h62; VBITS_GE_256-NEXT: ld1h { z1.h }, p0/z, [x0, x8, lsl #1]63; VBITS_GE_256-NEXT: fadda h0, p0, h0, z1.h64; VBITS_GE_256-NEXT: // kill: def $h0 killed $h0 killed $z065; VBITS_GE_256-NEXT: ret66;67; VBITS_GE_512-LABEL: fadda_v32f16:68; VBITS_GE_512: // %bb.0:69; VBITS_GE_512-NEXT: ptrue p0.h, vl3270; VBITS_GE_512-NEXT: // kill: def $h0 killed $h0 def $z071; VBITS_GE_512-NEXT: ld1h { z1.h }, p0/z, [x0]72; VBITS_GE_512-NEXT: fadda h0, p0, h0, z1.h73; VBITS_GE_512-NEXT: // kill: def $h0 killed $h0 killed $z074; VBITS_GE_512-NEXT: ret75 %op = load <32 x half>, ptr %a76 %res = call half @llvm.vector.reduce.fadd.v32f16(half %start, <32 x half> %op)77 ret half %res78}79 80define half @fadda_v64f16(half %start, ptr %a) vscale_range(8,0) #0 {81; CHECK-LABEL: fadda_v64f16:82; CHECK: // %bb.0:83; CHECK-NEXT: ptrue p0.h, vl6484; CHECK-NEXT: // kill: def $h0 killed $h0 def $z085; CHECK-NEXT: ld1h { z1.h }, p0/z, [x0]86; CHECK-NEXT: fadda h0, p0, h0, z1.h87; CHECK-NEXT: // kill: def $h0 killed $h0 killed $z088; CHECK-NEXT: ret89 %op = load <64 x half>, ptr %a90 %res = call half @llvm.vector.reduce.fadd.v64f16(half %start, <64 x half> %op)91 ret half %res92}93 94define half @fadda_v128f16(half %start, ptr %a) vscale_range(16,0) #0 {95; CHECK-LABEL: fadda_v128f16:96; CHECK: // %bb.0:97; CHECK-NEXT: ptrue p0.h, vl12898; CHECK-NEXT: // kill: def $h0 killed $h0 def $z099; CHECK-NEXT: ld1h { z1.h }, p0/z, [x0]100; CHECK-NEXT: fadda h0, p0, h0, z1.h101; CHECK-NEXT: // kill: def $h0 killed $h0 killed $z0102; CHECK-NEXT: ret103 %op = load <128 x half>, ptr %a104 %res = call half @llvm.vector.reduce.fadd.v128f16(half %start, <128 x half> %op)105 ret half %res106}107 108; No single instruction NEON support. Use SVE.109define float @fadda_v2f32(float %start, <2 x float> %a) vscale_range(1,0) #0 {110; CHECK-LABEL: fadda_v2f32:111; CHECK: // %bb.0:112; CHECK-NEXT: ptrue p0.s, vl2113; CHECK-NEXT: // kill: def $s0 killed $s0 def $z0114; CHECK-NEXT: // kill: def $d1 killed $d1 def $z1115; CHECK-NEXT: fadda s0, p0, s0, z1.s116; CHECK-NEXT: // kill: def $s0 killed $s0 killed $z0117; CHECK-NEXT: ret118 %res = call float @llvm.vector.reduce.fadd.v2f32(float %start, <2 x float> %a)119 ret float %res120}121 122; No single instruction NEON support. Use SVE.123define float @fadda_v4f32(float %start, <4 x float> %a) vscale_range(1,0) #0 {124; CHECK-LABEL: fadda_v4f32:125; CHECK: // %bb.0:126; CHECK-NEXT: ptrue p0.s, vl4127; CHECK-NEXT: // kill: def $s0 killed $s0 def $z0128; CHECK-NEXT: // kill: def $q1 killed $q1 def $z1129; CHECK-NEXT: fadda s0, p0, s0, z1.s130; CHECK-NEXT: // kill: def $s0 killed $s0 killed $z0131; CHECK-NEXT: ret132 %res = call float @llvm.vector.reduce.fadd.v4f32(float %start, <4 x float> %a)133 ret float %res134}135 136define float @fadda_v8f32(float %start, ptr %a) vscale_range(2,0) #0 {137; CHECK-LABEL: fadda_v8f32:138; CHECK: // %bb.0:139; CHECK-NEXT: ptrue p0.s, vl8140; CHECK-NEXT: // kill: def $s0 killed $s0 def $z0141; CHECK-NEXT: ld1w { z1.s }, p0/z, [x0]142; CHECK-NEXT: fadda s0, p0, s0, z1.s143; CHECK-NEXT: // kill: def $s0 killed $s0 killed $z0144; CHECK-NEXT: ret145 %op = load <8 x float>, ptr %a146 %res = call float @llvm.vector.reduce.fadd.v8f32(float %start, <8 x float> %op)147 ret float %res148}149 150define float @fadda_v16f32(float %start, ptr %a) #0 {151; VBITS_GE_256-LABEL: fadda_v16f32:152; VBITS_GE_256: // %bb.0:153; VBITS_GE_256-NEXT: ptrue p0.s, vl8154; VBITS_GE_256-NEXT: // kill: def $s0 killed $s0 def $z0155; VBITS_GE_256-NEXT: mov x8, #8 // =0x8156; VBITS_GE_256-NEXT: ld1w { z1.s }, p0/z, [x0]157; VBITS_GE_256-NEXT: fadda s0, p0, s0, z1.s158; VBITS_GE_256-NEXT: ld1w { z1.s }, p0/z, [x0, x8, lsl #2]159; VBITS_GE_256-NEXT: fadda s0, p0, s0, z1.s160; VBITS_GE_256-NEXT: // kill: def $s0 killed $s0 killed $z0161; VBITS_GE_256-NEXT: ret162;163; VBITS_GE_512-LABEL: fadda_v16f32:164; VBITS_GE_512: // %bb.0:165; VBITS_GE_512-NEXT: ptrue p0.s, vl16166; VBITS_GE_512-NEXT: // kill: def $s0 killed $s0 def $z0167; VBITS_GE_512-NEXT: ld1w { z1.s }, p0/z, [x0]168; VBITS_GE_512-NEXT: fadda s0, p0, s0, z1.s169; VBITS_GE_512-NEXT: // kill: def $s0 killed $s0 killed $z0170; VBITS_GE_512-NEXT: ret171 %op = load <16 x float>, ptr %a172 %res = call float @llvm.vector.reduce.fadd.v16f32(float %start, <16 x float> %op)173 ret float %res174}175 176define float @fadda_v32f32(float %start, ptr %a) vscale_range(8,0) #0 {177; CHECK-LABEL: fadda_v32f32:178; CHECK: // %bb.0:179; CHECK-NEXT: ptrue p0.s, vl32180; CHECK-NEXT: // kill: def $s0 killed $s0 def $z0181; CHECK-NEXT: ld1w { z1.s }, p0/z, [x0]182; CHECK-NEXT: fadda s0, p0, s0, z1.s183; CHECK-NEXT: // kill: def $s0 killed $s0 killed $z0184; CHECK-NEXT: ret185 %op = load <32 x float>, ptr %a186 %res = call float @llvm.vector.reduce.fadd.v32f32(float %start, <32 x float> %op)187 ret float %res188}189 190define float @fadda_v64f32(float %start, ptr %a) vscale_range(16,0) #0 {191; CHECK-LABEL: fadda_v64f32:192; CHECK: // %bb.0:193; CHECK-NEXT: ptrue p0.s, vl64194; CHECK-NEXT: // kill: def $s0 killed $s0 def $z0195; CHECK-NEXT: ld1w { z1.s }, p0/z, [x0]196; CHECK-NEXT: fadda s0, p0, s0, z1.s197; CHECK-NEXT: // kill: def $s0 killed $s0 killed $z0198; CHECK-NEXT: ret199 %op = load <64 x float>, ptr %a200 %res = call float @llvm.vector.reduce.fadd.v64f32(float %start, <64 x float> %op)201 ret float %res202}203 204; No single instruction NEON support. Use SVE.205define double @fadda_v1f64(double %start, <1 x double> %a) vscale_range(1,0) #0 {206; CHECK-LABEL: fadda_v1f64:207; CHECK: // %bb.0:208; CHECK-NEXT: fadd d0, d0, d1209; CHECK-NEXT: ret210 %res = call double @llvm.vector.reduce.fadd.v1f64(double %start, <1 x double> %a)211 ret double %res212}213 214; No single instruction NEON support. Use SVE.215define double @fadda_v2f64(double %start, <2 x double> %a) vscale_range(1,0) #0 {216; CHECK-LABEL: fadda_v2f64:217; CHECK: // %bb.0:218; CHECK-NEXT: ptrue p0.d, vl2219; CHECK-NEXT: // kill: def $d0 killed $d0 def $z0220; CHECK-NEXT: // kill: def $q1 killed $q1 def $z1221; CHECK-NEXT: fadda d0, p0, d0, z1.d222; CHECK-NEXT: // kill: def $d0 killed $d0 killed $z0223; CHECK-NEXT: ret224 %res = call double @llvm.vector.reduce.fadd.v2f64(double %start, <2 x double> %a)225 ret double %res226}227 228define double @fadda_v4f64(double %start, ptr %a) vscale_range(2,0) #0 {229; CHECK-LABEL: fadda_v4f64:230; CHECK: // %bb.0:231; CHECK-NEXT: ptrue p0.d, vl4232; CHECK-NEXT: // kill: def $d0 killed $d0 def $z0233; CHECK-NEXT: ld1d { z1.d }, p0/z, [x0]234; CHECK-NEXT: fadda d0, p0, d0, z1.d235; CHECK-NEXT: // kill: def $d0 killed $d0 killed $z0236; CHECK-NEXT: ret237 %op = load <4 x double>, ptr %a238 %res = call double @llvm.vector.reduce.fadd.v4f64(double %start, <4 x double> %op)239 ret double %res240}241 242define double @fadda_v8f64(double %start, ptr %a) #0 {243; VBITS_GE_256-LABEL: fadda_v8f64:244; VBITS_GE_256: // %bb.0:245; VBITS_GE_256-NEXT: ptrue p0.d, vl4246; VBITS_GE_256-NEXT: // kill: def $d0 killed $d0 def $z0247; VBITS_GE_256-NEXT: mov x8, #4 // =0x4248; VBITS_GE_256-NEXT: ld1d { z1.d }, p0/z, [x0]249; VBITS_GE_256-NEXT: fadda d0, p0, d0, z1.d250; VBITS_GE_256-NEXT: ld1d { z1.d }, p0/z, [x0, x8, lsl #3]251; VBITS_GE_256-NEXT: fadda d0, p0, d0, z1.d252; VBITS_GE_256-NEXT: // kill: def $d0 killed $d0 killed $z0253; VBITS_GE_256-NEXT: ret254;255; VBITS_GE_512-LABEL: fadda_v8f64:256; VBITS_GE_512: // %bb.0:257; VBITS_GE_512-NEXT: ptrue p0.d, vl8258; VBITS_GE_512-NEXT: // kill: def $d0 killed $d0 def $z0259; VBITS_GE_512-NEXT: ld1d { z1.d }, p0/z, [x0]260; VBITS_GE_512-NEXT: fadda d0, p0, d0, z1.d261; VBITS_GE_512-NEXT: // kill: def $d0 killed $d0 killed $z0262; VBITS_GE_512-NEXT: ret263 %op = load <8 x double>, ptr %a264 %res = call double @llvm.vector.reduce.fadd.v8f64(double %start, <8 x double> %op)265 ret double %res266}267 268define double @fadda_v16f64(double %start, ptr %a) vscale_range(8,0) #0 {269; CHECK-LABEL: fadda_v16f64:270; CHECK: // %bb.0:271; CHECK-NEXT: ptrue p0.d, vl16272; CHECK-NEXT: // kill: def $d0 killed $d0 def $z0273; CHECK-NEXT: ld1d { z1.d }, p0/z, [x0]274; CHECK-NEXT: fadda d0, p0, d0, z1.d275; CHECK-NEXT: // kill: def $d0 killed $d0 killed $z0276; CHECK-NEXT: ret277 %op = load <16 x double>, ptr %a278 %res = call double @llvm.vector.reduce.fadd.v16f64(double %start, <16 x double> %op)279 ret double %res280}281 282define double @fadda_v32f64(double %start, ptr %a) vscale_range(16,0) #0 {283; CHECK-LABEL: fadda_v32f64:284; CHECK: // %bb.0:285; CHECK-NEXT: ptrue p0.d, vl32286; CHECK-NEXT: // kill: def $d0 killed $d0 def $z0287; CHECK-NEXT: ld1d { z1.d }, p0/z, [x0]288; CHECK-NEXT: fadda d0, p0, d0, z1.d289; CHECK-NEXT: // kill: def $d0 killed $d0 killed $z0290; CHECK-NEXT: ret291 %op = load <32 x double>, ptr %a292 %res = call double @llvm.vector.reduce.fadd.v32f64(double %start, <32 x double> %op)293 ret double %res294}295 296;297; FADDV298;299 300; No single instruction NEON support for 4 element vectors.301define half @faddv_v4f16(half %start, <4 x half> %a) vscale_range(2,0) #0 {302; CHECK-LABEL: faddv_v4f16:303; CHECK: // %bb.0:304; CHECK-NEXT: ptrue p0.h, vl4305; CHECK-NEXT: // kill: def $d1 killed $d1 def $z1306; CHECK-NEXT: faddv h1, p0, z1.h307; CHECK-NEXT: fadd h0, h0, h1308; CHECK-NEXT: ret309 %res = call fast half @llvm.vector.reduce.fadd.v4f16(half %start, <4 x half> %a)310 ret half %res311}312 313; No single instruction NEON support for 8 element vectors.314define half @faddv_v8f16(half %start, <8 x half> %a) vscale_range(2,0) #0 {315; CHECK-LABEL: faddv_v8f16:316; CHECK: // %bb.0:317; CHECK-NEXT: ptrue p0.h, vl8318; CHECK-NEXT: // kill: def $q1 killed $q1 def $z1319; CHECK-NEXT: faddv h1, p0, z1.h320; CHECK-NEXT: fadd h0, h0, h1321; CHECK-NEXT: ret322 %res = call fast half @llvm.vector.reduce.fadd.v8f16(half %start, <8 x half> %a)323 ret half %res324}325 326define half @faddv_v16f16(half %start, ptr %a) vscale_range(2,0) #0 {327; CHECK-LABEL: faddv_v16f16:328; CHECK: // %bb.0:329; CHECK-NEXT: ptrue p0.h, vl16330; CHECK-NEXT: ld1h { z1.h }, p0/z, [x0]331; CHECK-NEXT: faddv h1, p0, z1.h332; CHECK-NEXT: fadd h0, h0, h1333; CHECK-NEXT: ret334 %op = load <16 x half>, ptr %a335 %res = call fast half @llvm.vector.reduce.fadd.v16f16(half %start, <16 x half> %op)336 ret half %res337}338 339define half @faddv_v32f16(half %start, ptr %a) #0 {340; VBITS_GE_256-LABEL: faddv_v32f16:341; VBITS_GE_256: // %bb.0:342; VBITS_GE_256-NEXT: ptrue p0.h, vl16343; VBITS_GE_256-NEXT: mov x8, #16 // =0x10344; VBITS_GE_256-NEXT: ld1h { z1.h }, p0/z, [x0, x8, lsl #1]345; VBITS_GE_256-NEXT: ld1h { z2.h }, p0/z, [x0]346; VBITS_GE_256-NEXT: fadd z1.h, p0/m, z1.h, z2.h347; VBITS_GE_256-NEXT: faddv h1, p0, z1.h348; VBITS_GE_256-NEXT: fadd h0, h0, h1349; VBITS_GE_256-NEXT: ret350;351; VBITS_GE_512-LABEL: faddv_v32f16:352; VBITS_GE_512: // %bb.0:353; VBITS_GE_512-NEXT: ptrue p0.h, vl32354; VBITS_GE_512-NEXT: ld1h { z1.h }, p0/z, [x0]355; VBITS_GE_512-NEXT: faddv h1, p0, z1.h356; VBITS_GE_512-NEXT: fadd h0, h0, h1357; VBITS_GE_512-NEXT: ret358 %op = load <32 x half>, ptr %a359 %res = call fast half @llvm.vector.reduce.fadd.v32f16(half %start, <32 x half> %op)360 ret half %res361}362 363define half @faddv_v64f16(half %start, ptr %a) vscale_range(8,0) #0 {364; CHECK-LABEL: faddv_v64f16:365; CHECK: // %bb.0:366; CHECK-NEXT: ptrue p0.h, vl64367; CHECK-NEXT: ld1h { z1.h }, p0/z, [x0]368; CHECK-NEXT: faddv h1, p0, z1.h369; CHECK-NEXT: fadd h0, h0, h1370; CHECK-NEXT: ret371 %op = load <64 x half>, ptr %a372 %res = call fast half @llvm.vector.reduce.fadd.v64f16(half %start, <64 x half> %op)373 ret half %res374}375 376define half @faddv_v128f16(half %start, ptr %a) vscale_range(16,0) #0 {377; CHECK-LABEL: faddv_v128f16:378; CHECK: // %bb.0:379; CHECK-NEXT: ptrue p0.h, vl128380; CHECK-NEXT: ld1h { z1.h }, p0/z, [x0]381; CHECK-NEXT: faddv h1, p0, z1.h382; CHECK-NEXT: fadd h0, h0, h1383; CHECK-NEXT: ret384 %op = load <128 x half>, ptr %a385 %res = call fast half @llvm.vector.reduce.fadd.v128f16(half %start, <128 x half> %op)386 ret half %res387}388 389; Don't use SVE for 2 element vectors.390define float @faddv_v2f32(float %start, <2 x float> %a) vscale_range(2,0) #0 {391; CHECK-LABEL: faddv_v2f32:392; CHECK: // %bb.0:393; CHECK-NEXT: faddp s1, v1.2s394; CHECK-NEXT: fadd s0, s0, s1395; CHECK-NEXT: ret396 %res = call fast float @llvm.vector.reduce.fadd.v2f32(float %start, <2 x float> %a)397 ret float %res398}399 400; No single instruction NEON support for 4 element vectors.401define float @faddv_v4f32(float %start, <4 x float> %a) vscale_range(2,0) #0 {402; CHECK-LABEL: faddv_v4f32:403; CHECK: // %bb.0:404; CHECK-NEXT: ptrue p0.s, vl4405; CHECK-NEXT: // kill: def $q1 killed $q1 def $z1406; CHECK-NEXT: faddv s1, p0, z1.s407; CHECK-NEXT: fadd s0, s0, s1408; CHECK-NEXT: ret409 %res = call fast float @llvm.vector.reduce.fadd.v4f32(float %start, <4 x float> %a)410 ret float %res411}412 413define float @faddv_v8f32(float %start, ptr %a) vscale_range(2,0) #0 {414; CHECK-LABEL: faddv_v8f32:415; CHECK: // %bb.0:416; CHECK-NEXT: ptrue p0.s, vl8417; CHECK-NEXT: ld1w { z1.s }, p0/z, [x0]418; CHECK-NEXT: faddv s1, p0, z1.s419; CHECK-NEXT: fadd s0, s0, s1420; CHECK-NEXT: ret421 %op = load <8 x float>, ptr %a422 %res = call fast float @llvm.vector.reduce.fadd.v8f32(float %start, <8 x float> %op)423 ret float %res424}425 426define float @faddv_v16f32(float %start, ptr %a) #0 {427; VBITS_GE_256-LABEL: faddv_v16f32:428; VBITS_GE_256: // %bb.0:429; VBITS_GE_256-NEXT: ptrue p0.s, vl8430; VBITS_GE_256-NEXT: mov x8, #8 // =0x8431; VBITS_GE_256-NEXT: ld1w { z1.s }, p0/z, [x0, x8, lsl #2]432; VBITS_GE_256-NEXT: ld1w { z2.s }, p0/z, [x0]433; VBITS_GE_256-NEXT: fadd z1.s, p0/m, z1.s, z2.s434; VBITS_GE_256-NEXT: faddv s1, p0, z1.s435; VBITS_GE_256-NEXT: fadd s0, s0, s1436; VBITS_GE_256-NEXT: ret437;438; VBITS_GE_512-LABEL: faddv_v16f32:439; VBITS_GE_512: // %bb.0:440; VBITS_GE_512-NEXT: ptrue p0.s, vl16441; VBITS_GE_512-NEXT: ld1w { z1.s }, p0/z, [x0]442; VBITS_GE_512-NEXT: faddv s1, p0, z1.s443; VBITS_GE_512-NEXT: fadd s0, s0, s1444; VBITS_GE_512-NEXT: ret445 %op = load <16 x float>, ptr %a446 %res = call fast float @llvm.vector.reduce.fadd.v16f32(float %start, <16 x float> %op)447 ret float %res448}449 450define float @faddv_v32f32(float %start, ptr %a) vscale_range(8,0) #0 {451; CHECK-LABEL: faddv_v32f32:452; CHECK: // %bb.0:453; CHECK-NEXT: ptrue p0.s, vl32454; CHECK-NEXT: ld1w { z1.s }, p0/z, [x0]455; CHECK-NEXT: faddv s1, p0, z1.s456; CHECK-NEXT: fadd s0, s0, s1457; CHECK-NEXT: ret458 %op = load <32 x float>, ptr %a459 %res = call fast float @llvm.vector.reduce.fadd.v32f32(float %start, <32 x float> %op)460 ret float %res461}462 463define float @faddv_v64f32(float %start, ptr %a) vscale_range(16,0) #0 {464; CHECK-LABEL: faddv_v64f32:465; CHECK: // %bb.0:466; CHECK-NEXT: ptrue p0.s, vl64467; CHECK-NEXT: ld1w { z1.s }, p0/z, [x0]468; CHECK-NEXT: faddv s1, p0, z1.s469; CHECK-NEXT: fadd s0, s0, s1470; CHECK-NEXT: ret471 %op = load <64 x float>, ptr %a472 %res = call fast float @llvm.vector.reduce.fadd.v64f32(float %start, <64 x float> %op)473 ret float %res474}475 476; Don't use SVE for 1 element vectors.477define double @faddv_v1f64(double %start, <1 x double> %a) vscale_range(2,0) #0 {478; CHECK-LABEL: faddv_v1f64:479; CHECK: // %bb.0:480; CHECK-NEXT: fadd d0, d0, d1481; CHECK-NEXT: ret482 %res = call fast double @llvm.vector.reduce.fadd.v1f64(double %start, <1 x double> %a)483 ret double %res484}485 486; Don't use SVE for 2 element vectors.487define double @faddv_v2f64(double %start, <2 x double> %a) vscale_range(2,0) #0 {488; CHECK-LABEL: faddv_v2f64:489; CHECK: // %bb.0:490; CHECK-NEXT: faddp d1, v1.2d491; CHECK-NEXT: fadd d0, d0, d1492; CHECK-NEXT: ret493 %res = call fast double @llvm.vector.reduce.fadd.v2f64(double %start, <2 x double> %a)494 ret double %res495}496 497define double @faddv_v4f64(double %start, ptr %a) vscale_range(2,0) #0 {498; CHECK-LABEL: faddv_v4f64:499; CHECK: // %bb.0:500; CHECK-NEXT: ptrue p0.d, vl4501; CHECK-NEXT: ld1d { z1.d }, p0/z, [x0]502; CHECK-NEXT: faddv d1, p0, z1.d503; CHECK-NEXT: fadd d0, d0, d1504; CHECK-NEXT: ret505 %op = load <4 x double>, ptr %a506 %res = call fast double @llvm.vector.reduce.fadd.v4f64(double %start, <4 x double> %op)507 ret double %res508}509 510define double @faddv_v8f64(double %start, ptr %a) #0 {511; VBITS_GE_256-LABEL: faddv_v8f64:512; VBITS_GE_256: // %bb.0:513; VBITS_GE_256-NEXT: ptrue p0.d, vl4514; VBITS_GE_256-NEXT: mov x8, #4 // =0x4515; VBITS_GE_256-NEXT: ld1d { z1.d }, p0/z, [x0, x8, lsl #3]516; VBITS_GE_256-NEXT: ld1d { z2.d }, p0/z, [x0]517; VBITS_GE_256-NEXT: fadd z1.d, p0/m, z1.d, z2.d518; VBITS_GE_256-NEXT: faddv d1, p0, z1.d519; VBITS_GE_256-NEXT: fadd d0, d0, d1520; VBITS_GE_256-NEXT: ret521;522; VBITS_GE_512-LABEL: faddv_v8f64:523; VBITS_GE_512: // %bb.0:524; VBITS_GE_512-NEXT: ptrue p0.d, vl8525; VBITS_GE_512-NEXT: ld1d { z1.d }, p0/z, [x0]526; VBITS_GE_512-NEXT: faddv d1, p0, z1.d527; VBITS_GE_512-NEXT: fadd d0, d0, d1528; VBITS_GE_512-NEXT: ret529 %op = load <8 x double>, ptr %a530 %res = call fast double @llvm.vector.reduce.fadd.v8f64(double %start, <8 x double> %op)531 ret double %res532}533 534define double @faddv_v16f64(double %start, ptr %a) vscale_range(8,0) #0 {535; CHECK-LABEL: faddv_v16f64:536; CHECK: // %bb.0:537; CHECK-NEXT: ptrue p0.d, vl16538; CHECK-NEXT: ld1d { z1.d }, p0/z, [x0]539; CHECK-NEXT: faddv d1, p0, z1.d540; CHECK-NEXT: fadd d0, d0, d1541; CHECK-NEXT: ret542 %op = load <16 x double>, ptr %a543 %res = call fast double @llvm.vector.reduce.fadd.v16f64(double %start, <16 x double> %op)544 ret double %res545}546 547define double @faddv_v32f64(double %start, ptr %a) vscale_range(16,0) #0 {548; CHECK-LABEL: faddv_v32f64:549; CHECK: // %bb.0:550; CHECK-NEXT: ptrue p0.d, vl32551; CHECK-NEXT: ld1d { z1.d }, p0/z, [x0]552; CHECK-NEXT: faddv d1, p0, z1.d553; CHECK-NEXT: fadd d0, d0, d1554; CHECK-NEXT: ret555 %op = load <32 x double>, ptr %a556 %res = call fast double @llvm.vector.reduce.fadd.v32f64(double %start, <32 x double> %op)557 ret double %res558}559 560;561; FMAXNMV562;563 564; No NEON 16-bit vector FMAXNMV support. Use SVE.565define half @fmaxv_v4f16(<4 x half> %a) vscale_range(2,0) #0 {566; CHECK-LABEL: fmaxv_v4f16:567; CHECK: // %bb.0:568; CHECK-NEXT: fmaxnmv h0, v0.4h569; CHECK-NEXT: ret570 %res = call half @llvm.vector.reduce.fmax.v4f16(<4 x half> %a)571 ret half %res572}573 574; No NEON 16-bit vector FMAXNMV support. Use SVE.575define half @fmaxv_v8f16(<8 x half> %a) vscale_range(2,0) #0 {576; CHECK-LABEL: fmaxv_v8f16:577; CHECK: // %bb.0:578; CHECK-NEXT: fmaxnmv h0, v0.8h579; CHECK-NEXT: ret580 %res = call half @llvm.vector.reduce.fmax.v8f16(<8 x half> %a)581 ret half %res582}583 584define half @fmaxv_v16f16(ptr %a) vscale_range(2,0) #0 {585; CHECK-LABEL: fmaxv_v16f16:586; CHECK: // %bb.0:587; CHECK-NEXT: ptrue p0.h, vl16588; CHECK-NEXT: ld1h { z0.h }, p0/z, [x0]589; CHECK-NEXT: fmaxnmv h0, p0, z0.h590; CHECK-NEXT: // kill: def $h0 killed $h0 killed $z0591; CHECK-NEXT: ret592 %op = load <16 x half>, ptr %a593 %res = call half @llvm.vector.reduce.fmax.v16f16(<16 x half> %op)594 ret half %res595}596 597define half @fmaxv_v32f16(ptr %a) #0 {598; VBITS_GE_256-LABEL: fmaxv_v32f16:599; VBITS_GE_256: // %bb.0:600; VBITS_GE_256-NEXT: ptrue p0.h, vl16601; VBITS_GE_256-NEXT: mov x8, #16 // =0x10602; VBITS_GE_256-NEXT: ld1h { z0.h }, p0/z, [x0, x8, lsl #1]603; VBITS_GE_256-NEXT: ld1h { z1.h }, p0/z, [x0]604; VBITS_GE_256-NEXT: fmaxnm z0.h, p0/m, z0.h, z1.h605; VBITS_GE_256-NEXT: fmaxnmv h0, p0, z0.h606; VBITS_GE_256-NEXT: // kill: def $h0 killed $h0 killed $z0607; VBITS_GE_256-NEXT: ret608;609; VBITS_GE_512-LABEL: fmaxv_v32f16:610; VBITS_GE_512: // %bb.0:611; VBITS_GE_512-NEXT: ptrue p0.h, vl32612; VBITS_GE_512-NEXT: ld1h { z0.h }, p0/z, [x0]613; VBITS_GE_512-NEXT: fmaxnmv h0, p0, z0.h614; VBITS_GE_512-NEXT: // kill: def $h0 killed $h0 killed $z0615; VBITS_GE_512-NEXT: ret616 %op = load <32 x half>, ptr %a617 %res = call half @llvm.vector.reduce.fmax.v32f16(<32 x half> %op)618 ret half %res619}620 621define half @fmaxv_v64f16(ptr %a) vscale_range(8,0) #0 {622; CHECK-LABEL: fmaxv_v64f16:623; CHECK: // %bb.0:624; CHECK-NEXT: ptrue p0.h, vl64625; CHECK-NEXT: ld1h { z0.h }, p0/z, [x0]626; CHECK-NEXT: fmaxnmv h0, p0, z0.h627; CHECK-NEXT: // kill: def $h0 killed $h0 killed $z0628; CHECK-NEXT: ret629 %op = load <64 x half>, ptr %a630 %res = call half @llvm.vector.reduce.fmax.v64f16(<64 x half> %op)631 ret half %res632}633 634define half @fmaxv_v128f16(ptr %a) vscale_range(16,0) #0 {635; CHECK-LABEL: fmaxv_v128f16:636; CHECK: // %bb.0:637; CHECK-NEXT: ptrue p0.h, vl128638; CHECK-NEXT: ld1h { z0.h }, p0/z, [x0]639; CHECK-NEXT: fmaxnmv h0, p0, z0.h640; CHECK-NEXT: // kill: def $h0 killed $h0 killed $z0641; CHECK-NEXT: ret642 %op = load <128 x half>, ptr %a643 %res = call half @llvm.vector.reduce.fmax.v128f16(<128 x half> %op)644 ret half %res645}646 647; Don't use SVE for 64-bit f32 vectors.648define float @fmaxv_v2f32(<2 x float> %a) vscale_range(2,0) #0 {649; CHECK-LABEL: fmaxv_v2f32:650; CHECK: // %bb.0:651; CHECK-NEXT: fmaxnmp s0, v0.2s652; CHECK-NEXT: ret653 %res = call float @llvm.vector.reduce.fmax.v2f32(<2 x float> %a)654 ret float %res655}656 657; Don't use SVE for 128-bit f32 vectors.658define float @fmaxv_v4f32(<4 x float> %a) vscale_range(2,0) #0 {659; CHECK-LABEL: fmaxv_v4f32:660; CHECK: // %bb.0:661; CHECK-NEXT: fmaxnmv s0, v0.4s662; CHECK-NEXT: ret663 %res = call float @llvm.vector.reduce.fmax.v4f32(<4 x float> %a)664 ret float %res665}666 667define float @fmaxv_v8f32(ptr %a) vscale_range(2,0) #0 {668; CHECK-LABEL: fmaxv_v8f32:669; CHECK: // %bb.0:670; CHECK-NEXT: ptrue p0.s, vl8671; CHECK-NEXT: ld1w { z0.s }, p0/z, [x0]672; CHECK-NEXT: fmaxnmv s0, p0, z0.s673; CHECK-NEXT: // kill: def $s0 killed $s0 killed $z0674; CHECK-NEXT: ret675 %op = load <8 x float>, ptr %a676 %res = call float @llvm.vector.reduce.fmax.v8f32(<8 x float> %op)677 ret float %res678}679 680define float @fmaxv_v16f32(ptr %a) #0 {681; VBITS_GE_256-LABEL: fmaxv_v16f32:682; VBITS_GE_256: // %bb.0:683; VBITS_GE_256-NEXT: ptrue p0.s, vl8684; VBITS_GE_256-NEXT: mov x8, #8 // =0x8685; VBITS_GE_256-NEXT: ld1w { z0.s }, p0/z, [x0, x8, lsl #2]686; VBITS_GE_256-NEXT: ld1w { z1.s }, p0/z, [x0]687; VBITS_GE_256-NEXT: fmaxnm z0.s, p0/m, z0.s, z1.s688; VBITS_GE_256-NEXT: fmaxnmv s0, p0, z0.s689; VBITS_GE_256-NEXT: // kill: def $s0 killed $s0 killed $z0690; VBITS_GE_256-NEXT: ret691;692; VBITS_GE_512-LABEL: fmaxv_v16f32:693; VBITS_GE_512: // %bb.0:694; VBITS_GE_512-NEXT: ptrue p0.s, vl16695; VBITS_GE_512-NEXT: ld1w { z0.s }, p0/z, [x0]696; VBITS_GE_512-NEXT: fmaxnmv s0, p0, z0.s697; VBITS_GE_512-NEXT: // kill: def $s0 killed $s0 killed $z0698; VBITS_GE_512-NEXT: ret699 %op = load <16 x float>, ptr %a700 %res = call float @llvm.vector.reduce.fmax.v16f32(<16 x float> %op)701 ret float %res702}703 704define float @fmaxv_v32f32(ptr %a) vscale_range(8,0) #0 {705; CHECK-LABEL: fmaxv_v32f32:706; CHECK: // %bb.0:707; CHECK-NEXT: ptrue p0.s, vl32708; CHECK-NEXT: ld1w { z0.s }, p0/z, [x0]709; CHECK-NEXT: fmaxnmv s0, p0, z0.s710; CHECK-NEXT: // kill: def $s0 killed $s0 killed $z0711; CHECK-NEXT: ret712 %op = load <32 x float>, ptr %a713 %res = call float @llvm.vector.reduce.fmax.v32f32(<32 x float> %op)714 ret float %res715}716 717define float @fmaxv_v64f32(ptr %a) vscale_range(16,0) #0 {718; CHECK-LABEL: fmaxv_v64f32:719; CHECK: // %bb.0:720; CHECK-NEXT: ptrue p0.s, vl64721; CHECK-NEXT: ld1w { z0.s }, p0/z, [x0]722; CHECK-NEXT: fmaxnmv s0, p0, z0.s723; CHECK-NEXT: // kill: def $s0 killed $s0 killed $z0724; CHECK-NEXT: ret725 %op = load <64 x float>, ptr %a726 %res = call float @llvm.vector.reduce.fmax.v64f32(<64 x float> %op)727 ret float %res728}729 730; Nothing to do for single element vectors.731define double @fmaxv_v1f64(<1 x double> %a) vscale_range(2,0) #0 {732; CHECK-LABEL: fmaxv_v1f64:733; CHECK: // %bb.0:734; CHECK-NEXT: ret735 %res = call double @llvm.vector.reduce.fmax.v1f64(<1 x double> %a)736 ret double %res737}738 739; Don't use SVE for 128-bit f64 vectors.740define double @fmaxv_v2f64(<2 x double> %a) vscale_range(2,0) #0 {741; CHECK-LABEL: fmaxv_v2f64:742; CHECK: // %bb.0:743; CHECK-NEXT: fmaxnmp d0, v0.2d744; CHECK-NEXT: ret745 %res = call double @llvm.vector.reduce.fmax.v2f64(<2 x double> %a)746 ret double %res747}748 749define double @fmaxv_v4f64(ptr %a) vscale_range(2,0) #0 {750; CHECK-LABEL: fmaxv_v4f64:751; CHECK: // %bb.0:752; CHECK-NEXT: ptrue p0.d, vl4753; CHECK-NEXT: ld1d { z0.d }, p0/z, [x0]754; CHECK-NEXT: fmaxnmv d0, p0, z0.d755; CHECK-NEXT: // kill: def $d0 killed $d0 killed $z0756; CHECK-NEXT: ret757 %op = load <4 x double>, ptr %a758 %res = call double @llvm.vector.reduce.fmax.v4f64(<4 x double> %op)759 ret double %res760}761 762define double @fmaxv_v8f64(ptr %a) #0 {763; VBITS_GE_256-LABEL: fmaxv_v8f64:764; VBITS_GE_256: // %bb.0:765; VBITS_GE_256-NEXT: ptrue p0.d, vl4766; VBITS_GE_256-NEXT: mov x8, #4 // =0x4767; VBITS_GE_256-NEXT: ld1d { z0.d }, p0/z, [x0, x8, lsl #3]768; VBITS_GE_256-NEXT: ld1d { z1.d }, p0/z, [x0]769; VBITS_GE_256-NEXT: fmaxnm z0.d, p0/m, z0.d, z1.d770; VBITS_GE_256-NEXT: fmaxnmv d0, p0, z0.d771; VBITS_GE_256-NEXT: // kill: def $d0 killed $d0 killed $z0772; VBITS_GE_256-NEXT: ret773;774; VBITS_GE_512-LABEL: fmaxv_v8f64:775; VBITS_GE_512: // %bb.0:776; VBITS_GE_512-NEXT: ptrue p0.d, vl8777; VBITS_GE_512-NEXT: ld1d { z0.d }, p0/z, [x0]778; VBITS_GE_512-NEXT: fmaxnmv d0, p0, z0.d779; VBITS_GE_512-NEXT: // kill: def $d0 killed $d0 killed $z0780; VBITS_GE_512-NEXT: ret781 %op = load <8 x double>, ptr %a782 %res = call double @llvm.vector.reduce.fmax.v8f64(<8 x double> %op)783 ret double %res784}785 786define double @fmaxv_v16f64(ptr %a) vscale_range(8,0) #0 {787; CHECK-LABEL: fmaxv_v16f64:788; CHECK: // %bb.0:789; CHECK-NEXT: ptrue p0.d, vl16790; CHECK-NEXT: ld1d { z0.d }, p0/z, [x0]791; CHECK-NEXT: fmaxnmv d0, p0, z0.d792; CHECK-NEXT: // kill: def $d0 killed $d0 killed $z0793; CHECK-NEXT: ret794 %op = load <16 x double>, ptr %a795 %res = call double @llvm.vector.reduce.fmax.v16f64(<16 x double> %op)796 ret double %res797}798 799define double @fmaxv_v32f64(ptr %a) vscale_range(16,0) #0 {800; CHECK-LABEL: fmaxv_v32f64:801; CHECK: // %bb.0:802; CHECK-NEXT: ptrue p0.d, vl32803; CHECK-NEXT: ld1d { z0.d }, p0/z, [x0]804; CHECK-NEXT: fmaxnmv d0, p0, z0.d805; CHECK-NEXT: // kill: def $d0 killed $d0 killed $z0806; CHECK-NEXT: ret807 %op = load <32 x double>, ptr %a808 %res = call double @llvm.vector.reduce.fmax.v32f64(<32 x double> %op)809 ret double %res810}811 812;813; FMINNMV814;815 816; No NEON 16-bit vector FMINNMV support. Use SVE.817define half @fminv_v4f16(<4 x half> %a) vscale_range(2,0) #0 {818; CHECK-LABEL: fminv_v4f16:819; CHECK: // %bb.0:820; CHECK-NEXT: fminnmv h0, v0.4h821; CHECK-NEXT: ret822 %res = call half @llvm.vector.reduce.fmin.v4f16(<4 x half> %a)823 ret half %res824}825 826; No NEON 16-bit vector FMINNMV support. Use SVE.827define half @fminv_v8f16(<8 x half> %a) vscale_range(2,0) #0 {828; CHECK-LABEL: fminv_v8f16:829; CHECK: // %bb.0:830; CHECK-NEXT: fminnmv h0, v0.8h831; CHECK-NEXT: ret832 %res = call half @llvm.vector.reduce.fmin.v8f16(<8 x half> %a)833 ret half %res834}835 836define half @fminv_v16f16(ptr %a) vscale_range(2,0) #0 {837; CHECK-LABEL: fminv_v16f16:838; CHECK: // %bb.0:839; CHECK-NEXT: ptrue p0.h, vl16840; CHECK-NEXT: ld1h { z0.h }, p0/z, [x0]841; CHECK-NEXT: fminnmv h0, p0, z0.h842; CHECK-NEXT: // kill: def $h0 killed $h0 killed $z0843; CHECK-NEXT: ret844 %op = load <16 x half>, ptr %a845 %res = call half @llvm.vector.reduce.fmin.v16f16(<16 x half> %op)846 ret half %res847}848 849define half @fminv_v32f16(ptr %a) #0 {850; VBITS_GE_256-LABEL: fminv_v32f16:851; VBITS_GE_256: // %bb.0:852; VBITS_GE_256-NEXT: ptrue p0.h, vl16853; VBITS_GE_256-NEXT: mov x8, #16 // =0x10854; VBITS_GE_256-NEXT: ld1h { z0.h }, p0/z, [x0, x8, lsl #1]855; VBITS_GE_256-NEXT: ld1h { z1.h }, p0/z, [x0]856; VBITS_GE_256-NEXT: fminnm z0.h, p0/m, z0.h, z1.h857; VBITS_GE_256-NEXT: fminnmv h0, p0, z0.h858; VBITS_GE_256-NEXT: // kill: def $h0 killed $h0 killed $z0859; VBITS_GE_256-NEXT: ret860;861; VBITS_GE_512-LABEL: fminv_v32f16:862; VBITS_GE_512: // %bb.0:863; VBITS_GE_512-NEXT: ptrue p0.h, vl32864; VBITS_GE_512-NEXT: ld1h { z0.h }, p0/z, [x0]865; VBITS_GE_512-NEXT: fminnmv h0, p0, z0.h866; VBITS_GE_512-NEXT: // kill: def $h0 killed $h0 killed $z0867; VBITS_GE_512-NEXT: ret868 %op = load <32 x half>, ptr %a869 %res = call half @llvm.vector.reduce.fmin.v32f16(<32 x half> %op)870 ret half %res871}872 873define half @fminv_v64f16(ptr %a) vscale_range(8,0) #0 {874; CHECK-LABEL: fminv_v64f16:875; CHECK: // %bb.0:876; CHECK-NEXT: ptrue p0.h, vl64877; CHECK-NEXT: ld1h { z0.h }, p0/z, [x0]878; CHECK-NEXT: fminnmv h0, p0, z0.h879; CHECK-NEXT: // kill: def $h0 killed $h0 killed $z0880; CHECK-NEXT: ret881 %op = load <64 x half>, ptr %a882 %res = call half @llvm.vector.reduce.fmin.v64f16(<64 x half> %op)883 ret half %res884}885 886define half @fminv_v128f16(ptr %a) vscale_range(16,0) #0 {887; CHECK-LABEL: fminv_v128f16:888; CHECK: // %bb.0:889; CHECK-NEXT: ptrue p0.h, vl128890; CHECK-NEXT: ld1h { z0.h }, p0/z, [x0]891; CHECK-NEXT: fminnmv h0, p0, z0.h892; CHECK-NEXT: // kill: def $h0 killed $h0 killed $z0893; CHECK-NEXT: ret894 %op = load <128 x half>, ptr %a895 %res = call half @llvm.vector.reduce.fmin.v128f16(<128 x half> %op)896 ret half %res897}898 899; Don't use SVE for 64-bit f32 vectors.900define float @fminv_v2f32(<2 x float> %a) vscale_range(2,0) #0 {901; CHECK-LABEL: fminv_v2f32:902; CHECK: // %bb.0:903; CHECK-NEXT: fminnmp s0, v0.2s904; CHECK-NEXT: ret905 %res = call float @llvm.vector.reduce.fmin.v2f32(<2 x float> %a)906 ret float %res907}908 909; Don't use SVE for 128-bit f32 vectors.910define float @fminv_v4f32(<4 x float> %a) vscale_range(2,0) #0 {911; CHECK-LABEL: fminv_v4f32:912; CHECK: // %bb.0:913; CHECK-NEXT: fminnmv s0, v0.4s914; CHECK-NEXT: ret915 %res = call float @llvm.vector.reduce.fmin.v4f32(<4 x float> %a)916 ret float %res917}918 919define float @fminv_v8f32(ptr %a) vscale_range(2,0) #0 {920; CHECK-LABEL: fminv_v8f32:921; CHECK: // %bb.0:922; CHECK-NEXT: ptrue p0.s, vl8923; CHECK-NEXT: ld1w { z0.s }, p0/z, [x0]924; CHECK-NEXT: fminnmv s0, p0, z0.s925; CHECK-NEXT: // kill: def $s0 killed $s0 killed $z0926; CHECK-NEXT: ret927 %op = load <8 x float>, ptr %a928 %res = call float @llvm.vector.reduce.fmin.v8f32(<8 x float> %op)929 ret float %res930}931 932define float @fminv_v16f32(ptr %a) #0 {933; VBITS_GE_256-LABEL: fminv_v16f32:934; VBITS_GE_256: // %bb.0:935; VBITS_GE_256-NEXT: ptrue p0.s, vl8936; VBITS_GE_256-NEXT: mov x8, #8 // =0x8937; VBITS_GE_256-NEXT: ld1w { z0.s }, p0/z, [x0, x8, lsl #2]938; VBITS_GE_256-NEXT: ld1w { z1.s }, p0/z, [x0]939; VBITS_GE_256-NEXT: fminnm z0.s, p0/m, z0.s, z1.s940; VBITS_GE_256-NEXT: fminnmv s0, p0, z0.s941; VBITS_GE_256-NEXT: // kill: def $s0 killed $s0 killed $z0942; VBITS_GE_256-NEXT: ret943;944; VBITS_GE_512-LABEL: fminv_v16f32:945; VBITS_GE_512: // %bb.0:946; VBITS_GE_512-NEXT: ptrue p0.s, vl16947; VBITS_GE_512-NEXT: ld1w { z0.s }, p0/z, [x0]948; VBITS_GE_512-NEXT: fminnmv s0, p0, z0.s949; VBITS_GE_512-NEXT: // kill: def $s0 killed $s0 killed $z0950; VBITS_GE_512-NEXT: ret951 %op = load <16 x float>, ptr %a952 %res = call float @llvm.vector.reduce.fmin.v16f32(<16 x float> %op)953 ret float %res954}955 956define float @fminv_v32f32(ptr %a) vscale_range(8,0) #0 {957; CHECK-LABEL: fminv_v32f32:958; CHECK: // %bb.0:959; CHECK-NEXT: ptrue p0.s, vl32960; CHECK-NEXT: ld1w { z0.s }, p0/z, [x0]961; CHECK-NEXT: fminnmv s0, p0, z0.s962; CHECK-NEXT: // kill: def $s0 killed $s0 killed $z0963; CHECK-NEXT: ret964 %op = load <32 x float>, ptr %a965 %res = call float @llvm.vector.reduce.fmin.v32f32(<32 x float> %op)966 ret float %res967}968 969define float @fminv_v64f32(ptr %a) vscale_range(16,0) #0 {970; CHECK-LABEL: fminv_v64f32:971; CHECK: // %bb.0:972; CHECK-NEXT: ptrue p0.s, vl64973; CHECK-NEXT: ld1w { z0.s }, p0/z, [x0]974; CHECK-NEXT: fminnmv s0, p0, z0.s975; CHECK-NEXT: // kill: def $s0 killed $s0 killed $z0976; CHECK-NEXT: ret977 %op = load <64 x float>, ptr %a978 %res = call float @llvm.vector.reduce.fmin.v64f32(<64 x float> %op)979 ret float %res980}981 982; Nothing to do for single element vectors.983define double @fminv_v1f64(<1 x double> %a) vscale_range(2,0) #0 {984; CHECK-LABEL: fminv_v1f64:985; CHECK: // %bb.0:986; CHECK-NEXT: ret987 %res = call double @llvm.vector.reduce.fmin.v1f64(<1 x double> %a)988 ret double %res989}990 991; Don't use SVE for 128-bit f64 vectors.992define double @fminv_v2f64(<2 x double> %a) vscale_range(2,0) #0 {993; CHECK-LABEL: fminv_v2f64:994; CHECK: // %bb.0:995; CHECK-NEXT: fminnmp d0, v0.2d996; CHECK-NEXT: ret997 %res = call double @llvm.vector.reduce.fmin.v2f64(<2 x double> %a)998 ret double %res999}1000 1001define double @fminv_v4f64(ptr %a) vscale_range(2,0) #0 {1002; CHECK-LABEL: fminv_v4f64:1003; CHECK: // %bb.0:1004; CHECK-NEXT: ptrue p0.d, vl41005; CHECK-NEXT: ld1d { z0.d }, p0/z, [x0]1006; CHECK-NEXT: fminnmv d0, p0, z0.d1007; CHECK-NEXT: // kill: def $d0 killed $d0 killed $z01008; CHECK-NEXT: ret1009 %op = load <4 x double>, ptr %a1010 %res = call double @llvm.vector.reduce.fmin.v4f64(<4 x double> %op)1011 ret double %res1012}1013 1014define double @fminv_v8f64(ptr %a) #0 {1015; VBITS_GE_256-LABEL: fminv_v8f64:1016; VBITS_GE_256: // %bb.0:1017; VBITS_GE_256-NEXT: ptrue p0.d, vl41018; VBITS_GE_256-NEXT: mov x8, #4 // =0x41019; VBITS_GE_256-NEXT: ld1d { z0.d }, p0/z, [x0, x8, lsl #3]1020; VBITS_GE_256-NEXT: ld1d { z1.d }, p0/z, [x0]1021; VBITS_GE_256-NEXT: fminnm z0.d, p0/m, z0.d, z1.d1022; VBITS_GE_256-NEXT: fminnmv d0, p0, z0.d1023; VBITS_GE_256-NEXT: // kill: def $d0 killed $d0 killed $z01024; VBITS_GE_256-NEXT: ret1025;1026; VBITS_GE_512-LABEL: fminv_v8f64:1027; VBITS_GE_512: // %bb.0:1028; VBITS_GE_512-NEXT: ptrue p0.d, vl81029; VBITS_GE_512-NEXT: ld1d { z0.d }, p0/z, [x0]1030; VBITS_GE_512-NEXT: fminnmv d0, p0, z0.d1031; VBITS_GE_512-NEXT: // kill: def $d0 killed $d0 killed $z01032; VBITS_GE_512-NEXT: ret1033 %op = load <8 x double>, ptr %a1034 %res = call double @llvm.vector.reduce.fmin.v8f64(<8 x double> %op)1035 ret double %res1036}1037 1038define double @fminv_v16f64(ptr %a) vscale_range(8,0) #0 {1039; CHECK-LABEL: fminv_v16f64:1040; CHECK: // %bb.0:1041; CHECK-NEXT: ptrue p0.d, vl161042; CHECK-NEXT: ld1d { z0.d }, p0/z, [x0]1043; CHECK-NEXT: fminnmv d0, p0, z0.d1044; CHECK-NEXT: // kill: def $d0 killed $d0 killed $z01045; CHECK-NEXT: ret1046 %op = load <16 x double>, ptr %a1047 %res = call double @llvm.vector.reduce.fmin.v16f64(<16 x double> %op)1048 ret double %res1049}1050 1051define double @fminv_v32f64(ptr %a) vscale_range(16,0) #0 {1052; CHECK-LABEL: fminv_v32f64:1053; CHECK: // %bb.0:1054; CHECK-NEXT: ptrue p0.d, vl321055; CHECK-NEXT: ld1d { z0.d }, p0/z, [x0]1056; CHECK-NEXT: fminnmv d0, p0, z0.d1057; CHECK-NEXT: // kill: def $d0 killed $d0 killed $z01058; CHECK-NEXT: ret1059 %op = load <32 x double>, ptr %a1060 %res = call double @llvm.vector.reduce.fmin.v32f64(<32 x double> %op)1061 ret double %res1062}1063 1064;1065; FMAXV1066;1067 1068define half @fmaximumv_v4f16(<4 x half> %a) vscale_range(2,0) #0 {1069; CHECK-LABEL: fmaximumv_v4f16:1070; CHECK: // %bb.0:1071; CHECK-NEXT: fmaxv h0, v0.4h1072; CHECK-NEXT: ret1073 %res = call half @llvm.vector.reduce.fmaximum.v4f16(<4 x half> %a)1074 ret half %res1075}1076 1077define half @fmaximumv_v8f16(<8 x half> %a) vscale_range(2,0) #0 {1078; CHECK-LABEL: fmaximumv_v8f16:1079; CHECK: // %bb.0:1080; CHECK-NEXT: fmaxv h0, v0.8h1081; CHECK-NEXT: ret1082 %res = call half @llvm.vector.reduce.fmaximum.v8f16(<8 x half> %a)1083 ret half %res1084}1085 1086define half @fmaximumv_v16f16(ptr %a) vscale_range(2,0) #0 {1087; CHECK-LABEL: fmaximumv_v16f16:1088; CHECK: // %bb.0:1089; CHECK-NEXT: ptrue p0.h, vl161090; CHECK-NEXT: ld1h { z0.h }, p0/z, [x0]1091; CHECK-NEXT: fmaxv h0, p0, z0.h1092; CHECK-NEXT: // kill: def $h0 killed $h0 killed $z01093; CHECK-NEXT: ret1094 %op = load <16 x half>, ptr %a1095 %res = call half @llvm.vector.reduce.fmaximum.v16f16(<16 x half> %op)1096 ret half %res1097}1098 1099define half @fmaximumv_v32f16(ptr %a) #0 {1100; VBITS_GE_256-LABEL: fmaximumv_v32f16:1101; VBITS_GE_256: // %bb.0:1102; VBITS_GE_256-NEXT: ptrue p0.h, vl161103; VBITS_GE_256-NEXT: mov x8, #16 // =0x101104; VBITS_GE_256-NEXT: ld1h { z0.h }, p0/z, [x0, x8, lsl #1]1105; VBITS_GE_256-NEXT: ld1h { z1.h }, p0/z, [x0]1106; VBITS_GE_256-NEXT: fmax z0.h, p0/m, z0.h, z1.h1107; VBITS_GE_256-NEXT: fmaxv h0, p0, z0.h1108; VBITS_GE_256-NEXT: // kill: def $h0 killed $h0 killed $z01109; VBITS_GE_256-NEXT: ret1110;1111; VBITS_GE_512-LABEL: fmaximumv_v32f16:1112; VBITS_GE_512: // %bb.0:1113; VBITS_GE_512-NEXT: ptrue p0.h, vl321114; VBITS_GE_512-NEXT: ld1h { z0.h }, p0/z, [x0]1115; VBITS_GE_512-NEXT: fmaxv h0, p0, z0.h1116; VBITS_GE_512-NEXT: // kill: def $h0 killed $h0 killed $z01117; VBITS_GE_512-NEXT: ret1118 %op = load <32 x half>, ptr %a1119 %res = call half @llvm.vector.reduce.fmaximum.v32f16(<32 x half> %op)1120 ret half %res1121}1122 1123define half @fmaximumv_v64f16(ptr %a) vscale_range(8,0) #0 {1124; CHECK-LABEL: fmaximumv_v64f16:1125; CHECK: // %bb.0:1126; CHECK-NEXT: ptrue p0.h, vl641127; CHECK-NEXT: ld1h { z0.h }, p0/z, [x0]1128; CHECK-NEXT: fmaxv h0, p0, z0.h1129; CHECK-NEXT: // kill: def $h0 killed $h0 killed $z01130; CHECK-NEXT: ret1131 %op = load <64 x half>, ptr %a1132 %res = call half @llvm.vector.reduce.fmaximum.v64f16(<64 x half> %op)1133 ret half %res1134}1135 1136define half @fmaximumv_v128f16(ptr %a) vscale_range(16,0) #0 {1137; CHECK-LABEL: fmaximumv_v128f16:1138; CHECK: // %bb.0:1139; CHECK-NEXT: ptrue p0.h, vl1281140; CHECK-NEXT: ld1h { z0.h }, p0/z, [x0]1141; CHECK-NEXT: fmaxv h0, p0, z0.h1142; CHECK-NEXT: // kill: def $h0 killed $h0 killed $z01143; CHECK-NEXT: ret1144 %op = load <128 x half>, ptr %a1145 %res = call half @llvm.vector.reduce.fmaximum.v128f16(<128 x half> %op)1146 ret half %res1147}1148 1149; Don't use SVE for 64-bit f32 vectors.1150define float @fmaximumv_v2f32(<2 x float> %a) vscale_range(2,0) #0 {1151; CHECK-LABEL: fmaximumv_v2f32:1152; CHECK: // %bb.0:1153; CHECK-NEXT: fmaxp s0, v0.2s1154; CHECK-NEXT: ret1155 %res = call float @llvm.vector.reduce.fmaximum.v2f32(<2 x float> %a)1156 ret float %res1157}1158 1159; Don't use SVE for 128-bit f32 vectors.1160define float @fmaximumv_v4f32(<4 x float> %a) vscale_range(2,0) #0 {1161; CHECK-LABEL: fmaximumv_v4f32:1162; CHECK: // %bb.0:1163; CHECK-NEXT: fmaxv s0, v0.4s1164; CHECK-NEXT: ret1165 %res = call float @llvm.vector.reduce.fmaximum.v4f32(<4 x float> %a)1166 ret float %res1167}1168 1169define float @fmaximumv_v8f32(ptr %a) vscale_range(2,0) #0 {1170; CHECK-LABEL: fmaximumv_v8f32:1171; CHECK: // %bb.0:1172; CHECK-NEXT: ptrue p0.s, vl81173; CHECK-NEXT: ld1w { z0.s }, p0/z, [x0]1174; CHECK-NEXT: fmaxv s0, p0, z0.s1175; CHECK-NEXT: // kill: def $s0 killed $s0 killed $z01176; CHECK-NEXT: ret1177 %op = load <8 x float>, ptr %a1178 %res = call float @llvm.vector.reduce.fmaximum.v8f32(<8 x float> %op)1179 ret float %res1180}1181 1182define float @fmaximumv_v16f32(ptr %a) #0 {1183; VBITS_GE_256-LABEL: fmaximumv_v16f32:1184; VBITS_GE_256: // %bb.0:1185; VBITS_GE_256-NEXT: ptrue p0.s, vl81186; VBITS_GE_256-NEXT: mov x8, #8 // =0x81187; VBITS_GE_256-NEXT: ld1w { z0.s }, p0/z, [x0, x8, lsl #2]1188; VBITS_GE_256-NEXT: ld1w { z1.s }, p0/z, [x0]1189; VBITS_GE_256-NEXT: fmax z0.s, p0/m, z0.s, z1.s1190; VBITS_GE_256-NEXT: fmaxv s0, p0, z0.s1191; VBITS_GE_256-NEXT: // kill: def $s0 killed $s0 killed $z01192; VBITS_GE_256-NEXT: ret1193;1194; VBITS_GE_512-LABEL: fmaximumv_v16f32:1195; VBITS_GE_512: // %bb.0:1196; VBITS_GE_512-NEXT: ptrue p0.s, vl161197; VBITS_GE_512-NEXT: ld1w { z0.s }, p0/z, [x0]1198; VBITS_GE_512-NEXT: fmaxv s0, p0, z0.s1199; VBITS_GE_512-NEXT: // kill: def $s0 killed $s0 killed $z01200; VBITS_GE_512-NEXT: ret1201 %op = load <16 x float>, ptr %a1202 %res = call float @llvm.vector.reduce.fmaximum.v16f32(<16 x float> %op)1203 ret float %res1204}1205 1206define float @fmaximumv_v32f32(ptr %a) vscale_range(8,0) #0 {1207; CHECK-LABEL: fmaximumv_v32f32:1208; CHECK: // %bb.0:1209; CHECK-NEXT: ptrue p0.s, vl321210; CHECK-NEXT: ld1w { z0.s }, p0/z, [x0]1211; CHECK-NEXT: fmaxv s0, p0, z0.s1212; CHECK-NEXT: // kill: def $s0 killed $s0 killed $z01213; CHECK-NEXT: ret1214 %op = load <32 x float>, ptr %a1215 %res = call float @llvm.vector.reduce.fmaximum.v32f32(<32 x float> %op)1216 ret float %res1217}1218 1219define float @fmaximumv_v64f32(ptr %a) vscale_range(16,0) #0 {1220; CHECK-LABEL: fmaximumv_v64f32:1221; CHECK: // %bb.0:1222; CHECK-NEXT: ptrue p0.s, vl641223; CHECK-NEXT: ld1w { z0.s }, p0/z, [x0]1224; CHECK-NEXT: fmaxv s0, p0, z0.s1225; CHECK-NEXT: // kill: def $s0 killed $s0 killed $z01226; CHECK-NEXT: ret1227 %op = load <64 x float>, ptr %a1228 %res = call float @llvm.vector.reduce.fmaximum.v64f32(<64 x float> %op)1229 ret float %res1230}1231 1232; Nothing to do for single element vectors.1233define double @fmaximumv_v1f64(<1 x double> %a) vscale_range(2,0) #0 {1234; CHECK-LABEL: fmaximumv_v1f64:1235; CHECK: // %bb.0:1236; CHECK-NEXT: ret1237 %res = call double @llvm.vector.reduce.fmaximum.v1f64(<1 x double> %a)1238 ret double %res1239}1240 1241; Don't use SVE for 128-bit f64 vectors.1242define double @fmaximumv_v2f64(<2 x double> %a) vscale_range(2,0) #0 {1243; CHECK-LABEL: fmaximumv_v2f64:1244; CHECK: // %bb.0:1245; CHECK-NEXT: fmaxp d0, v0.2d1246; CHECK-NEXT: ret1247 %res = call double @llvm.vector.reduce.fmaximum.v2f64(<2 x double> %a)1248 ret double %res1249}1250 1251define double @fmaximumv_v4f64(ptr %a) vscale_range(2,0) #0 {1252; CHECK-LABEL: fmaximumv_v4f64:1253; CHECK: // %bb.0:1254; CHECK-NEXT: ptrue p0.d, vl41255; CHECK-NEXT: ld1d { z0.d }, p0/z, [x0]1256; CHECK-NEXT: fmaxv d0, p0, z0.d1257; CHECK-NEXT: // kill: def $d0 killed $d0 killed $z01258; CHECK-NEXT: ret1259 %op = load <4 x double>, ptr %a1260 %res = call double @llvm.vector.reduce.fmaximum.v4f64(<4 x double> %op)1261 ret double %res1262}1263 1264define double @fmaximumv_v8f64(ptr %a) #0 {1265; VBITS_GE_256-LABEL: fmaximumv_v8f64:1266; VBITS_GE_256: // %bb.0:1267; VBITS_GE_256-NEXT: ptrue p0.d, vl41268; VBITS_GE_256-NEXT: mov x8, #4 // =0x41269; VBITS_GE_256-NEXT: ld1d { z0.d }, p0/z, [x0, x8, lsl #3]1270; VBITS_GE_256-NEXT: ld1d { z1.d }, p0/z, [x0]1271; VBITS_GE_256-NEXT: fmax z0.d, p0/m, z0.d, z1.d1272; VBITS_GE_256-NEXT: fmaxv d0, p0, z0.d1273; VBITS_GE_256-NEXT: // kill: def $d0 killed $d0 killed $z01274; VBITS_GE_256-NEXT: ret1275;1276; VBITS_GE_512-LABEL: fmaximumv_v8f64:1277; VBITS_GE_512: // %bb.0:1278; VBITS_GE_512-NEXT: ptrue p0.d, vl81279; VBITS_GE_512-NEXT: ld1d { z0.d }, p0/z, [x0]1280; VBITS_GE_512-NEXT: fmaxv d0, p0, z0.d1281; VBITS_GE_512-NEXT: // kill: def $d0 killed $d0 killed $z01282; VBITS_GE_512-NEXT: ret1283 %op = load <8 x double>, ptr %a1284 %res = call double @llvm.vector.reduce.fmaximum.v8f64(<8 x double> %op)1285 ret double %res1286}1287 1288define double @fmaximumv_v16f64(ptr %a) vscale_range(8,0) #0 {1289; CHECK-LABEL: fmaximumv_v16f64:1290; CHECK: // %bb.0:1291; CHECK-NEXT: ptrue p0.d, vl161292; CHECK-NEXT: ld1d { z0.d }, p0/z, [x0]1293; CHECK-NEXT: fmaxv d0, p0, z0.d1294; CHECK-NEXT: // kill: def $d0 killed $d0 killed $z01295; CHECK-NEXT: ret1296 %op = load <16 x double>, ptr %a1297 %res = call double @llvm.vector.reduce.fmaximum.v16f64(<16 x double> %op)1298 ret double %res1299}1300 1301define double @fmaximumv_v32f64(ptr %a) vscale_range(16,0) #0 {1302; CHECK-LABEL: fmaximumv_v32f64:1303; CHECK: // %bb.0:1304; CHECK-NEXT: ptrue p0.d, vl321305; CHECK-NEXT: ld1d { z0.d }, p0/z, [x0]1306; CHECK-NEXT: fmaxv d0, p0, z0.d1307; CHECK-NEXT: // kill: def $d0 killed $d0 killed $z01308; CHECK-NEXT: ret1309 %op = load <32 x double>, ptr %a1310 %res = call double @llvm.vector.reduce.fmaximum.v32f64(<32 x double> %op)1311 ret double %res1312}1313 1314;1315; FMINV1316;1317 1318define half @fminimumv_v4f16(<4 x half> %a) vscale_range(2,0) #0 {1319; CHECK-LABEL: fminimumv_v4f16:1320; CHECK: // %bb.0:1321; CHECK-NEXT: fminv h0, v0.4h1322; CHECK-NEXT: ret1323 %res = call half @llvm.vector.reduce.fminimum.v4f16(<4 x half> %a)1324 ret half %res1325}1326 1327define half @fminimumv_v8f16(<8 x half> %a) vscale_range(2,0) #0 {1328; CHECK-LABEL: fminimumv_v8f16:1329; CHECK: // %bb.0:1330; CHECK-NEXT: fminv h0, v0.8h1331; CHECK-NEXT: ret1332 %res = call half @llvm.vector.reduce.fminimum.v8f16(<8 x half> %a)1333 ret half %res1334}1335 1336define half @fminimumv_v16f16(ptr %a) vscale_range(2,0) #0 {1337; CHECK-LABEL: fminimumv_v16f16:1338; CHECK: // %bb.0:1339; CHECK-NEXT: ptrue p0.h, vl161340; CHECK-NEXT: ld1h { z0.h }, p0/z, [x0]1341; CHECK-NEXT: fminv h0, p0, z0.h1342; CHECK-NEXT: // kill: def $h0 killed $h0 killed $z01343; CHECK-NEXT: ret1344 %op = load <16 x half>, ptr %a1345 %res = call half @llvm.vector.reduce.fminimum.v16f16(<16 x half> %op)1346 ret half %res1347}1348 1349define half @fminimumv_v32f16(ptr %a) #0 {1350; VBITS_GE_256-LABEL: fminimumv_v32f16:1351; VBITS_GE_256: // %bb.0:1352; VBITS_GE_256-NEXT: ptrue p0.h, vl161353; VBITS_GE_256-NEXT: mov x8, #16 // =0x101354; VBITS_GE_256-NEXT: ld1h { z0.h }, p0/z, [x0, x8, lsl #1]1355; VBITS_GE_256-NEXT: ld1h { z1.h }, p0/z, [x0]1356; VBITS_GE_256-NEXT: fmin z0.h, p0/m, z0.h, z1.h1357; VBITS_GE_256-NEXT: fminv h0, p0, z0.h1358; VBITS_GE_256-NEXT: // kill: def $h0 killed $h0 killed $z01359; VBITS_GE_256-NEXT: ret1360;1361; VBITS_GE_512-LABEL: fminimumv_v32f16:1362; VBITS_GE_512: // %bb.0:1363; VBITS_GE_512-NEXT: ptrue p0.h, vl321364; VBITS_GE_512-NEXT: ld1h { z0.h }, p0/z, [x0]1365; VBITS_GE_512-NEXT: fminv h0, p0, z0.h1366; VBITS_GE_512-NEXT: // kill: def $h0 killed $h0 killed $z01367; VBITS_GE_512-NEXT: ret1368 %op = load <32 x half>, ptr %a1369 %res = call half @llvm.vector.reduce.fminimum.v32f16(<32 x half> %op)1370 ret half %res1371}1372 1373define half @fminimumv_v64f16(ptr %a) vscale_range(8,0) #0 {1374; CHECK-LABEL: fminimumv_v64f16:1375; CHECK: // %bb.0:1376; CHECK-NEXT: ptrue p0.h, vl641377; CHECK-NEXT: ld1h { z0.h }, p0/z, [x0]1378; CHECK-NEXT: fminv h0, p0, z0.h1379; CHECK-NEXT: // kill: def $h0 killed $h0 killed $z01380; CHECK-NEXT: ret1381 %op = load <64 x half>, ptr %a1382 %res = call half @llvm.vector.reduce.fminimum.v64f16(<64 x half> %op)1383 ret half %res1384}1385 1386define half @fminimumv_v128f16(ptr %a) vscale_range(16,0) #0 {1387; CHECK-LABEL: fminimumv_v128f16:1388; CHECK: // %bb.0:1389; CHECK-NEXT: ptrue p0.h, vl1281390; CHECK-NEXT: ld1h { z0.h }, p0/z, [x0]1391; CHECK-NEXT: fminv h0, p0, z0.h1392; CHECK-NEXT: // kill: def $h0 killed $h0 killed $z01393; CHECK-NEXT: ret1394 %op = load <128 x half>, ptr %a1395 %res = call half @llvm.vector.reduce.fminimum.v128f16(<128 x half> %op)1396 ret half %res1397}1398 1399; Don't use SVE for 64-bit f32 vectors.1400define float @fminimumv_v2f32(<2 x float> %a) vscale_range(2,0) #0 {1401; CHECK-LABEL: fminimumv_v2f32:1402; CHECK: // %bb.0:1403; CHECK-NEXT: fminp s0, v0.2s1404; CHECK-NEXT: ret1405 %res = call float @llvm.vector.reduce.fminimum.v2f32(<2 x float> %a)1406 ret float %res1407}1408 1409; Don't use SVE for 128-bit f32 vectors.1410define float @fminimumv_v4f32(<4 x float> %a) vscale_range(2,0) #0 {1411; CHECK-LABEL: fminimumv_v4f32:1412; CHECK: // %bb.0:1413; CHECK-NEXT: fminv s0, v0.4s1414; CHECK-NEXT: ret1415 %res = call float @llvm.vector.reduce.fminimum.v4f32(<4 x float> %a)1416 ret float %res1417}1418 1419define float @fminimumv_v8f32(ptr %a) vscale_range(2,0) #0 {1420; CHECK-LABEL: fminimumv_v8f32:1421; CHECK: // %bb.0:1422; CHECK-NEXT: ptrue p0.s, vl81423; CHECK-NEXT: ld1w { z0.s }, p0/z, [x0]1424; CHECK-NEXT: fminv s0, p0, z0.s1425; CHECK-NEXT: // kill: def $s0 killed $s0 killed $z01426; CHECK-NEXT: ret1427 %op = load <8 x float>, ptr %a1428 %res = call float @llvm.vector.reduce.fminimum.v8f32(<8 x float> %op)1429 ret float %res1430}1431 1432define float @fminimumv_v16f32(ptr %a) #0 {1433; VBITS_GE_256-LABEL: fminimumv_v16f32:1434; VBITS_GE_256: // %bb.0:1435; VBITS_GE_256-NEXT: ptrue p0.s, vl81436; VBITS_GE_256-NEXT: mov x8, #8 // =0x81437; VBITS_GE_256-NEXT: ld1w { z0.s }, p0/z, [x0, x8, lsl #2]1438; VBITS_GE_256-NEXT: ld1w { z1.s }, p0/z, [x0]1439; VBITS_GE_256-NEXT: fmin z0.s, p0/m, z0.s, z1.s1440; VBITS_GE_256-NEXT: fminv s0, p0, z0.s1441; VBITS_GE_256-NEXT: // kill: def $s0 killed $s0 killed $z01442; VBITS_GE_256-NEXT: ret1443;1444; VBITS_GE_512-LABEL: fminimumv_v16f32:1445; VBITS_GE_512: // %bb.0:1446; VBITS_GE_512-NEXT: ptrue p0.s, vl161447; VBITS_GE_512-NEXT: ld1w { z0.s }, p0/z, [x0]1448; VBITS_GE_512-NEXT: fminv s0, p0, z0.s1449; VBITS_GE_512-NEXT: // kill: def $s0 killed $s0 killed $z01450; VBITS_GE_512-NEXT: ret1451 %op = load <16 x float>, ptr %a1452 %res = call float @llvm.vector.reduce.fminimum.v16f32(<16 x float> %op)1453 ret float %res1454}1455 1456define float @fminimumv_v32f32(ptr %a) vscale_range(8,0) #0 {1457; CHECK-LABEL: fminimumv_v32f32:1458; CHECK: // %bb.0:1459; CHECK-NEXT: ptrue p0.s, vl321460; CHECK-NEXT: ld1w { z0.s }, p0/z, [x0]1461; CHECK-NEXT: fminv s0, p0, z0.s1462; CHECK-NEXT: // kill: def $s0 killed $s0 killed $z01463; CHECK-NEXT: ret1464 %op = load <32 x float>, ptr %a1465 %res = call float @llvm.vector.reduce.fminimum.v32f32(<32 x float> %op)1466 ret float %res1467}1468 1469define float @fminimumv_v64f32(ptr %a) vscale_range(16,0) #0 {1470; CHECK-LABEL: fminimumv_v64f32:1471; CHECK: // %bb.0:1472; CHECK-NEXT: ptrue p0.s, vl641473; CHECK-NEXT: ld1w { z0.s }, p0/z, [x0]1474; CHECK-NEXT: fminv s0, p0, z0.s1475; CHECK-NEXT: // kill: def $s0 killed $s0 killed $z01476; CHECK-NEXT: ret1477 %op = load <64 x float>, ptr %a1478 %res = call float @llvm.vector.reduce.fminimum.v64f32(<64 x float> %op)1479 ret float %res1480}1481 1482; Nothing to do for single element vectors.1483define double @fminimumv_v1f64(<1 x double> %a) vscale_range(2,0) #0 {1484; CHECK-LABEL: fminimumv_v1f64:1485; CHECK: // %bb.0:1486; CHECK-NEXT: ret1487 %res = call double @llvm.vector.reduce.fminimum.v1f64(<1 x double> %a)1488 ret double %res1489}1490 1491; Don't use SVE for 128-bit f64 vectors.1492define double @fminimumv_v2f64(<2 x double> %a) vscale_range(2,0) #0 {1493; CHECK-LABEL: fminimumv_v2f64:1494; CHECK: // %bb.0:1495; CHECK-NEXT: fminp d0, v0.2d1496; CHECK-NEXT: ret1497 %res = call double @llvm.vector.reduce.fminimum.v2f64(<2 x double> %a)1498 ret double %res1499}1500 1501define double @fminimumv_v4f64(ptr %a) vscale_range(2,0) #0 {1502; CHECK-LABEL: fminimumv_v4f64:1503; CHECK: // %bb.0:1504; CHECK-NEXT: ptrue p0.d, vl41505; CHECK-NEXT: ld1d { z0.d }, p0/z, [x0]1506; CHECK-NEXT: fminv d0, p0, z0.d1507; CHECK-NEXT: // kill: def $d0 killed $d0 killed $z01508; CHECK-NEXT: ret1509 %op = load <4 x double>, ptr %a1510 %res = call double @llvm.vector.reduce.fminimum.v4f64(<4 x double> %op)1511 ret double %res1512}1513 1514define double @fminimumv_v8f64(ptr %a) #0 {1515; VBITS_GE_256-LABEL: fminimumv_v8f64:1516; VBITS_GE_256: // %bb.0:1517; VBITS_GE_256-NEXT: ptrue p0.d, vl41518; VBITS_GE_256-NEXT: mov x8, #4 // =0x41519; VBITS_GE_256-NEXT: ld1d { z0.d }, p0/z, [x0, x8, lsl #3]1520; VBITS_GE_256-NEXT: ld1d { z1.d }, p0/z, [x0]1521; VBITS_GE_256-NEXT: fmin z0.d, p0/m, z0.d, z1.d1522; VBITS_GE_256-NEXT: fminv d0, p0, z0.d1523; VBITS_GE_256-NEXT: // kill: def $d0 killed $d0 killed $z01524; VBITS_GE_256-NEXT: ret1525;1526; VBITS_GE_512-LABEL: fminimumv_v8f64:1527; VBITS_GE_512: // %bb.0:1528; VBITS_GE_512-NEXT: ptrue p0.d, vl81529; VBITS_GE_512-NEXT: ld1d { z0.d }, p0/z, [x0]1530; VBITS_GE_512-NEXT: fminv d0, p0, z0.d1531; VBITS_GE_512-NEXT: // kill: def $d0 killed $d0 killed $z01532; VBITS_GE_512-NEXT: ret1533 %op = load <8 x double>, ptr %a1534 %res = call double @llvm.vector.reduce.fminimum.v8f64(<8 x double> %op)1535 ret double %res1536}1537 1538define double @fminimumv_v16f64(ptr %a) vscale_range(8,0) #0 {1539; CHECK-LABEL: fminimumv_v16f64:1540; CHECK: // %bb.0:1541; CHECK-NEXT: ptrue p0.d, vl161542; CHECK-NEXT: ld1d { z0.d }, p0/z, [x0]1543; CHECK-NEXT: fminv d0, p0, z0.d1544; CHECK-NEXT: // kill: def $d0 killed $d0 killed $z01545; CHECK-NEXT: ret1546 %op = load <16 x double>, ptr %a1547 %res = call double @llvm.vector.reduce.fminimum.v16f64(<16 x double> %op)1548 ret double %res1549}1550 1551define double @fminimumv_v32f64(ptr %a) vscale_range(16,0) #0 {1552; CHECK-LABEL: fminimumv_v32f64:1553; CHECK: // %bb.0:1554; CHECK-NEXT: ptrue p0.d, vl321555; CHECK-NEXT: ld1d { z0.d }, p0/z, [x0]1556; CHECK-NEXT: fminv d0, p0, z0.d1557; CHECK-NEXT: // kill: def $d0 killed $d0 killed $z01558; CHECK-NEXT: ret1559 %op = load <32 x double>, ptr %a1560 %res = call double @llvm.vector.reduce.fminimum.v32f64(<32 x double> %op)1561 ret double %res1562}1563 1564attributes #0 = { "target-features"="+sve" }1565 1566declare half @llvm.vector.reduce.fadd.v4f16(half, <4 x half>)1567declare half @llvm.vector.reduce.fadd.v8f16(half, <8 x half>)1568declare half @llvm.vector.reduce.fadd.v16f16(half, <16 x half>)1569declare half @llvm.vector.reduce.fadd.v32f16(half, <32 x half>)1570declare half @llvm.vector.reduce.fadd.v64f16(half, <64 x half>)1571declare half @llvm.vector.reduce.fadd.v128f16(half, <128 x half>)1572 1573declare float @llvm.vector.reduce.fadd.v2f32(float, <2 x float>)1574declare float @llvm.vector.reduce.fadd.v4f32(float, <4 x float>)1575declare float @llvm.vector.reduce.fadd.v8f32(float, <8 x float>)1576declare float @llvm.vector.reduce.fadd.v16f32(float, <16 x float>)1577declare float @llvm.vector.reduce.fadd.v32f32(float, <32 x float>)1578declare float @llvm.vector.reduce.fadd.v64f32(float, <64 x float>)1579 1580declare double @llvm.vector.reduce.fadd.v1f64(double, <1 x double>)1581declare double @llvm.vector.reduce.fadd.v2f64(double, <2 x double>)1582declare double @llvm.vector.reduce.fadd.v4f64(double, <4 x double>)1583declare double @llvm.vector.reduce.fadd.v8f64(double, <8 x double>)1584declare double @llvm.vector.reduce.fadd.v16f64(double, <16 x double>)1585declare double @llvm.vector.reduce.fadd.v32f64(double, <32 x double>)1586 1587declare half @llvm.vector.reduce.fmax.v4f16(<4 x half>)1588declare half @llvm.vector.reduce.fmax.v8f16(<8 x half>)1589declare half @llvm.vector.reduce.fmax.v16f16(<16 x half>)1590declare half @llvm.vector.reduce.fmax.v32f16(<32 x half>)1591declare half @llvm.vector.reduce.fmax.v64f16(<64 x half>)1592declare half @llvm.vector.reduce.fmax.v128f16(<128 x half>)1593 1594declare float @llvm.vector.reduce.fmax.v2f32(<2 x float>)1595declare float @llvm.vector.reduce.fmax.v4f32(<4 x float>)1596declare float @llvm.vector.reduce.fmax.v8f32(<8 x float>)1597declare float @llvm.vector.reduce.fmax.v16f32(<16 x float>)1598declare float @llvm.vector.reduce.fmax.v32f32(<32 x float>)1599declare float @llvm.vector.reduce.fmax.v64f32(<64 x float>)1600 1601declare double @llvm.vector.reduce.fmax.v1f64(<1 x double>)1602declare double @llvm.vector.reduce.fmax.v2f64(<2 x double>)1603declare double @llvm.vector.reduce.fmax.v4f64(<4 x double>)1604declare double @llvm.vector.reduce.fmax.v8f64(<8 x double>)1605declare double @llvm.vector.reduce.fmax.v16f64(<16 x double>)1606declare double @llvm.vector.reduce.fmax.v32f64(<32 x double>)1607 1608declare half @llvm.vector.reduce.fmin.v4f16(<4 x half>)1609declare half @llvm.vector.reduce.fmin.v8f16(<8 x half>)1610declare half @llvm.vector.reduce.fmin.v16f16(<16 x half>)1611declare half @llvm.vector.reduce.fmin.v32f16(<32 x half>)1612declare half @llvm.vector.reduce.fmin.v64f16(<64 x half>)1613declare half @llvm.vector.reduce.fmin.v128f16(<128 x half>)1614 1615declare float @llvm.vector.reduce.fmin.v2f32(<2 x float>)1616declare float @llvm.vector.reduce.fmin.v4f32(<4 x float>)1617declare float @llvm.vector.reduce.fmin.v8f32(<8 x float>)1618declare float @llvm.vector.reduce.fmin.v16f32(<16 x float>)1619declare float @llvm.vector.reduce.fmin.v32f32(<32 x float>)1620declare float @llvm.vector.reduce.fmin.v64f32(<64 x float>)1621 1622declare double @llvm.vector.reduce.fmin.v1f64(<1 x double>)1623declare double @llvm.vector.reduce.fmin.v2f64(<2 x double>)1624declare double @llvm.vector.reduce.fmin.v4f64(<4 x double>)1625declare double @llvm.vector.reduce.fmin.v8f64(<8 x double>)1626declare double @llvm.vector.reduce.fmin.v16f64(<16 x double>)1627declare double @llvm.vector.reduce.fmin.v32f64(<32 x double>)1628 1629declare half @llvm.vector.reduce.fmaximum.v4f16(<4 x half>)1630declare half @llvm.vector.reduce.fmaximum.v8f16(<8 x half>)1631declare half @llvm.vector.reduce.fmaximum.v16f16(<16 x half>)1632declare half @llvm.vector.reduce.fmaximum.v32f16(<32 x half>)1633declare half @llvm.vector.reduce.fmaximum.v64f16(<64 x half>)1634declare half @llvm.vector.reduce.fmaximum.v128f16(<128 x half>)1635 1636declare float @llvm.vector.reduce.fmaximum.v2f32(<2 x float>)1637declare float @llvm.vector.reduce.fmaximum.v4f32(<4 x float>)1638declare float @llvm.vector.reduce.fmaximum.v8f32(<8 x float>)1639declare float @llvm.vector.reduce.fmaximum.v16f32(<16 x float>)1640declare float @llvm.vector.reduce.fmaximum.v32f32(<32 x float>)1641declare float @llvm.vector.reduce.fmaximum.v64f32(<64 x float>)1642 1643declare double @llvm.vector.reduce.fmaximum.v1f64(<1 x double>)1644declare double @llvm.vector.reduce.fmaximum.v2f64(<2 x double>)1645declare double @llvm.vector.reduce.fmaximum.v4f64(<4 x double>)1646declare double @llvm.vector.reduce.fmaximum.v8f64(<8 x double>)1647declare double @llvm.vector.reduce.fmaximum.v16f64(<16 x double>)1648declare double @llvm.vector.reduce.fmaximum.v32f64(<32 x double>)1649 1650declare half @llvm.vector.reduce.fminimum.v4f16(<4 x half>)1651declare half @llvm.vector.reduce.fminimum.v8f16(<8 x half>)1652declare half @llvm.vector.reduce.fminimum.v16f16(<16 x half>)1653declare half @llvm.vector.reduce.fminimum.v32f16(<32 x half>)1654declare half @llvm.vector.reduce.fminimum.v64f16(<64 x half>)1655declare half @llvm.vector.reduce.fminimum.v128f16(<128 x half>)1656 1657declare float @llvm.vector.reduce.fminimum.v2f32(<2 x float>)1658declare float @llvm.vector.reduce.fminimum.v4f32(<4 x float>)1659declare float @llvm.vector.reduce.fminimum.v8f32(<8 x float>)1660declare float @llvm.vector.reduce.fminimum.v16f32(<16 x float>)1661declare float @llvm.vector.reduce.fminimum.v32f32(<32 x float>)1662declare float @llvm.vector.reduce.fminimum.v64f32(<64 x float>)1663 1664declare double @llvm.vector.reduce.fminimum.v1f64(<1 x double>)1665declare double @llvm.vector.reduce.fminimum.v2f64(<2 x double>)1666declare double @llvm.vector.reduce.fminimum.v4f64(<4 x double>)1667declare double @llvm.vector.reduce.fminimum.v8f64(<8 x double>)1668declare double @llvm.vector.reduce.fminimum.v16f64(<16 x double>)1669declare double @llvm.vector.reduce.fminimum.v32f64(<32 x double>)1670