diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst --- a/llvm/docs/LangRef.rst +++ b/llvm/docs/LangRef.rst @@ -4822,7 +4822,7 @@ - ``r``: A 32- or 64-bit general-purpose register (depending on the platform ``XLEN``). - ``vr``: A vector register. (requires V extension). -- ``vm``: A vector mask register. (requires V extension). +- ``vm``: A vector register for masking operand. (requires V extension). Sparc: diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -9310,8 +9310,8 @@ return std::make_pair(0U, RC); } } else if (Constraint == "vm") { - if (TRI->isTypeLegalForClass(RISCV::VMRegClass, VT.SimpleTy)) - return std::make_pair(0U, &RISCV::VMRegClass); + if (TRI->isTypeLegalForClass(RISCV::VMV0RegClass, VT.SimpleTy)) + return std::make_pair(0U, &RISCV::VMV0RegClass); } } @@ -9833,16 +9833,27 @@ unsigned ValueVTBitSize = ValueVT.getSizeInBits().getKnownMinSize(); unsigned PartVTBitSize = PartVT.getSizeInBits().getKnownMinSize(); if (PartVTBitSize % ValueVTBitSize == 0) { + assert(PartVTBitSize >= ValueVTBitSize); // If the element types are different, bitcast to the same element type of // PartVT first. + // Give an example here, we want copy a value to + // . + // We need to convert to by insert + // subvector, then we can bitcast to . if (ValueEltVT != PartEltVT) { - unsigned Count = ValueVTBitSize / PartEltVT.getSizeInBits(); - assert(Count != 0 && "The number of element should not be zero."); - EVT SameEltTypeVT = - EVT::getVectorVT(Context, PartEltVT, Count, /*IsScalable=*/true); - Val = DAG.getNode(ISD::BITCAST, DL, SameEltTypeVT, Val); - } - Val = DAG.getNode(ISD::INSERT_SUBVECTOR, DL, PartVT, DAG.getUNDEF(PartVT), + if (PartVTBitSize > ValueVTBitSize) { + unsigned Count = PartVTBitSize / ValueEltVT.getFixedSizeInBits(); + assert(Count != 0 && "The number of element should not be zero."); + EVT LargerEltTypeVT = + EVT::getVectorVT(Context, ValueEltVT, Count, /*IsScalable=*/true); + Val = DAG.getNode(ISD::INSERT_SUBVECTOR, DL, LargerEltTypeVT, + DAG.getUNDEF(LargerEltTypeVT), Val, + DAG.getConstant(0, DL, Subtarget.getXLenVT())); + } + Val = DAG.getNode(ISD::BITCAST, DL, PartVT, Val); + } else + Val = + DAG.getNode(ISD::INSERT_SUBVECTOR, DL, PartVT, DAG.getUNDEF(PartVT), Val, DAG.getConstant(0, DL, Subtarget.getXLenVT())); Parts[0] = Val; return true; @@ -9873,19 +9884,23 @@ unsigned ValueVTBitSize = ValueVT.getSizeInBits().getKnownMinSize(); unsigned PartVTBitSize = PartVT.getSizeInBits().getKnownMinSize(); if (PartVTBitSize % ValueVTBitSize == 0) { + assert(PartVTBitSize >= ValueVTBitSize); EVT SameEltTypeVT = ValueVT; // If the element types are different, convert it to the same element type // of PartVT. + // Give an example here, we want copy a value from + // . + // We need to convert to first, + // then we can extract . if (ValueEltVT != PartEltVT) { - unsigned Count = ValueVTBitSize / PartEltVT.getSizeInBits(); + unsigned Count = PartVTBitSize / ValueEltVT.getFixedSizeInBits(); assert(Count != 0 && "The number of element should not be zero."); SameEltTypeVT = - EVT::getVectorVT(Context, PartEltVT, Count, /*IsScalable=*/true); + EVT::getVectorVT(Context, ValueEltVT, Count, /*IsScalable=*/true); + Val = DAG.getNode(ISD::BITCAST, DL, SameEltTypeVT, Val); } - Val = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, SameEltTypeVT, Val, + Val = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, ValueVT, Val, DAG.getConstant(0, DL, Subtarget.getXLenVT())); - if (ValueEltVT != PartEltVT) - Val = DAG.getNode(ISD::BITCAST, DL, ValueVT, Val); return Val; } } diff --git a/llvm/lib/Target/RISCV/RISCVRegisterInfo.td b/llvm/lib/Target/RISCV/RISCVRegisterInfo.td --- a/llvm/lib/Target/RISCV/RISCVRegisterInfo.td +++ b/llvm/lib/Target/RISCV/RISCVRegisterInfo.td @@ -526,8 +526,8 @@ vfloat16m8_t, vfloat32m8_t, vfloat64m8_t], (add V8M8, V16M8, V24M8), 8>; -defvar VMaskVTs = [vbool64_t, vbool32_t, vbool16_t, vbool8_t, - vbool4_t, vbool2_t, vbool1_t]; +defvar VMaskVTs = [vbool1_t, vbool64_t, vbool32_t, vbool16_t, vbool8_t, + vbool4_t, vbool2_t]; def VMV0 : RegisterClass<"RISCV", VMaskVTs, 64, (add V0)> { let Size = 64; diff --git a/llvm/test/CodeGen/RISCV/rvv/inline-asm.ll b/llvm/test/CodeGen/RISCV/rvv/inline-asm.ll --- a/llvm/test/CodeGen/RISCV/rvv/inline-asm.ll +++ b/llvm/test/CodeGen/RISCV/rvv/inline-asm.ll @@ -10,7 +10,7 @@ ; CHECK-NEXT: #NO_APP ; CHECK-NEXT: ret entry: - %0 = tail call asm "vmand.mm $0, $1, $2", "=^vm,^vm,^vm"( %in, %in2) + %0 = tail call asm "vmand.mm $0, $1, $2", "=^vr,^vr,^vr"( %in, %in2) ret %0 } @@ -22,7 +22,7 @@ ; CHECK-NEXT: #NO_APP ; CHECK-NEXT: ret entry: - %0 = tail call asm "vmand.mm $0, $1, $2", "=^vm,^vm,^vm"( %in, %in2) + %0 = tail call asm "vmand.mm $0, $1, $2", "=^vr,^vr,^vr"( %in, %in2) ret %0 } @@ -34,7 +34,7 @@ ; CHECK-NEXT: #NO_APP ; CHECK-NEXT: ret entry: - %0 = tail call asm "vmand.mm $0, $1, $2", "=^vm,^vm,^vm"( %in, %in2) + %0 = tail call asm "vmand.mm $0, $1, $2", "=^vr,^vr,^vr"( %in, %in2) ret %0 } @@ -46,7 +46,7 @@ ; CHECK-NEXT: #NO_APP ; CHECK-NEXT: ret entry: - %0 = tail call asm "vmand.mm $0, $1, $2", "=^vm,^vm,^vm"( %in, %in2) + %0 = tail call asm "vmand.mm $0, $1, $2", "=^vr,^vr,^vr"( %in, %in2) ret %0 } @@ -58,7 +58,7 @@ ; CHECK-NEXT: #NO_APP ; CHECK-NEXT: ret entry: - %0 = tail call asm "vmand.mm $0, $1, $2", "=^vm,^vm,^vm"( %in, %in2) + %0 = tail call asm "vmand.mm $0, $1, $2", "=^vr,^vr,^vr"( %in, %in2) ret %0 } @@ -70,7 +70,7 @@ ; CHECK-NEXT: #NO_APP ; CHECK-NEXT: ret entry: - %0 = tail call asm "vmand.mm $0, $1, $2", "=^vm,^vm,^vm"( %in, %in2) + %0 = tail call asm "vmand.mm $0, $1, $2", "=^vr,^vr,^vr"( %in, %in2) ret %0 } @@ -82,7 +82,7 @@ ; CHECK-NEXT: #NO_APP ; CHECK-NEXT: ret entry: - %0 = tail call asm "vmand.mm $0, $1, $2", "=^vm,^vm,^vm"( %in, %in2) + %0 = tail call asm "vmand.mm $0, $1, $2", "=^vr,^vr,^vr"( %in, %in2) ret %0 } @@ -350,6 +350,18 @@ ret %0 } +define @test_64xi8_with_mask( %in, %in2, %mask) nounwind { +; CHECK-LABEL: test_64xi8_with_mask: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: #APP +; CHECK-NEXT: vadd.vv v8, v8, v16, v0.t +; CHECK-NEXT: #NO_APP +; CHECK-NEXT: ret +entry: + %0 = tail call asm "vadd.vv $0, $1, $2, $3.t", "=^vr,^vr,^vr,^vm"( %in, %in2, %mask) + ret %0 +} + define @test_specify_reg_mf2( %in, %in2) nounwind { ; CHECK-LABEL: test_specify_reg_mf2: ; CHECK: # %bb.0: # %entry