diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -1724,9 +1724,17 @@ StringRef Val = A->getValue(); const Driver &D = getToolChain().getDriver(); if (Val.equals("128") || Val.equals("256") || Val.equals("512") || - Val.equals("1024") || Val.equals("2048")) + Val.equals("1024") || Val.equals("2048")) { CmdArgs.push_back( Args.MakeArgString(llvm::Twine("-msve-vector-bits=") + Val)); + + CmdArgs.push_back("-mllvm"); + CmdArgs.push_back( + Args.MakeArgString("-aarch64-sve-vector-bits-min=" + Val)); + // CmdArgs.push_back("-mllvm"); + // CmdArgs.push_back( + // Args.MakeArgString("-aarch64-sve-vector-bits-max=" + Val)); + } // Silently drop requests for vector-length agnostic code as it's implied. else if (!Val.equals("scalable")) // Handle the unsupported values passed to msve-vector-bits. diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -20577,7 +20577,8 @@ EVT N0SrcSVT = N0Src.getValueType().getScalarType(); EVT N1SrcSVT = N1Src.getValueType().getScalarType(); if ((N0.isUndef() || N0SrcSVT == N1SrcSVT) && - N0Src.getValueType().isVector() && N1Src.getValueType().isVector()) { + N0Src.getValueType().isFixedLengthVector() && + N1Src.getValueType().isFixedLengthVector()) { EVT NewVT; SDLoc DL(N); SDValue NewIdx; diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.h b/llvm/lib/Target/AArch64/AArch64ISelLowering.h --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.h +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.h @@ -878,6 +878,7 @@ SDValue LowerVectorSRA_SRL_SHL(SDValue Op, SelectionDAG &DAG) const; SDValue LowerShiftLeftParts(SDValue Op, SelectionDAG &DAG) const; SDValue LowerShiftRightParts(SDValue Op, SelectionDAG &DAG) const; + SDValue LowerVSELECT(SDValue Op, SelectionDAG &DAG) const; SDValue LowerVSETCC(SDValue Op, SelectionDAG &DAG) const; SDValue LowerCTPOP(SDValue Op, SelectionDAG &DAG) const; SDValue LowerF128Call(SDValue Op, SelectionDAG &DAG, diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -1110,13 +1110,24 @@ setOperationAction(ISD::SHL, VT, Custom); setOperationAction(ISD::SIGN_EXTEND, VT, Custom); setOperationAction(ISD::SIGN_EXTEND_INREG, VT, Custom); + setOperationAction(ISD::SMAX, VT, Custom); + setOperationAction(ISD::SMIN, VT, Custom); setOperationAction(ISD::SRA, VT, Custom); setOperationAction(ISD::SRL, VT, Custom); setOperationAction(ISD::STORE, VT, Custom); setOperationAction(ISD::SUB, VT, Custom); setOperationAction(ISD::TRUNCATE, VT, Custom); + setOperationAction(ISD::UMAX, VT, Custom); + setOperationAction(ISD::UMIN, VT, Custom); + setOperationAction(ISD::VSELECT, VT, Custom); setOperationAction(ISD::XOR, VT, Custom); setOperationAction(ISD::ZERO_EXTEND, VT, Custom); + + if (VT.getVectorElementType() == MVT::i32 || + VT.getVectorElementType() == MVT::i64) { + setOperationAction(ISD::SDIV, VT, Custom); + setOperationAction(ISD::UDIV, VT, Custom); + } } void AArch64TargetLowering::addDRTypeForNEON(MVT VT) { @@ -3710,6 +3721,8 @@ return LowerToPredicatedOp(Op, DAG, AArch64ISD::FMAXNM_PRED); case ISD::FMINNUM: return LowerToPredicatedOp(Op, DAG, AArch64ISD::FMINNM_PRED); + case ISD::VSELECT: + return LowerVSELECT(Op, DAG); } } @@ -15491,3 +15504,24 @@ auto Promote = DAG.getBoolExtOrTrunc(Cmp, DL, PromoteVT, InVT); return convertFromScalableVector(DAG, Op.getValueType(), Promote); } + +SDValue AArch64TargetLowering::LowerVSELECT(SDValue Op, + SelectionDAG &DAG) const { + SDLoc DL(Op); + + EVT InVT = Op.getOperand(1).getValueType(); + EVT ContainerVT = getContainerForFixedLengthVector(DAG, InVT); + auto Op1 = convertToScalableVector(DAG, ContainerVT, Op.getOperand(1)); + auto Op2 = convertToScalableVector(DAG, ContainerVT, Op.getOperand(2)); + + // Convert the mask to a predicated (NOTE: We don't need to worry about + // inactive lanes since VSELECT is safe when given undefined elements). + EVT MaskVT = Op.getOperand(0).getValueType(); + EVT MaskContainerVT = getContainerForFixedLengthVector(DAG, MaskVT); + auto Mask = convertToScalableVector(DAG, MaskContainerVT, Op.getOperand(0)); + Mask = DAG.getNode(ISD::TRUNCATE, DL, + MaskContainerVT.changeVectorElementType(MVT::i1), Mask); + + auto VSel = DAG.getNode(ISD::VSELECT, DL, ContainerVT, Mask, Op1, Op2); + return convertFromScalableVector(DAG, InVT, VSel); +}