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 @@ -3208,6 +3208,10 @@ SDValue True = N->getOperand(2); SDValue Mask = N->getOperand(3); SDValue VL = N->getOperand(4); + // We always have a glue node for the mask at v0 + assert(cast(Mask)->getReg() == RISCV::V0); + SDValue Glue = N->getOperand(N->getNumOperands() - 1); + assert(Glue.getValueType() == MVT::Glue); // We require that either merge and false are the same, or that merge // is undefined. @@ -3253,19 +3257,6 @@ return false; } - if (IsMasked) { - assert(HasTiedDest && "Expected tied dest"); - // The vmerge instruction must be TU. - if (isImplicitDef(Merge)) - return false; - // The vmerge instruction must have an all 1s mask since we're going to keep - // the mask from the True instruction. - // FIXME: Support mask agnostic True instruction which would have an - // undef merge operand. - if (!usesAllOnesMask(N, /* MaskOpIdx */ 3)) - return false; - } - // Skip if True has side effect. // TODO: Support vleff and vlsegff. if (TII->get(TrueOpc).hasUnmodeledSideEffects()) @@ -3288,17 +3279,34 @@ LoopWorklist.push_back(False.getNode()); LoopWorklist.push_back(Mask.getNode()); LoopWorklist.push_back(VL.getNode()); - if (SDNode *Glued = N->getGluedNode()) - LoopWorklist.push_back(Glued); + LoopWorklist.push_back(Glue.getNode()); if (SDNode::hasPredecessorHelper(True.getNode(), Visited, LoopWorklist)) return false; } + if (IsMasked) { + assert(HasTiedDest && "Expected tied dest"); + // The vmerge instruction must be TU. + if (isImplicitDef(Merge)) + return false; + // The vmerge instruction must have an all 1s mask since we're going to keep + // the mask from the True instruction. + // FIXME: Support mask agnostic True instruction which would have an + // undef merge operand. + if (!usesAllOnesMask(N, /* MaskOpIdx */ 3)) + return false; + + Mask = True->getOperand(Info->MaskOpIdx); + assert(True->getGluedNode()); + Glue = True->getOperand(True->getNumOperands() - 1); + } + // The vector policy operand may be present for masked intrinsics bool HasVecPolicyOp = RISCVII::hasVecPolicyOp(TrueTSFlags); - unsigned TrueVLIndex = - True.getNumOperands() - HasVecPolicyOp - HasChainOp - HasGlueOp - 2; - SDValue TrueVL = True.getOperand(TrueVLIndex); + unsigned TrueVOpsStart = True.getNumOperands() - HasVecPolicyOp - HasChainOp - + HasGlueOp - 2 - IsMasked; + SDValue TrueVL = True.getOperand(TrueVOpsStart + IsMasked); + SDValue TrueSEW = True.getOperand(TrueVOpsStart + IsMasked + 1); // Allow the peephole for non-exception True with VLMAX vector length, since // all the values after VL of N are dependent on Merge. VLMAX should be @@ -3331,25 +3339,16 @@ CurDAG->getTargetConstant(Policy, DL, Subtarget->getXLenVT()); SmallVector Ops; - if (IsMasked) { - Ops.push_back(False); - Ops.append(True->op_begin() + 1, True->op_begin() + TrueVLIndex); - Ops.append({VL, /* SEW */ True.getOperand(TrueVLIndex + 1)}); - Ops.push_back(PolicyOp); - Ops.append(True->op_begin() + TrueVLIndex + 3, True->op_end()); - } else { - Ops.push_back(False); - Ops.append(True->op_begin() + HasTiedDest, True->op_begin() + TrueVLIndex); - Ops.append({Mask, VL, /* SEW */ True.getOperand(TrueVLIndex + 1)}); - Ops.push_back(PolicyOp); + Ops.push_back(False); + Ops.append(True->op_begin() + HasTiedDest, True->op_begin() + TrueVOpsStart); + Ops.append({Mask, VL, TrueSEW, PolicyOp}); - // Result node should have chain operand of True. - if (HasChainOp) - Ops.push_back(True.getOperand(TrueChainOpIdx)); + // Result node should have chain operand of True. + if (HasChainOp) + Ops.push_back(True.getOperand(TrueChainOpIdx)); - if (N->getGluedNode()) - Ops.push_back(N->getOperand(N->getNumOperands() - 1)); - } + // Add the glue for the CopyToReg of mask->v0. + Ops.push_back(Glue); SDNode *Result = CurDAG->getMachineNode(MaskedOpc, DL, True->getVTList(), Ops);