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 @@ -55,8 +55,7 @@ unsigned Opc = VT.isInteger() ? RISCVISD::VMV_V_X_VL : RISCVISD::VFMV_V_F_VL; SDLoc DL(N); - SDValue VL = CurDAG->getTargetConstant(RISCV::VLMaxSentinel, DL, - Subtarget->getXLenVT()); + SDValue VL = CurDAG->getRegister(RISCV::X0, Subtarget->getXLenVT()); SDValue Result = CurDAG->getNode(Opc, DL, VT, N->getOperand(0), VL); --I; @@ -1902,14 +1901,24 @@ // allows us to choose betwen VSETIVLI or VSETVLI later. bool RISCVDAGToDAGISel::selectVLOp(SDValue N, SDValue &VL) { auto *C = dyn_cast(N); - if (C && isUInt<5>(C->getZExtValue())) + if (C && isUInt<5>(C->getZExtValue())) { VL = CurDAG->getTargetConstant(C->getZExtValue(), SDLoc(N), N->getValueType(0)); - else if (C && C->isAllOnesValue() && C->getOpcode() != ISD::TargetConstant) + } else if (C && C->isAllOnesValue()) { + // Treat all ones as VLMax. VL = CurDAG->getTargetConstant(RISCV::VLMaxSentinel, SDLoc(N), N->getValueType(0)); - else + } else if (isa(N) && + cast(N)->getReg() == RISCV::X0) { + // All our VL operands use an operand that allows GPRNoX0 or an immediate + // as the register class. Convert X0 to a special immediate to pass the + // MachineVerifier. This is recognized specially by the vsetvli insertion + // pass. + VL = CurDAG->getTargetConstant(RISCV::VLMaxSentinel, SDLoc(N), + N->getValueType(0)); + } else { VL = N; + } return true; } 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 @@ -1723,7 +1723,7 @@ MVT XLenVT = Subtarget.getXLenVT(); SDValue VL = VecVT.isFixedLengthVector() ? DAG.getConstant(VecVT.getVectorNumElements(), DL, XLenVT) - : DAG.getTargetConstant(RISCV::VLMaxSentinel, DL, XLenVT); + : DAG.getRegister(RISCV::X0, XLenVT); MVT MaskVT = MVT::getVectorVT(MVT::i1, ContainerVT.getVectorElementCount()); SDValue Mask = DAG.getNode(RISCVISD::VMSET_VL, DL, MaskVT, VL); return {Mask, VL}; @@ -2370,14 +2370,12 @@ // If vl is equal to XLEN_MAX and Hi constant is equal to Lo, we could use // vmv.v.x whose EEW = 32 to lower it. auto *Const = dyn_cast(VL); - if (LoC == HiC && Const && Const->isAllOnesValue() && - Const->getOpcode() != ISD::TargetConstant) { + if (LoC == HiC && Const && Const->isAllOnesValue()) { MVT InterVT = MVT::getVectorVT(MVT::i32, VT.getVectorElementCount() * 2); // TODO: if vl <= min(VLMAX), we can also do this. But we could not // access the subtarget here now. - auto InterVec = DAG.getNode( - RISCVISD::VMV_V_X_VL, DL, InterVT, Lo, - DAG.getTargetConstant(RISCV::VLMaxSentinel, DL, MVT::i32)); + auto InterVec = DAG.getNode(RISCVISD::VMV_V_X_VL, DL, InterVT, Lo, + DAG.getRegister(RISCV::X0, MVT::i32)); return DAG.getNode(ISD::BITCAST, DL, VT, InterVec); } } @@ -4159,22 +4157,20 @@ // If Hi constant is all the same sign bit as Lo, lower this as a custom // node in order to try and match RVV vector/scalar instructions. if ((LoC >> 31) == HiC) - return DAG.getNode( - RISCVISD::VMV_V_X_VL, DL, VecVT, Lo, - DAG.getTargetConstant(RISCV::VLMaxSentinel, DL, MVT::i32)); + return DAG.getNode(RISCVISD::VMV_V_X_VL, DL, VecVT, Lo, + DAG.getRegister(RISCV::X0, MVT::i32)); } // Detect cases where Hi is (SRA Lo, 31) which means Hi is Lo sign extended. if (Hi.getOpcode() == ISD::SRA && Hi.getOperand(0) == Lo && isa(Hi.getOperand(1)) && Hi.getConstantOperandVal(1) == 31) - return DAG.getNode( - RISCVISD::VMV_V_X_VL, DL, VecVT, Lo, - DAG.getTargetConstant(RISCV::VLMaxSentinel, DL, MVT::i32)); + return DAG.getNode(RISCVISD::VMV_V_X_VL, DL, VecVT, Lo, + DAG.getRegister(RISCV::X0, MVT::i32)); // Fall back to use a stack store and stride x0 vector load. Use X0 as VL. return DAG.getNode(RISCVISD::SPLAT_VECTOR_SPLIT_I64_VL, DL, VecVT, Lo, Hi, - DAG.getTargetConstant(RISCV::VLMaxSentinel, DL, MVT::i32)); + DAG.getRegister(RISCV::X0, MVT::i32)); } // Custom-lower extensions from mask vectors by using a vselect either with 1 @@ -4206,12 +4202,10 @@ SplatZero = DAG.getSplatVector(VecVT, DL, SplatZero); SplatTrueVal = DAG.getSplatVector(VecVT, DL, SplatTrueVal); } else { - SplatZero = - DAG.getNode(RISCVISD::VMV_V_X_VL, DL, VecVT, SplatZero, - DAG.getTargetConstant(RISCV::VLMaxSentinel, DL, XLenVT)); - SplatTrueVal = - DAG.getNode(RISCVISD::VMV_V_X_VL, DL, VecVT, SplatTrueVal, - DAG.getTargetConstant(RISCV::VLMaxSentinel, DL, XLenVT)); + SplatZero = DAG.getNode(RISCVISD::VMV_V_X_VL, DL, VecVT, SplatZero, + DAG.getRegister(RISCV::X0, XLenVT)); + SplatTrueVal = DAG.getNode(RISCVISD::VMV_V_X_VL, DL, VecVT, SplatTrueVal, + DAG.getRegister(RISCV::X0, XLenVT)); } return DAG.getNode(ISD::VSELECT, DL, VecVT, Src, SplatTrueVal, SplatZero); @@ -5528,9 +5522,8 @@ if (!IsRV32E64) SplatVL = DAG.getSplatVector(IntVT, DL, VLMinus1); else - SplatVL = - DAG.getNode(RISCVISD::VMV_V_X_VL, DL, IntVT, VLMinus1, - DAG.getTargetConstant(RISCV::VLMaxSentinel, DL, XLenVT)); + SplatVL = DAG.getNode(RISCVISD::VMV_V_X_VL, DL, IntVT, VLMinus1, + DAG.getRegister(RISCV::X0, XLenVT)); SDValue VID = DAG.getNode(RISCVISD::VID_VL, DL, IntVT, Mask, VL); SDValue Indices = @@ -8255,8 +8248,7 @@ SDLoc DL(N); EVT VT = N->getValueType(0); ShAmt = DAG.getNode(RISCVISD::VMV_V_X_VL, DL, VT, ShAmt.getOperand(0), - DAG.getTargetConstant(RISCV::VLMaxSentinel, DL, - Subtarget.getXLenVT())); + DAG.getRegister(RISCV::X0, Subtarget.getXLenVT())); return DAG.getNode(N->getOpcode(), DL, VT, N->getOperand(0), ShAmt); } break; diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoVVLPatterns.td b/llvm/lib/Target/RISCV/RISCVInstrInfoVVLPatterns.td --- a/llvm/lib/Target/RISCV/RISCVInstrInfoVVLPatterns.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoVVLPatterns.td @@ -649,8 +649,8 @@ (riscv_trunc_vector_vl (op (vti.Wti.Vector vti.Wti.RegClass:$rs2), (vti.Wti.Vector (extop (vti.Vti.Vector vti.Vti.RegClass:$rs1)))), - (riscv_vmset_vl VLMax), - VLMax)), + (riscv_vmset_vl X0), + X0)), (!cast(instruction_name#"_WV_"#vti.Vti.LMul.MX) vti.Wti.RegClass:$rs2, vti.Vti.RegClass:$rs1, vti.Vti.AVL, vti.Vti.Log2SEW)>; @@ -664,8 +664,8 @@ (riscv_trunc_vector_vl (op (vti.Wti.Vector vti.Wti.RegClass:$rs2), (vti.Wti.Vector (extop (vti.Vti.Vector (SplatPat GPR:$rs1))))), - (riscv_vmset_vl VLMax), - VLMax)), + (riscv_vmset_vl X0), + X0)), (!cast(instruction_name#"_WX_"#vti.Vti.LMul.MX) vti.Wti.RegClass:$rs2, GPR:$rs1, vti.Vti.AVL, vti.Vti.Log2SEW)>;