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 @@ -15829,6 +15829,8 @@ } else { if (Constraint == "vr" || Constraint == "vm") return C_RegisterClass; + if (Constraint == "vi" || Constraint == "vj" || Constraint == "vk") + return C_Immediate; } return TargetLowering::getConstraintType(Constraint); } @@ -16089,6 +16091,29 @@ default: break; } + } else { + if (Constraint == "vi") { + if (auto *C = dyn_cast(Op)) { + int64_t CVal = C->getSExtValue(); + if (isInt<5>(CVal)) + Ops.push_back( + DAG.getTargetConstant(CVal, SDLoc(Op), Subtarget.getXLenVT())); + } + } else if (Constraint == "vj") { + if (auto *C = dyn_cast(Op)) { + int64_t CVal = C->getSExtValue(); + if (isInt<5>(-CVal)) + Ops.push_back( + DAG.getTargetConstant(CVal, SDLoc(Op), Subtarget.getXLenVT())); + } + } else if (Constraint == "vk") { + if (auto *C = dyn_cast(Op)) { + uint64_t CVal = C->getZExtValue(); + if (isUInt<5>(CVal)) + Ops.push_back( + DAG.getTargetConstant(CVal, SDLoc(Op), Subtarget.getXLenVT())); + } + } } TargetLowering::LowerAsmOperandForConstraint(Op, Constraint, Ops, DAG); } diff --git a/llvm/test/CodeGen/RISCV/rvv/inline-asm-invalid.ll b/llvm/test/CodeGen/RISCV/rvv/inline-asm-invalid.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/rvv/inline-asm-invalid.ll @@ -0,0 +1,29 @@ +; RUN: not llc -mtriple=riscv64 -mattr=+v < %s 2>&1 | FileCheck %s + +define @test_vi( %in) nounwind { +entry: +; CHECK: error: value out of range for constraint 'vi' + %0 = tail call asm "vadd.vi $0, $1, $2", "=^vr,^vr,^vi"( %in, i32 -17) +; CHECK: error: value out of range for constraint 'vi' + %1 = tail call asm "vadd.vi $0, $1, $2", "=^vr,^vr,^vi"( %0, i32 16) + ret %1 +} + +define @test_vj( %in) nounwind { +entry: +; CHECK: error: value out of range for constraint 'vj' + %0 = tail call asm "vmslt.vi $0, $1, $2", "=^vr,^vr,^vj"( %in, i32 -16) +; CHECK: error: value out of range for constraint 'vj' + %1 = tail call asm "vmslt.vi $0, $1, $2", "=^vr,^vr,^vj"( %in, i32 17) + %2 = and %0, %1 + ret %2 +} + +define @test_vk( %in) nounwind { +entry: +; CHECK: error: value out of range for constraint 'vk' + %0 = tail call asm "vsll.vi $0, $1, $2", "=^vr,^vr,^vk"( %in, i32 -1) +; CHECK: error: value out of range for constraint 'vk' + %1 = tail call asm "vsll.vi $0, $1, $2", "=^vr,^vr,^vk"( %0, i32 32) + ret %1 +} 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 @@ -420,3 +420,54 @@ %0 = tail call asm "vmand.mm $0, $1, $2", "={v0},{v1},{v2}"( %in, %in2) ret %0 } + +define @test_vi( %in) nounwind { +; CHECK-LABEL: test_vi: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: #APP +; CHECK-NEXT: vadd.vi v8, v8, -16 +; CHECK-NEXT: #NO_APP +; CHECK-NEXT: #APP +; CHECK-NEXT: vadd.vi v8, v8, 15 +; CHECK-NEXT: #NO_APP +; CHECK-NEXT: ret +entry: + %0 = tail call asm "vadd.vi $0, $1, $2", "=^vr,^vr,^vi"( %in, i32 -16) + %1 = tail call asm "vadd.vi $0, $1, $2", "=^vr,^vr,^vi"( %0, i32 15) + ret %1 +} + +define @test_vj( %in) nounwind { +; CHECK-LABEL: test_vj: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: #APP +; CHECK-NEXT: vmsle.vi v9, v8, -16 +; CHECK-NEXT: #NO_APP +; CHECK-NEXT: #APP +; CHECK-NEXT: vmsle.vi v8, v8, 15 +; CHECK-NEXT: #NO_APP +; CHECK-NEXT: vsetvli a0, zero, e8, mf8, ta, ma +; CHECK-NEXT: vmand.mm v0, v9, v8 +; CHECK-NEXT: ret +entry: + %0 = tail call asm "vmslt.vi $0, $1, $2", "=^vr,^vr,^vj"( %in, i32 -15) + %1 = tail call asm "vmslt.vi $0, $1, $2", "=^vr,^vr,^vj"( %in, i32 16) + %2 = and %0, %1 + ret %2 +} + +define @test_vk( %in) nounwind { +; CHECK-LABEL: test_vk: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: #APP +; CHECK-NEXT: vsll.vi v8, v8, 0 +; CHECK-NEXT: #NO_APP +; CHECK-NEXT: #APP +; CHECK-NEXT: vsll.vi v8, v8, 31 +; CHECK-NEXT: #NO_APP +; CHECK-NEXT: ret +entry: + %0 = tail call asm "vsll.vi $0, $1, $2", "=^vr,^vr,^vk"( %in, i32 0) + %1 = tail call asm "vsll.vi $0, $1, $2", "=^vr,^vr,^vk"( %0, i32 31) + ret %1 +}