248 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 22; RUN: sed 's/iXLen/i32/g' %s | llc -mtriple=riscv32 -mattr=+v -verify-machineinstrs | FileCheck %s3; RUN: sed 's/iXLen/i64/g' %s | llc -mtriple=riscv64 -mattr=+v -verify-machineinstrs | FileCheck %s4 5define <vscale x 4 x i32> @vadd(<vscale x 4 x i32> %passthru, <vscale x 4 x i32> %a, <vscale x 4 x i32> %b, iXLen %vl) {6; CHECK-LABEL: vadd:7; CHECK: # %bb.0:8; CHECK-NEXT: vsetvli zero, a0, e32, m2, tu, ma9; CHECK-NEXT: vadd.vv v8, v10, v1210; CHECK-NEXT: ret11 %v = call <vscale x 4 x i32> @llvm.riscv.vadd.nxv4i32.nxv4i32(<vscale x 4 x i32> poison, <vscale x 4 x i32> %a, <vscale x 4 x i32> %b, iXLen %vl)12 %w = call <vscale x 4 x i32> @llvm.riscv.vmv.v.v.nxv4i32(<vscale x 4 x i32> %passthru, <vscale x 4 x i32> %v, iXLen %vl)13 ret <vscale x 4 x i32> %w14}15 16define <vscale x 4 x i32> @vadd_mask(<vscale x 4 x i32> %passthru, <vscale x 4 x i32> %a, <vscale x 4 x i32> %b, <vscale x 4 x i1> %m, iXLen %vl) {17; CHECK-LABEL: vadd_mask:18; CHECK: # %bb.0:19; CHECK-NEXT: vsetvli zero, a0, e32, m2, tu, mu20; CHECK-NEXT: vadd.vv v8, v10, v12, v0.t21; CHECK-NEXT: ret22 %v = call <vscale x 4 x i32> @llvm.riscv.vadd.mask.nxv4i32.nxv4i32(<vscale x 4 x i32> poison, <vscale x 4 x i32> %a, <vscale x 4 x i32> %b, <vscale x 4 x i1> %m, iXLen %vl, iXLen 3)23 %w = call <vscale x 4 x i32> @llvm.riscv.vmv.v.v.nxv4i32(<vscale x 4 x i32> %passthru, <vscale x 4 x i32> %v, iXLen %vl)24 ret <vscale x 4 x i32> %w25}26 27define <vscale x 4 x i32> @vadd_undef(<vscale x 4 x i32> %a, <vscale x 4 x i32> %b, iXLen %vl) {28; CHECK-LABEL: vadd_undef:29; CHECK: # %bb.0:30; CHECK-NEXT: vsetvli zero, a0, e32, m2, ta, ma31; CHECK-NEXT: vadd.vv v8, v8, v1032; CHECK-NEXT: ret33 %v = call <vscale x 4 x i32> @llvm.riscv.vadd.nxv4i32.nxv4i32(<vscale x 4 x i32> poison, <vscale x 4 x i32> %a, <vscale x 4 x i32> %b, iXLen %vl)34 %w = call <vscale x 4 x i32> @llvm.riscv.vmv.v.v.nxv4i32(<vscale x 4 x i32> poison, <vscale x 4 x i32> %v, iXLen %vl)35 ret <vscale x 4 x i32> %w36}37 38define <vscale x 4 x i32> @vadd_same_passthru(<vscale x 4 x i32> %passthru, <vscale x 4 x i32> %a, <vscale x 4 x i32> %b, iXLen %vl) {39; CHECK-LABEL: vadd_same_passthru:40; CHECK: # %bb.0:41; CHECK-NEXT: vsetvli zero, a0, e32, m2, tu, ma42; CHECK-NEXT: vadd.vv v8, v10, v1243; CHECK-NEXT: ret44 %v = call <vscale x 4 x i32> @llvm.riscv.vadd.nxv4i32.nxv4i32(<vscale x 4 x i32> %passthru, <vscale x 4 x i32> %a, <vscale x 4 x i32> %b, iXLen %vl)45 %w = call <vscale x 4 x i32> @llvm.riscv.vmv.v.v.nxv4i32(<vscale x 4 x i32> %passthru, <vscale x 4 x i32> %v, iXLen %vl)46 ret <vscale x 4 x i32> %w47}48 49define <vscale x 4 x i32> @unfoldable_diff_avl_unknown(<vscale x 4 x i32> %passthru, <vscale x 4 x i32> %a, <vscale x 4 x i32> %b, iXLen %vl1, iXLen %vl2) {50; CHECK-LABEL: unfoldable_diff_avl_unknown:51; CHECK: # %bb.0:52; CHECK-NEXT: vsetvli zero, a0, e32, m2, tu, ma53; CHECK-NEXT: vmv2r.v v14, v854; CHECK-NEXT: vadd.vv v14, v10, v1255; CHECK-NEXT: vsetvli zero, a1, e32, m2, tu, ma56; CHECK-NEXT: vmv.v.v v8, v1457; CHECK-NEXT: ret58 %v = call <vscale x 4 x i32> @llvm.riscv.vadd.nxv4i32.nxv4i32(<vscale x 4 x i32> %passthru, <vscale x 4 x i32> %a, <vscale x 4 x i32> %b, iXLen %vl1)59 %w = call <vscale x 4 x i32> @llvm.riscv.vmv.v.v.nxv4i32(<vscale x 4 x i32> %passthru, <vscale x 4 x i32> %v, iXLen %vl2)60 ret <vscale x 4 x i32> %w61}62 63define <vscale x 4 x i32> @diff_avl_known(<vscale x 4 x i32> %passthru, <vscale x 4 x i32> %a, <vscale x 4 x i32> %b) {64; CHECK-LABEL: diff_avl_known:65; CHECK: # %bb.0:66; CHECK-NEXT: vsetivli zero, 4, e32, m2, tu, ma67; CHECK-NEXT: vadd.vv v8, v10, v1268; CHECK-NEXT: ret69 %v = call <vscale x 4 x i32> @llvm.riscv.vadd.nxv4i32.nxv4i32(<vscale x 4 x i32> %passthru, <vscale x 4 x i32> %a, <vscale x 4 x i32> %b, iXLen 4)70 %w = call <vscale x 4 x i32> @llvm.riscv.vmv.v.v.nxv4i32(<vscale x 4 x i32> %passthru, <vscale x 4 x i32> %v, iXLen 8)71 ret <vscale x 4 x i32> %w72}73 74define <vscale x 4 x i32> @diff_avl_vlmax(<vscale x 4 x i32> %passthru, <vscale x 4 x i32> %a, <vscale x 4 x i32> %b, iXLen %vl) {75; CHECK-LABEL: diff_avl_vlmax:76; CHECK: # %bb.0:77; CHECK-NEXT: vsetvli zero, a0, e32, m2, tu, ma78; CHECK-NEXT: vadd.vv v8, v10, v1279; CHECK-NEXT: ret80 %v = call <vscale x 4 x i32> @llvm.riscv.vadd.nxv4i32.nxv4i32(<vscale x 4 x i32> %passthru, <vscale x 4 x i32> %a, <vscale x 4 x i32> %b, iXLen -1)81 %w = call <vscale x 4 x i32> @llvm.riscv.vmv.v.v.nxv4i32(<vscale x 4 x i32> %passthru, <vscale x 4 x i32> %v, iXLen %vl)82 ret <vscale x 4 x i32> %w83}84 85define <vscale x 4 x i32> @diff_avl_non_uimm5(<vscale x 4 x i32> %passthru, <vscale x 4 x i32> %a, <vscale x 4 x i32> %b) {86; CHECK-LABEL: diff_avl_non_uimm5:87; CHECK: # %bb.0:88; CHECK-NEXT: li a0, 4289; CHECK-NEXT: vsetvli zero, a0, e32, m2, tu, ma90; CHECK-NEXT: vadd.vv v8, v10, v1291; CHECK-NEXT: ret92 %v = call <vscale x 4 x i32> @llvm.riscv.vadd.nxv4i32.nxv4i32(<vscale x 4 x i32> %passthru, <vscale x 4 x i32> %a, <vscale x 4 x i32> %b, iXLen 42)93 %w = call <vscale x 4 x i32> @llvm.riscv.vmv.v.v.nxv4i32(<vscale x 4 x i32> %passthru, <vscale x 4 x i32> %v, iXLen 123)94 ret <vscale x 4 x i32> %w95}96 97define <vscale x 4 x i32> @vadd_mask_ma(<vscale x 4 x i32> %passthru, <vscale x 4 x i32> %a, <vscale x 4 x i32> %b, <vscale x 4 x i1> %mask, iXLen %vl) {98; CHECK-LABEL: vadd_mask_ma:99; CHECK: # %bb.0:100; CHECK-NEXT: vsetvli zero, a0, e32, m2, tu, mu101; CHECK-NEXT: vadd.vv v8, v10, v12, v0.t102; CHECK-NEXT: ret103 %v = call <vscale x 4 x i32> @llvm.riscv.vadd.mask.nxv4i32.nxv4i32(<vscale x 4 x i32> poison, <vscale x 4 x i32> %a, <vscale x 4 x i32> %b, <vscale x 4 x i1> %mask, iXLen %vl, iXLen 2)104 %w = call <vscale x 4 x i32> @llvm.riscv.vmv.v.v.nxv4i32(<vscale x 4 x i32> %passthru, <vscale x 4 x i32> %v, iXLen %vl)105 ret <vscale x 4 x i32> %w106}107 108define <vscale x 4 x i32> @vadd_mask_mu(<vscale x 4 x i32> %passthru, <vscale x 4 x i32> %a, <vscale x 4 x i32> %b, <vscale x 4 x i1> %mask, iXLen %vl) {109; CHECK-LABEL: vadd_mask_mu:110; CHECK: # %bb.0:111; CHECK-NEXT: vsetvli zero, a0, e32, m2, tu, mu112; CHECK-NEXT: vadd.vv v8, v10, v12, v0.t113; CHECK-NEXT: ret114 %v = call <vscale x 4 x i32> @llvm.riscv.vadd.mask.nxv4i32.nxv4i32(<vscale x 4 x i32> poison, <vscale x 4 x i32> %a, <vscale x 4 x i32> %b, <vscale x 4 x i1> %mask, iXLen %vl, iXLen 0)115 %w = call <vscale x 4 x i32> @llvm.riscv.vmv.v.v.nxv4i32(<vscale x 4 x i32> %passthru, <vscale x 4 x i32> %v, iXLen %vl)116 ret <vscale x 4 x i32> %w117}118 119define <vscale x 4 x i32> @foldable_load(<vscale x 4 x i32> %passthru, ptr %p) {120; CHECK-LABEL: foldable_load:121; CHECK: # %bb.0:122; CHECK-NEXT: vsetivli zero, 2, e32, m2, tu, ma123; CHECK-NEXT: vle32.v v8, (a0)124; CHECK-NEXT: ret125 %v = call <vscale x 4 x i32> @llvm.riscv.vle.nxv4i32(<vscale x 4 x i32> poison, ptr %p, iXLen 4)126 %w = call <vscale x 4 x i32> @llvm.riscv.vmv.v.v.nxv4i32(<vscale x 4 x i32> %passthru, <vscale x 4 x i32> %v, iXLen 2)127 ret <vscale x 4 x i32> %w128}129 130; Can't fold this as the VLs aren't constant.131define <vscale x 4 x i32> @unfoldable_load(<vscale x 4 x i32> %passthru, ptr %p, iXLen %vl1, iXLen %vl2) {132; CHECK-LABEL: unfoldable_load:133; CHECK: # %bb.0:134; CHECK-NEXT: vsetvli zero, a1, e32, m2, ta, ma135; CHECK-NEXT: vle32.v v10, (a0)136; CHECK-NEXT: vsetvli zero, a2, e32, m2, tu, ma137; CHECK-NEXT: vmv.v.v v8, v10138; CHECK-NEXT: ret139 %v = call <vscale x 4 x i32> @llvm.riscv.vle.nxv4i32(<vscale x 4 x i32> poison, ptr %p, iXLen %vl1)140 %w = call <vscale x 4 x i32> @llvm.riscv.vmv.v.v.nxv4i32(<vscale x 4 x i32> %passthru, <vscale x 4 x i32> %v, iXLen %vl2)141 ret <vscale x 4 x i32> %w142}143 144define <vscale x 4 x float> @unfoldable_vfadd(<vscale x 4 x float> %passthru, <vscale x 4 x float> %a, <vscale x 4 x float> %b, iXLen %vl1, iXLen %vl2) {145; CHECK-LABEL: unfoldable_vfadd:146; CHECK: # %bb.0:147; CHECK-NEXT: vsetvli zero, a0, e32, m2, ta, ma148; CHECK-NEXT: vfadd.vv v10, v10, v12149; CHECK-NEXT: vsetvli zero, a1, e32, m2, tu, ma150; CHECK-NEXT: vmv.v.v v8, v10151; CHECK-NEXT: ret152 %v = call <vscale x 4 x float> @llvm.riscv.vfadd.nxv4f32.nxv4f32(<vscale x 4 x float> poison, <vscale x 4 x float> %a, <vscale x 4 x float> %b, iXLen 7, iXLen %vl1)153 %w = call <vscale x 4 x float> @llvm.riscv.vmv.v.v.nxv4f32(<vscale x 4 x float> %passthru, <vscale x 4 x float> %v, iXLen %vl2)154 ret <vscale x 4 x float> %w155}156 157define <vscale x 4 x float> @foldable_vfadd(<vscale x 4 x float> %passthru, <vscale x 4 x float> %a, <vscale x 4 x float> %b, iXLen %vl) {158; CHECK-LABEL: foldable_vfadd:159; CHECK: # %bb.0:160; CHECK-NEXT: vsetvli zero, a0, e32, m2, tu, ma161; CHECK-NEXT: vfadd.vv v8, v10, v12162; CHECK-NEXT: ret163 %v = call <vscale x 4 x float> @llvm.riscv.vfadd.nxv4f32.nxv4f32(<vscale x 4 x float> poison, <vscale x 4 x float> %a, <vscale x 4 x float> %b, iXLen 7, iXLen %vl)164 %w = call <vscale x 4 x float> @llvm.riscv.vmv.v.v.nxv4f32(<vscale x 4 x float> %passthru, <vscale x 4 x float> %v, iXLen %vl)165 ret <vscale x 4 x float> %w166}167 168; This shouldn't be folded because we need to preserve exceptions with169; "fpexcept.strict" exception behaviour, and changing the VL may hide them.170define <vscale x 4 x float> @unfoldable_constrained_fadd(<vscale x 4 x float> %passthru, <vscale x 4 x float> %x, <vscale x 4 x float> %y, iXLen %vl) strictfp {171; CHECK-LABEL: unfoldable_constrained_fadd:172; CHECK: # %bb.0:173; CHECK-NEXT: vsetvli a1, zero, e32, m2, ta, ma174; CHECK-NEXT: vfadd.vv v10, v10, v12175; CHECK-NEXT: vsetvli zero, a0, e32, m2, tu, ma176; CHECK-NEXT: vmv.v.v v8, v10177; CHECK-NEXT: ret178 %a = call <vscale x 4 x float> @llvm.experimental.constrained.fadd(<vscale x 4 x float> %x, <vscale x 4 x float> %y, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp179 %b = call <vscale x 4 x float> @llvm.riscv.vmv.v.v.nxv4f32(<vscale x 4 x float> %passthru, <vscale x 4 x float> %a, iXLen %vl) strictfp180 ret <vscale x 4 x float> %b181}182 183define <vscale x 2 x i32> @unfoldable_vredsum(<vscale x 2 x i32> %passthru, <vscale x 4 x i32> %x, <vscale x 2 x i32> %y) {184; CHECK-LABEL: unfoldable_vredsum:185; CHECK: # %bb.0:186; CHECK-NEXT: vsetvli a0, zero, e32, m2, ta, ma187; CHECK-NEXT: vredsum.vs v9, v10, v9188; CHECK-NEXT: vsetivli zero, 1, e32, m1, tu, ma189; CHECK-NEXT: vmv.v.v v8, v9190; CHECK-NEXT: ret191 %a = call <vscale x 2 x i32> @llvm.riscv.vredsum.nxv2i32.nxv4i32(<vscale x 2 x i32> poison, <vscale x 4 x i32> %x, <vscale x 2 x i32> %y, iXLen -1)192 %b = call <vscale x 2 x i32> @llvm.riscv.vmv.v.v.nxv2i32(<vscale x 2 x i32> %passthru, <vscale x 2 x i32> %a, iXLen 1)193 ret <vscale x 2 x i32> %b194}195 196define <vscale x 2 x i32> @unfoldable_mismatched_sew(<vscale x 2 x i32> %passthru, <vscale x 1 x i64> %x, <vscale x 1 x i64> %y, iXLen %avl) {197; CHECK-LABEL: unfoldable_mismatched_sew:198; CHECK: # %bb.0:199; CHECK-NEXT: vsetvli zero, a0, e64, m1, ta, ma200; CHECK-NEXT: vadd.vv v9, v9, v10201; CHECK-NEXT: vsetvli zero, a0, e32, m1, tu, ma202; CHECK-NEXT: vmv.v.v v8, v9203; CHECK-NEXT: ret204 %a = call <vscale x 1 x i64> @llvm.riscv.vadd.nxv1i64.nxv1i64(<vscale x 1 x i64> poison, <vscale x 1 x i64> %x, <vscale x 1 x i64> %y, iXLen %avl)205 %a.bitcast = bitcast <vscale x 1 x i64> %a to <vscale x 2 x i32>206 %b = call <vscale x 2 x i32> @llvm.riscv.vmv.v.v.nxv2i32(<vscale x 2 x i32> %passthru, <vscale x 2 x i32> %a.bitcast, iXLen %avl)207 ret <vscale x 2 x i32> %b208}209 210 211define <vscale x 1 x i64> @undef_passthru(<vscale x 1 x i64> %passthru, <vscale x 1 x i64> %x, <vscale x 1 x i64> %y, iXLen %avl) {212; CHECK-LABEL: undef_passthru:213; CHECK: # %bb.0:214; CHECK-NEXT: vsetvli zero, a0, e64, m1, ta, ma215; CHECK-NEXT: vadd.vv v8, v9, v10216; CHECK-NEXT: ret217 %a = call <vscale x 1 x i64> @llvm.riscv.vadd.nxv1i64.nxv1i64(<vscale x 1 x i64> %passthru, <vscale x 1 x i64> %x, <vscale x 1 x i64> %y, iXLen %avl)218 %b = call <vscale x 1 x i64> @llvm.riscv.vmv.v.v.nxv1i64(<vscale x 1 x i64> poison, <vscale x 1 x i64> %a, iXLen %avl)219 ret <vscale x 1 x i64> %b220}221 222; Check that we can fold into vle64ff.v even if we need to move it past the223; passthru and it's safe.224define <vscale x 1 x i64> @vleff_move_past_passthru(ptr %p, ptr %q, iXLen %avl) {225; CHECK-LABEL: vleff_move_past_passthru:226; CHECK: # %bb.0:227; CHECK-NEXT: vl1re64.v v8, (a1)228; CHECK-NEXT: vsetvli zero, a2, e64, m1, tu, ma229; CHECK-NEXT: vle64ff.v v8, (a0)230; CHECK-NEXT: ret231 %a = call { <vscale x 1 x i64>, iXLen } @llvm.riscv.vleff(<vscale x 1 x i64> poison, ptr %p, iXLen %avl)232 %vec = extractvalue { <vscale x 1 x i64>, iXLen } %a, 0233 %passthru = load <vscale x 1 x i64>, ptr %q234 %b = call <vscale x 1 x i64> @llvm.riscv.vmv.v.v.nxv1i64(<vscale x 1 x i64> %passthru, <vscale x 1 x i64> %vec, iXLen %avl)235 ret <vscale x 1 x i64> %b236}237 238define <vscale x 1 x i64> @vmerge(<vscale x 1 x i64> %passthru, <vscale x 1 x i64> %x, <vscale x 1 x i64> %y, <vscale x 1 x i1> %m, iXLen %avl) {239; CHECK-LABEL: vmerge:240; CHECK: # %bb.0:241; CHECK-NEXT: vsetvli zero, a0, e64, m1, tu, ma242; CHECK-NEXT: vmerge.vvm v8, v9, v10, v0243; CHECK-NEXT: ret244 %a = call <vscale x 1 x i64> @llvm.riscv.vmerge.nxv1i64.nxv1i64(<vscale x 1 x i64> %passthru, <vscale x 1 x i64> %x, <vscale x 1 x i64> %y, <vscale x 1 x i1> %m, iXLen %avl)245 %b = call <vscale x 1 x i64> @llvm.riscv.vmv.v.v.nxv1i64(<vscale x 1 x i64> %passthru, <vscale x 1 x i64> %a, iXLen %avl)246 ret <vscale x 1 x i64> %b247}248