diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp --- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp @@ -1034,6 +1034,23 @@ /* Chain */ Node->getOperand(0))); return; } + + unsigned LMul; + bool Fractional; + std::tie(LMul, Fractional) = RISCVVType::decodeVLMUL(VLMul); + // Convert LMul to a fixed point value with 3 fractional bits. + LMul = Fractional ? (8 / LMul) : (LMul * 8); + + unsigned MaxVl = Subtarget->getMaxRVVVectorSizeInBits() == 0 + ? 65536 + : Subtarget->getMaxRVVVectorSizeInBits(); + unsigned MaxVLMAX = MaxVl * LMul / (8 * SEW); + + // vl = VLMAX if AVL ≥ (2 * VLMAX) + if (AVL >= 2 * MaxVLMAX) { + VLOperand = CurDAG->getRegister(RISCV::X0, XLenVT); + Opcode = RISCV::PseudoVSETVLIX0; + } } } diff --git a/llvm/test/CodeGen/RISCV/rvv/vsetvli.ll b/llvm/test/CodeGen/RISCV/rvv/vsetvli.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/rvv/vsetvli.ll @@ -0,0 +1,65 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc < %s -mtriple=riscv64 -mattr=+experimental-v | FileCheck %s --check-prefixes=CHECK,DEFAULT +; RUN: llc < %s -mtriple=riscv64 -mattr=+experimental-v -riscv-v-vector-bits-max=1024 | FileCheck %s --check-prefixes=CHECK,MAXVLEN1024 + +declare i64 @llvm.riscv.vsetvli( + i64, i64, i64); + +define i64 @vsetvli_max() { +; CHECK-LABEL: vsetvli_max: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e16, m2, ta, mu +; CHECK-NEXT: ret + %vl = call i64 @llvm.riscv.vsetvli(i64 -1, i64 1, i64 1) + ret i64 %vl +} + +define i64 @vsetvli_16384() { +; CHECK-LABEL: vsetvli_16384: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e16, m2, ta, mu +; CHECK-NEXT: ret + %vl = call i64 @llvm.riscv.vsetvli(i64 16384, i64 1, i64 1) + ret i64 %vl +} + +define i64 @vsetvli_16383() { +; DEFAULT-LABEL: vsetvli_16383: +; DEFAULT: # %bb.0: +; DEFAULT-NEXT: lui a0, 4 +; DEFAULT-NEXT: addiw a0, a0, -1 +; DEFAULT-NEXT: vsetvli a0, a0, e16, m2, ta, mu +; DEFAULT-NEXT: ret +; +; MAXVLEN1024-LABEL: vsetvli_16383: +; MAXVLEN1024: # %bb.0: +; MAXVLEN1024-NEXT: vsetvli a0, zero, e16, m2, ta, mu +; MAXVLEN1024-NEXT: ret + %vl = call i64 @llvm.riscv.vsetvli(i64 16383, i64 1, i64 1) + ret i64 %vl +} + +define i64 @vsetvli_8192() { +; CHECK-LABEL: vsetvli_8192: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e8, mf2, ta, mu +; CHECK-NEXT: ret + %vl = call i64 @llvm.riscv.vsetvli(i64 8192, i64 0, i64 7) + ret i64 %vl +} + +define i64 @vsetvli_8191() { +; DEFAULT-LABEL: vsetvli_8191: +; DEFAULT: # %bb.0: +; DEFAULT-NEXT: lui a0, 2 +; DEFAULT-NEXT: addiw a0, a0, -1 +; DEFAULT-NEXT: vsetvli a0, a0, e8, mf2, ta, mu +; DEFAULT-NEXT: ret +; +; MAXVLEN1024-LABEL: vsetvli_8191: +; MAXVLEN1024: # %bb.0: +; MAXVLEN1024-NEXT: vsetvli a0, zero, e8, mf2, ta, mu +; MAXVLEN1024-NEXT: ret + %vl = call i64 @llvm.riscv.vsetvli(i64 8191, i64 0, i64 7) + ret i64 %vl +}