325 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 32; RUN: llc < %s -mtriple=riscv32 -mattr=+v,+zvfh -verify-machineinstrs | FileCheck %s -check-prefixes=CHECK,RV323; RUN: llc < %s -mtriple=riscv64 -mattr=+v,+zvfh -verify-machineinstrs | FileCheck %s -check-prefixes=CHECK,RV644 5define i8 @extract_last_i8(<16 x i8> %data, <16 x i8> %mask, i8 %passthru) {6; CHECK-LABEL: extract_last_i8:7; CHECK: # %bb.0:8; CHECK-NEXT: vsetivli zero, 16, e8, m1, ta, ma9; CHECK-NEXT: vmsne.vi v0, v9, 010; CHECK-NEXT: vcpop.m a1, v011; CHECK-NEXT: beqz a1, .LBB0_212; CHECK-NEXT: # %bb.1:13; CHECK-NEXT: vmv.v.i v9, 014; CHECK-NEXT: vsetvli zero, zero, e8, m1, ta, mu15; CHECK-NEXT: vid.v v9, v0.t16; CHECK-NEXT: vredmaxu.vs v9, v9, v917; CHECK-NEXT: vmv.x.s a0, v918; CHECK-NEXT: zext.b a0, a019; CHECK-NEXT: vslidedown.vx v8, v8, a020; CHECK-NEXT: vmv.x.s a0, v821; CHECK-NEXT: .LBB0_2:22; CHECK-NEXT: ret23 %notzero = icmp ne <16 x i8> %mask, zeroinitializer24 %res = call i8 @llvm.experimental.vector.extract.last.active.v16i8(<16 x i8> %data, <16 x i1> %notzero, i8 %passthru)25 ret i8 %res26}27 28define i16 @extract_last_i16(<8 x i16> %data, <8 x i16> %mask, i16 %passthru) {29; CHECK-LABEL: extract_last_i16:30; CHECK: # %bb.0:31; CHECK-NEXT: vsetivli zero, 8, e16, m1, ta, ma32; CHECK-NEXT: vmsne.vi v0, v9, 033; CHECK-NEXT: vcpop.m a1, v034; CHECK-NEXT: beqz a1, .LBB1_235; CHECK-NEXT: # %bb.1:36; CHECK-NEXT: vsetvli zero, zero, e8, mf2, ta, mu37; CHECK-NEXT: vmv.v.i v9, 038; CHECK-NEXT: vid.v v9, v0.t39; CHECK-NEXT: vredmaxu.vs v9, v9, v940; CHECK-NEXT: vmv.x.s a0, v941; CHECK-NEXT: zext.b a0, a042; CHECK-NEXT: vsetvli zero, zero, e16, m1, ta, ma43; CHECK-NEXT: vslidedown.vx v8, v8, a044; CHECK-NEXT: vmv.x.s a0, v845; CHECK-NEXT: .LBB1_2:46; CHECK-NEXT: ret47 %notzero = icmp ne <8 x i16> %mask, zeroinitializer48 %res = call i16 @llvm.experimental.vector.extract.last.active.v8i16(<8 x i16> %data, <8 x i1> %notzero, i16 %passthru)49 ret i16 %res50}51 52define i32 @extract_last_i32(<4 x i32> %data, <4 x i32> %mask, i32 %passthru) {53; CHECK-LABEL: extract_last_i32:54; CHECK: # %bb.0:55; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, ma56; CHECK-NEXT: vmsne.vi v0, v9, 057; CHECK-NEXT: vcpop.m a1, v058; CHECK-NEXT: beqz a1, .LBB2_259; CHECK-NEXT: # %bb.1:60; CHECK-NEXT: vsetvli zero, zero, e8, mf4, ta, mu61; CHECK-NEXT: vmv.v.i v9, 062; CHECK-NEXT: vid.v v9, v0.t63; CHECK-NEXT: vredmaxu.vs v9, v9, v964; CHECK-NEXT: vmv.x.s a0, v965; CHECK-NEXT: zext.b a0, a066; CHECK-NEXT: vsetvli zero, zero, e32, m1, ta, ma67; CHECK-NEXT: vslidedown.vx v8, v8, a068; CHECK-NEXT: vmv.x.s a0, v869; CHECK-NEXT: .LBB2_2:70; CHECK-NEXT: ret71 %notzero = icmp ne <4 x i32> %mask, zeroinitializer72 %res = call i32 @llvm.experimental.vector.extract.last.active.v4i32(<4 x i32> %data, <4 x i1> %notzero, i32 %passthru)73 ret i32 %res74}75 76define i64 @extract_last_i64(<2 x i64> %data, <2 x i64> %mask, i64 %passthru) {77; RV32-LABEL: extract_last_i64:78; RV32: # %bb.0:79; RV32-NEXT: vsetivli zero, 2, e64, m1, ta, ma80; RV32-NEXT: vmsne.vi v0, v9, 081; RV32-NEXT: vcpop.m a2, v082; RV32-NEXT: beqz a2, .LBB3_283; RV32-NEXT: # %bb.1:84; RV32-NEXT: vsetvli zero, zero, e8, mf8, ta, mu85; RV32-NEXT: vmv.v.i v9, 086; RV32-NEXT: li a1, 3287; RV32-NEXT: vid.v v9, v0.t88; RV32-NEXT: vredmaxu.vs v9, v9, v989; RV32-NEXT: vmv.x.s a0, v990; RV32-NEXT: zext.b a0, a091; RV32-NEXT: vsetvli zero, zero, e64, m1, ta, ma92; RV32-NEXT: vslidedown.vx v8, v8, a093; RV32-NEXT: vmv.x.s a0, v894; RV32-NEXT: vsetivli zero, 1, e64, m1, ta, ma95; RV32-NEXT: vsrl.vx v8, v8, a196; RV32-NEXT: vmv.x.s a1, v897; RV32-NEXT: .LBB3_2:98; RV32-NEXT: ret99;100; RV64-LABEL: extract_last_i64:101; RV64: # %bb.0:102; RV64-NEXT: vsetivli zero, 2, e64, m1, ta, ma103; RV64-NEXT: vmsne.vi v0, v9, 0104; RV64-NEXT: vcpop.m a1, v0105; RV64-NEXT: beqz a1, .LBB3_2106; RV64-NEXT: # %bb.1:107; RV64-NEXT: vsetvli zero, zero, e8, mf8, ta, mu108; RV64-NEXT: vmv.v.i v9, 0109; RV64-NEXT: vid.v v9, v0.t110; RV64-NEXT: vredmaxu.vs v9, v9, v9111; RV64-NEXT: vmv.x.s a0, v9112; RV64-NEXT: zext.b a0, a0113; RV64-NEXT: vsetvli zero, zero, e64, m1, ta, ma114; RV64-NEXT: vslidedown.vx v8, v8, a0115; RV64-NEXT: vmv.x.s a0, v8116; RV64-NEXT: .LBB3_2:117; RV64-NEXT: ret118 %notzero = icmp ne <2 x i64> %mask, zeroinitializer119 %res = call i64 @llvm.experimental.vector.extract.last.active.v2i64(<2 x i64> %data, <2 x i1> %notzero, i64 %passthru)120 ret i64 %res121}122 123define float @extract_last_float(<4 x float> %data, <4 x i32> %mask, float %passthru) {124; CHECK-LABEL: extract_last_float:125; CHECK: # %bb.0:126; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, ma127; CHECK-NEXT: vmsne.vi v0, v9, 0128; CHECK-NEXT: vcpop.m a0, v0129; CHECK-NEXT: beqz a0, .LBB4_2130; CHECK-NEXT: # %bb.1:131; CHECK-NEXT: vsetvli zero, zero, e8, mf4, ta, mu132; CHECK-NEXT: vmv.v.i v9, 0133; CHECK-NEXT: vid.v v9, v0.t134; CHECK-NEXT: vredmaxu.vs v9, v9, v9135; CHECK-NEXT: vmv.x.s a0, v9136; CHECK-NEXT: zext.b a0, a0137; CHECK-NEXT: vsetvli zero, zero, e32, m1, ta, ma138; CHECK-NEXT: vslidedown.vx v8, v8, a0139; CHECK-NEXT: vfmv.f.s fa0, v8140; CHECK-NEXT: .LBB4_2:141; CHECK-NEXT: ret142 %notzero = icmp ne <4 x i32> %mask, zeroinitializer143 %res = call float @llvm.experimental.vector.extract.last.active.v4f32(<4 x float> %data, <4 x i1> %notzero, float %passthru)144 ret float %res145}146 147define double @extract_last_double(<2 x double> %data, <2 x i64> %mask, double %passthru) {148; CHECK-LABEL: extract_last_double:149; CHECK: # %bb.0:150; CHECK-NEXT: vsetivli zero, 2, e64, m1, ta, ma151; CHECK-NEXT: vmsne.vi v0, v9, 0152; CHECK-NEXT: vcpop.m a0, v0153; CHECK-NEXT: beqz a0, .LBB5_2154; CHECK-NEXT: # %bb.1:155; CHECK-NEXT: vsetvli zero, zero, e8, mf8, ta, mu156; CHECK-NEXT: vmv.v.i v9, 0157; CHECK-NEXT: vid.v v9, v0.t158; CHECK-NEXT: vredmaxu.vs v9, v9, v9159; CHECK-NEXT: vmv.x.s a0, v9160; CHECK-NEXT: zext.b a0, a0161; CHECK-NEXT: vsetvli zero, zero, e64, m1, ta, ma162; CHECK-NEXT: vslidedown.vx v8, v8, a0163; CHECK-NEXT: vfmv.f.s fa0, v8164; CHECK-NEXT: .LBB5_2:165; CHECK-NEXT: ret166 %notzero = icmp ne <2 x i64> %mask, zeroinitializer167 %res = call double @llvm.experimental.vector.extract.last.active.v2f64(<2 x double> %data, <2 x i1> %notzero, double %passthru)168 ret double %res169}170 171define i8 @extract_last_i8_scalable(<vscale x 16 x i8> %data, <vscale x 16 x i1> %mask, i8 %passthru) {172; CHECK-LABEL: extract_last_i8_scalable:173; CHECK: # %bb.0:174; CHECK-NEXT: vsetvli a1, zero, e8, m2, ta, ma175; CHECK-NEXT: vcpop.m a1, v0176; CHECK-NEXT: beqz a1, .LBB6_2177; CHECK-NEXT: # %bb.1:178; CHECK-NEXT: vmv.v.i v10, 0179; CHECK-NEXT: vsetvli zero, zero, e8, m2, ta, mu180; CHECK-NEXT: vid.v v10, v0.t181; CHECK-NEXT: vredmaxu.vs v10, v10, v10182; CHECK-NEXT: vmv.x.s a0, v10183; CHECK-NEXT: zext.b a0, a0184; CHECK-NEXT: vsetvli zero, zero, e8, m2, ta, ma185; CHECK-NEXT: vslidedown.vx v8, v8, a0186; CHECK-NEXT: vmv.x.s a0, v8187; CHECK-NEXT: .LBB6_2:188; CHECK-NEXT: ret189 %res = call i8 @llvm.experimental.vector.extract.last.active.nxv16i8(<vscale x 16 x i8> %data, <vscale x 16 x i1> %mask, i8 %passthru)190 ret i8 %res191}192 193define i16 @extract_last_i16_scalable(<vscale x 8 x i16> %data, <vscale x 8 x i1> %mask, i16 %passthru) {194; CHECK-LABEL: extract_last_i16_scalable:195; CHECK: # %bb.0:196; CHECK-NEXT: vsetvli a1, zero, e8, m1, ta, ma197; CHECK-NEXT: vcpop.m a1, v0198; CHECK-NEXT: beqz a1, .LBB7_2199; CHECK-NEXT: # %bb.1:200; CHECK-NEXT: vmv.v.i v10, 0201; CHECK-NEXT: vsetvli zero, zero, e8, m1, ta, mu202; CHECK-NEXT: vid.v v10, v0.t203; CHECK-NEXT: vredmaxu.vs v10, v10, v10204; CHECK-NEXT: vmv.x.s a0, v10205; CHECK-NEXT: zext.b a0, a0206; CHECK-NEXT: vsetvli zero, zero, e16, m2, ta, ma207; CHECK-NEXT: vslidedown.vx v8, v8, a0208; CHECK-NEXT: vmv.x.s a0, v8209; CHECK-NEXT: .LBB7_2:210; CHECK-NEXT: ret211 %res = call i16 @llvm.experimental.vector.extract.last.active.nxv8i16(<vscale x 8 x i16> %data, <vscale x 8 x i1> %mask, i16 %passthru)212 ret i16 %res213}214 215define i32 @extract_last_i32_scalable(<vscale x 4 x i32> %data, <vscale x 4 x i1> %mask, i32 %passthru) {216; CHECK-LABEL: extract_last_i32_scalable:217; CHECK: # %bb.0:218; CHECK-NEXT: vsetvli a1, zero, e8, mf2, ta, ma219; CHECK-NEXT: vcpop.m a1, v0220; CHECK-NEXT: beqz a1, .LBB8_2221; CHECK-NEXT: # %bb.1:222; CHECK-NEXT: vmv.v.i v10, 0223; CHECK-NEXT: vsetvli zero, zero, e8, mf2, ta, mu224; CHECK-NEXT: vid.v v10, v0.t225; CHECK-NEXT: vredmaxu.vs v10, v10, v10226; CHECK-NEXT: vmv.x.s a0, v10227; CHECK-NEXT: zext.b a0, a0228; CHECK-NEXT: vsetvli zero, zero, e32, m2, ta, ma229; CHECK-NEXT: vslidedown.vx v8, v8, a0230; CHECK-NEXT: vmv.x.s a0, v8231; CHECK-NEXT: .LBB8_2:232; CHECK-NEXT: ret233 %res = call i32 @llvm.experimental.vector.extract.last.active.nxv4i32(<vscale x 4 x i32> %data, <vscale x 4 x i1> %mask, i32 %passthru)234 ret i32 %res235}236 237define i64 @extract_last_i64_scalable(<vscale x 2 x i64> %data, <vscale x 2 x i1> %mask, i64 %passthru) {238; RV32-LABEL: extract_last_i64_scalable:239; RV32: # %bb.0:240; RV32-NEXT: vsetvli a2, zero, e8, mf4, ta, ma241; RV32-NEXT: vcpop.m a2, v0242; RV32-NEXT: beqz a2, .LBB9_2243; RV32-NEXT: # %bb.1:244; RV32-NEXT: vmv.v.i v10, 0245; RV32-NEXT: li a1, 32246; RV32-NEXT: vsetvli zero, zero, e8, mf4, ta, mu247; RV32-NEXT: vid.v v10, v0.t248; RV32-NEXT: vredmaxu.vs v10, v10, v10249; RV32-NEXT: vmv.x.s a0, v10250; RV32-NEXT: zext.b a0, a0251; RV32-NEXT: vsetvli zero, zero, e64, m2, ta, ma252; RV32-NEXT: vslidedown.vx v8, v8, a0253; RV32-NEXT: vmv.x.s a0, v8254; RV32-NEXT: vsetivli zero, 1, e64, m2, ta, ma255; RV32-NEXT: vsrl.vx v8, v8, a1256; RV32-NEXT: vmv.x.s a1, v8257; RV32-NEXT: .LBB9_2:258; RV32-NEXT: ret259;260; RV64-LABEL: extract_last_i64_scalable:261; RV64: # %bb.0:262; RV64-NEXT: vsetvli a1, zero, e8, mf4, ta, ma263; RV64-NEXT: vcpop.m a1, v0264; RV64-NEXT: beqz a1, .LBB9_2265; RV64-NEXT: # %bb.1:266; RV64-NEXT: vmv.v.i v10, 0267; RV64-NEXT: vsetvli zero, zero, e8, mf4, ta, mu268; RV64-NEXT: vid.v v10, v0.t269; RV64-NEXT: vredmaxu.vs v10, v10, v10270; RV64-NEXT: vmv.x.s a0, v10271; RV64-NEXT: zext.b a0, a0272; RV64-NEXT: vsetvli zero, zero, e64, m2, ta, ma273; RV64-NEXT: vslidedown.vx v8, v8, a0274; RV64-NEXT: vmv.x.s a0, v8275; RV64-NEXT: .LBB9_2:276; RV64-NEXT: ret277 %res = call i64 @llvm.experimental.vector.extract.last.active.nxv2i64(<vscale x 2 x i64> %data, <vscale x 2 x i1> %mask, i64 %passthru)278 ret i64 %res279}280 281define float @extract_last_float_scalable(<vscale x 4 x float> %data, <vscale x 4 x i1> %mask, float %passthru) {282; CHECK-LABEL: extract_last_float_scalable:283; CHECK: # %bb.0:284; CHECK-NEXT: vsetvli a0, zero, e8, mf2, ta, ma285; CHECK-NEXT: vcpop.m a0, v0286; CHECK-NEXT: beqz a0, .LBB10_2287; CHECK-NEXT: # %bb.1:288; CHECK-NEXT: vmv.v.i v10, 0289; CHECK-NEXT: vsetvli zero, zero, e8, mf2, ta, mu290; CHECK-NEXT: vid.v v10, v0.t291; CHECK-NEXT: vredmaxu.vs v10, v10, v10292; CHECK-NEXT: vmv.x.s a0, v10293; CHECK-NEXT: zext.b a0, a0294; CHECK-NEXT: vsetvli zero, zero, e32, m2, ta, ma295; CHECK-NEXT: vslidedown.vx v8, v8, a0296; CHECK-NEXT: vfmv.f.s fa0, v8297; CHECK-NEXT: .LBB10_2:298; CHECK-NEXT: ret299 %res = call float @llvm.experimental.vector.extract.last.active.nxv4f32(<vscale x 4 x float> %data, <vscale x 4 x i1> %mask, float %passthru)300 ret float %res301}302 303define double @extract_last_double_scalable(<vscale x 2 x double> %data, <vscale x 2 x i1> %mask, double %passthru) {304; CHECK-LABEL: extract_last_double_scalable:305; CHECK: # %bb.0:306; CHECK-NEXT: vsetvli a0, zero, e8, mf4, ta, ma307; CHECK-NEXT: vcpop.m a0, v0308; CHECK-NEXT: beqz a0, .LBB11_2309; CHECK-NEXT: # %bb.1:310; CHECK-NEXT: vmv.v.i v10, 0311; CHECK-NEXT: vsetvli zero, zero, e8, mf4, ta, mu312; CHECK-NEXT: vid.v v10, v0.t313; CHECK-NEXT: vredmaxu.vs v10, v10, v10314; CHECK-NEXT: vmv.x.s a0, v10315; CHECK-NEXT: zext.b a0, a0316; CHECK-NEXT: vsetvli zero, zero, e64, m2, ta, ma317; CHECK-NEXT: vslidedown.vx v8, v8, a0318; CHECK-NEXT: vfmv.f.s fa0, v8319; CHECK-NEXT: .LBB11_2:320; CHECK-NEXT: ret321 %res = call double @llvm.experimental.vector.extract.last.active.nxv2f64(<vscale x 2 x double> %data, <vscale x 2 x i1> %mask, double %passthru)322 ret double %res323}324 325