; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2 ; RUN: sed 's/iXLen/i32/g' %s | llc -mtriple=riscv32 -mattr=+v -verify-machineinstrs | FileCheck %s ; RUN: sed 's/iXLen/i64/g' %s | llc -mtriple=riscv64 -mattr=+v -verify-machineinstrs | FileCheck %s define @vadd( %passthru, %a, %b, iXLen %vl) { ; CHECK-LABEL: vadd: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetvli zero, a0, e32, m2, tu, ma ; CHECK-NEXT: vadd.vv v8, v10, v12 ; CHECK-NEXT: ret %v = call @llvm.riscv.vadd.nxv4i32.nxv4i32( poison, %a, %b, iXLen %vl) %w = call @llvm.riscv.vmv.v.v.nxv4i32( %passthru, %v, iXLen %vl) ret %w } define @vadd_mask( %passthru, %a, %b, %m, iXLen %vl) { ; CHECK-LABEL: vadd_mask: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetvli zero, a0, e32, m2, tu, mu ; CHECK-NEXT: vadd.vv v8, v10, v12, v0.t ; CHECK-NEXT: ret %v = call @llvm.riscv.vadd.mask.nxv4i32.nxv4i32( poison, %a, %b, %m, iXLen %vl, iXLen 3) %w = call @llvm.riscv.vmv.v.v.nxv4i32( %passthru, %v, iXLen %vl) ret %w } define @vadd_undef( %a, %b, iXLen %vl) { ; CHECK-LABEL: vadd_undef: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetvli zero, a0, e32, m2, ta, ma ; CHECK-NEXT: vadd.vv v8, v8, v10 ; CHECK-NEXT: ret %v = call @llvm.riscv.vadd.nxv4i32.nxv4i32( poison, %a, %b, iXLen %vl) %w = call @llvm.riscv.vmv.v.v.nxv4i32( poison, %v, iXLen %vl) ret %w } define @vadd_same_passthru( %passthru, %a, %b, iXLen %vl) { ; CHECK-LABEL: vadd_same_passthru: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetvli zero, a0, e32, m2, tu, ma ; CHECK-NEXT: vadd.vv v8, v10, v12 ; CHECK-NEXT: ret %v = call @llvm.riscv.vadd.nxv4i32.nxv4i32( %passthru, %a, %b, iXLen %vl) %w = call @llvm.riscv.vmv.v.v.nxv4i32( %passthru, %v, iXLen %vl) ret %w } define @unfoldable_diff_avl_unknown( %passthru, %a, %b, iXLen %vl1, iXLen %vl2) { ; CHECK-LABEL: unfoldable_diff_avl_unknown: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetvli zero, a0, e32, m2, tu, ma ; CHECK-NEXT: vmv2r.v v14, v8 ; CHECK-NEXT: vadd.vv v14, v10, v12 ; CHECK-NEXT: vsetvli zero, a1, e32, m2, tu, ma ; CHECK-NEXT: vmv.v.v v8, v14 ; CHECK-NEXT: ret %v = call @llvm.riscv.vadd.nxv4i32.nxv4i32( %passthru, %a, %b, iXLen %vl1) %w = call @llvm.riscv.vmv.v.v.nxv4i32( %passthru, %v, iXLen %vl2) ret %w } define @diff_avl_known( %passthru, %a, %b) { ; CHECK-LABEL: diff_avl_known: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetivli zero, 4, e32, m2, tu, ma ; CHECK-NEXT: vadd.vv v8, v10, v12 ; CHECK-NEXT: ret %v = call @llvm.riscv.vadd.nxv4i32.nxv4i32( %passthru, %a, %b, iXLen 4) %w = call @llvm.riscv.vmv.v.v.nxv4i32( %passthru, %v, iXLen 8) ret %w } define @diff_avl_vlmax( %passthru, %a, %b, iXLen %vl) { ; CHECK-LABEL: diff_avl_vlmax: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetvli zero, a0, e32, m2, tu, ma ; CHECK-NEXT: vadd.vv v8, v10, v12 ; CHECK-NEXT: ret %v = call @llvm.riscv.vadd.nxv4i32.nxv4i32( %passthru, %a, %b, iXLen -1) %w = call @llvm.riscv.vmv.v.v.nxv4i32( %passthru, %v, iXLen %vl) ret %w } define @diff_avl_non_uimm5( %passthru, %a, %b) { ; CHECK-LABEL: diff_avl_non_uimm5: ; CHECK: # %bb.0: ; CHECK-NEXT: li a0, 42 ; CHECK-NEXT: vsetvli zero, a0, e32, m2, tu, ma ; CHECK-NEXT: vadd.vv v8, v10, v12 ; CHECK-NEXT: ret %v = call @llvm.riscv.vadd.nxv4i32.nxv4i32( %passthru, %a, %b, iXLen 42) %w = call @llvm.riscv.vmv.v.v.nxv4i32( %passthru, %v, iXLen 123) ret %w } define @vadd_mask_ma( %passthru, %a, %b, %mask, iXLen %vl) { ; CHECK-LABEL: vadd_mask_ma: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetvli zero, a0, e32, m2, tu, mu ; CHECK-NEXT: vadd.vv v8, v10, v12, v0.t ; CHECK-NEXT: ret %v = call @llvm.riscv.vadd.mask.nxv4i32.nxv4i32( poison, %a, %b, %mask, iXLen %vl, iXLen 2) %w = call @llvm.riscv.vmv.v.v.nxv4i32( %passthru, %v, iXLen %vl) ret %w } define @vadd_mask_mu( %passthru, %a, %b, %mask, iXLen %vl) { ; CHECK-LABEL: vadd_mask_mu: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetvli zero, a0, e32, m2, tu, mu ; CHECK-NEXT: vadd.vv v8, v10, v12, v0.t ; CHECK-NEXT: ret %v = call @llvm.riscv.vadd.mask.nxv4i32.nxv4i32( poison, %a, %b, %mask, iXLen %vl, iXLen 0) %w = call @llvm.riscv.vmv.v.v.nxv4i32( %passthru, %v, iXLen %vl) ret %w } define @foldable_load( %passthru, ptr %p) { ; CHECK-LABEL: foldable_load: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetivli zero, 2, e32, m2, tu, ma ; CHECK-NEXT: vle32.v v8, (a0) ; CHECK-NEXT: ret %v = call @llvm.riscv.vle.nxv4i32( poison, ptr %p, iXLen 4) %w = call @llvm.riscv.vmv.v.v.nxv4i32( %passthru, %v, iXLen 2) ret %w } ; Can't fold this as the VLs aren't constant. define @unfoldable_load( %passthru, ptr %p, iXLen %vl1, iXLen %vl2) { ; CHECK-LABEL: unfoldable_load: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetvli zero, a1, e32, m2, ta, ma ; CHECK-NEXT: vle32.v v10, (a0) ; CHECK-NEXT: vsetvli zero, a2, e32, m2, tu, ma ; CHECK-NEXT: vmv.v.v v8, v10 ; CHECK-NEXT: ret %v = call @llvm.riscv.vle.nxv4i32( poison, ptr %p, iXLen %vl1) %w = call @llvm.riscv.vmv.v.v.nxv4i32( %passthru, %v, iXLen %vl2) ret %w } define @unfoldable_vfadd( %passthru, %a, %b, iXLen %vl1, iXLen %vl2) { ; CHECK-LABEL: unfoldable_vfadd: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetvli zero, a0, e32, m2, ta, ma ; CHECK-NEXT: vfadd.vv v10, v10, v12 ; CHECK-NEXT: vsetvli zero, a1, e32, m2, tu, ma ; CHECK-NEXT: vmv.v.v v8, v10 ; CHECK-NEXT: ret %v = call @llvm.riscv.vfadd.nxv4f32.nxv4f32( poison, %a, %b, iXLen 7, iXLen %vl1) %w = call @llvm.riscv.vmv.v.v.nxv4f32( %passthru, %v, iXLen %vl2) ret %w } define @foldable_vfadd( %passthru, %a, %b, iXLen %vl) { ; CHECK-LABEL: foldable_vfadd: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetvli zero, a0, e32, m2, tu, ma ; CHECK-NEXT: vfadd.vv v8, v10, v12 ; CHECK-NEXT: ret %v = call @llvm.riscv.vfadd.nxv4f32.nxv4f32( poison, %a, %b, iXLen 7, iXLen %vl) %w = call @llvm.riscv.vmv.v.v.nxv4f32( %passthru, %v, iXLen %vl) ret %w } ; This shouldn't be folded because we need to preserve exceptions with ; "fpexcept.strict" exception behaviour, and changing the VL may hide them. define @unfoldable_constrained_fadd( %passthru, %x, %y, iXLen %vl) strictfp { ; CHECK-LABEL: unfoldable_constrained_fadd: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetvli a1, zero, e32, m2, ta, ma ; CHECK-NEXT: vfadd.vv v10, v10, v12 ; CHECK-NEXT: vsetvli zero, a0, e32, m2, tu, ma ; CHECK-NEXT: vmv.v.v v8, v10 ; CHECK-NEXT: ret %a = call @llvm.experimental.constrained.fadd( %x, %y, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp %b = call @llvm.riscv.vmv.v.v.nxv4f32( %passthru, %a, iXLen %vl) strictfp ret %b } define @unfoldable_vredsum( %passthru, %x, %y) { ; CHECK-LABEL: unfoldable_vredsum: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetvli a0, zero, e32, m2, ta, ma ; CHECK-NEXT: vredsum.vs v9, v10, v9 ; CHECK-NEXT: vsetivli zero, 1, e32, m1, tu, ma ; CHECK-NEXT: vmv.v.v v8, v9 ; CHECK-NEXT: ret %a = call @llvm.riscv.vredsum.nxv2i32.nxv4i32( poison, %x, %y, iXLen -1) %b = call @llvm.riscv.vmv.v.v.nxv2i32( %passthru, %a, iXLen 1) ret %b } define @unfoldable_mismatched_sew( %passthru, %x, %y, iXLen %avl) { ; CHECK-LABEL: unfoldable_mismatched_sew: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetvli zero, a0, e64, m1, ta, ma ; CHECK-NEXT: vadd.vv v9, v9, v10 ; CHECK-NEXT: vsetvli zero, a0, e32, m1, tu, ma ; CHECK-NEXT: vmv.v.v v8, v9 ; CHECK-NEXT: ret %a = call @llvm.riscv.vadd.nxv1i64.nxv1i64( poison, %x, %y, iXLen %avl) %a.bitcast = bitcast %a to %b = call @llvm.riscv.vmv.v.v.nxv2i32( %passthru, %a.bitcast, iXLen %avl) ret %b } define @undef_passthru( %passthru, %x, %y, iXLen %avl) { ; CHECK-LABEL: undef_passthru: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetvli zero, a0, e64, m1, ta, ma ; CHECK-NEXT: vadd.vv v8, v9, v10 ; CHECK-NEXT: ret %a = call @llvm.riscv.vadd.nxv1i64.nxv1i64( %passthru, %x, %y, iXLen %avl) %b = call @llvm.riscv.vmv.v.v.nxv1i64( poison, %a, iXLen %avl) ret %b } ; Check that we can fold into vle64ff.v even if we need to move it past the ; passthru and it's safe. define @vleff_move_past_passthru(ptr %p, ptr %q, iXLen %avl) { ; CHECK-LABEL: vleff_move_past_passthru: ; CHECK: # %bb.0: ; CHECK-NEXT: vl1re64.v v8, (a1) ; CHECK-NEXT: vsetvli zero, a2, e64, m1, tu, ma ; CHECK-NEXT: vle64ff.v v8, (a0) ; CHECK-NEXT: ret %a = call { , iXLen } @llvm.riscv.vleff( poison, ptr %p, iXLen %avl) %vec = extractvalue { , iXLen } %a, 0 %passthru = load , ptr %q %b = call @llvm.riscv.vmv.v.v.nxv1i64( %passthru, %vec, iXLen %avl) ret %b } define @vmerge( %passthru, %x, %y, %m, iXLen %avl) { ; CHECK-LABEL: vmerge: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetvli zero, a0, e64, m1, tu, ma ; CHECK-NEXT: vmerge.vvm v8, v9, v10, v0 ; CHECK-NEXT: ret %a = call @llvm.riscv.vmerge.nxv1i64.nxv1i64( %passthru, %x, %y, %m, iXLen %avl) %b = call @llvm.riscv.vmv.v.v.nxv1i64( %passthru, %a, iXLen %avl) ret %b } define @commute_vfmadd( %passthru, %a, %b, iXLen %vl) { ; CHECK-LABEL: commute_vfmadd: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetvli zero, a0, e32, m2, tu, ma ; CHECK-NEXT: vfmacc.vv v8, v12, v10 ; CHECK-NEXT: ret %v = call @llvm.riscv.vfmadd( %a, %b, %passthru, iXLen 7, iXLen %vl, iXLen 3) %w = call @llvm.riscv.vmv.v.v( %passthru, %v, iXLen %vl) ret %w }