diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -731,10 +731,10 @@ IntermediateVT.getVectorNumElements() : 1; // Convert the vector to the appropriate type if necessary. - unsigned DestVectorNoElts = NumIntermediates * IntermediateNumElts; - + auto DestEltCnt = ElementCount(NumIntermediates * IntermediateNumElts, + ValueVT.isScalableVector()); EVT BuiltVectorTy = EVT::getVectorVT( - *DAG.getContext(), IntermediateVT.getScalarType(), DestVectorNoElts); + *DAG.getContext(), IntermediateVT.getScalarType(), DestEltCnt); if (ValueVT != BuiltVectorTy) { if (SDValue Widened = widenVectorToPartType(DAG, Val, DL, BuiltVectorTy)) Val = Widened; diff --git a/llvm/lib/CodeGen/TargetLoweringBase.cpp b/llvm/lib/CodeGen/TargetLoweringBase.cpp --- a/llvm/lib/CodeGen/TargetLoweringBase.cpp +++ b/llvm/lib/CodeGen/TargetLoweringBase.cpp @@ -1392,7 +1392,7 @@ EVT &IntermediateVT, unsigned &NumIntermediates, MVT &RegisterVT) const { - unsigned NumElts = VT.getVectorNumElements(); + ElementCount EltCnt = VT.getVectorElementCount(); // If there is a wider vector type with the same element type as this one, // or a promoted vector type that has the same number of elements which @@ -1400,7 +1400,7 @@ // This handles things like <2 x float> -> <4 x float> and // <4 x i1> -> <4 x i32>. LegalizeTypeAction TA = getTypeAction(Context, VT); - if (NumElts != 1 && (TA == TypeWidenVector || TA == TypePromoteInteger)) { + if (EltCnt.Min != 1 && (TA == TypeWidenVector || TA == TypePromoteInteger)) { EVT RegisterEVT = getTypeToTransformTo(Context, VT); if (isTypeLegal(RegisterEVT)) { IntermediateVT = RegisterEVT; @@ -1417,22 +1417,22 @@ // FIXME: We don't support non-power-of-2-sized vectors for now. Ideally we // could break down into LHS/RHS like LegalizeDAG does. - if (!isPowerOf2_32(NumElts)) { - NumVectorRegs = NumElts; - NumElts = 1; + if (!isPowerOf2_32(EltCnt.Min)) { + NumVectorRegs = EltCnt.Min; + EltCnt.Min = 1; } // Divide the input until we get to a supported size. This will always // end with a scalar if the target doesn't support vectors. - while (NumElts > 1 && !isTypeLegal( - EVT::getVectorVT(Context, EltTy, NumElts))) { - NumElts >>= 1; + while (EltCnt.Min > 1 && + !isTypeLegal(EVT::getVectorVT(Context, EltTy, EltCnt))) { + EltCnt.Min >>= 1; NumVectorRegs <<= 1; } NumIntermediates = NumVectorRegs; - EVT NewVT = EVT::getVectorVT(Context, EltTy, NumElts); + EVT NewVT = EVT::getVectorVT(Context, EltTy, EltCnt); if (!isTypeLegal(NewVT)) NewVT = EltTy; IntermediateVT = NewVT; diff --git a/llvm/test/CodeGen/AArch64/llvm-ir-to-intrinsic.ll b/llvm/test/CodeGen/AArch64/llvm-ir-to-intrinsic.ll --- a/llvm/test/CodeGen/AArch64/llvm-ir-to-intrinsic.ll +++ b/llvm/test/CodeGen/AArch64/llvm-ir-to-intrinsic.ll @@ -22,6 +22,37 @@ ret %div } +define @sdiv_split_i32( %a, %b) { +; CHECK-LABEL: @sdiv_split_i32 +; CHECK-DAG: ptrue p0.s +; CHECK-DAG: sdiv z0.s, p0/m, z0.s, z2.s +; CHECK-DAG: sdiv z1.s, p0/m, z1.s, z3.s +; CHECK-NEXT: ret + %div = sdiv %a, %b + ret %div +} + +define @sdiv_widen_i32( %a, %b) { +; CHECK-LABEL: @sdiv_widen_i32 +; CHECK-DAG: ptrue p0.d +; CHECK-DAG: sxtw z1.d, p0/m, z1.d +; CHECK-DAG: sxtw z0.d, p0/m, z0.d +; CHECK-DAG: sdiv z0.d, p0/m, z0.d, z1.d +; CHECK-NEXT: ret + %div = sdiv %a, %b + ret %div +} + +define @sdiv_split_i64( %a, %b) { +; CHECK-LABEL: @sdiv_split_i64 +; CHECK-DAG: ptrue p0.d +; CHECK-DAG: sdiv z0.d, p0/m, z0.d, z2.d +; CHECK-DAG: sdiv z1.d, p0/m, z1.d, z3.d +; CHECK-NEXT: ret + %div = sdiv %a, %b + ret %div +} + ; ; UDIV ; @@ -44,6 +75,37 @@ ret %div } +define @udiv_split_i32( %a, %b) { +; CHECK-LABEL: @udiv_split_i32 +; CHECK-DAG: ptrue p0.s +; CHECK-DAG: udiv z0.s, p0/m, z0.s, z2.s +; CHECK-DAG: udiv z1.s, p0/m, z1.s, z3.s +; CHECK-NEXT: ret + %div = udiv %a, %b + ret %div +} + +define @udiv_widen_i32( %a, %b) { +; CHECK-LABEL: @udiv_widen_i32 +; CHECK-DAG: ptrue p0.d +; CHECK-DAG: and z1.d, z1.d, #0xffffffff +; CHECK-DAG: and z0.d, z0.d, #0xffffffff +; CHECK-DAG: udiv z0.d, p0/m, z0.d, z1.d +; CHECK-NEXT: ret + %div = udiv %a, %b + ret %div +} + +define @udiv_split_i64( %a, %b) { +; CHECK-LABEL: @udiv_split_i64 +; CHECK-DAG: ptrue p0.d +; CHECK-DAG: udiv z0.d, p0/m, z0.d, z2.d +; CHECK-DAG: udiv z1.d, p0/m, z1.d, z3.d +; CHECK-NEXT: ret + %div = udiv %a, %b + ret %div +} + ; ; SMIN ;