Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp =================================================================== --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -734,7 +734,8 @@ unsigned DestVectorNoElts = NumIntermediates * IntermediateNumElts; EVT BuiltVectorTy = EVT::getVectorVT( - *DAG.getContext(), IntermediateVT.getScalarType(), DestVectorNoElts); + *DAG.getContext(), IntermediateVT.getScalarType(), DestVectorNoElts, + ValueVT.isScalableVector()); if (ValueVT != BuiltVectorTy) { if (SDValue Widened = widenVectorToPartType(DAG, Val, DL, BuiltVectorTy)) Val = Widened; Index: llvm/lib/CodeGen/TargetLoweringBase.cpp =================================================================== --- llvm/lib/CodeGen/TargetLoweringBase.cpp +++ llvm/lib/CodeGen/TargetLoweringBase.cpp @@ -1393,6 +1393,7 @@ unsigned &NumIntermediates, MVT &RegisterVT) const { unsigned NumElts = VT.getVectorNumElements(); + bool IsScalable = VT.isScalableVector(); // 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 @@ -1424,15 +1425,15 @@ // 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))) { + while (NumElts > 1 && + !isTypeLegal(EVT::getVectorVT(Context, EltTy, NumElts, IsScalable))) { NumElts >>= 1; NumVectorRegs <<= 1; } NumIntermediates = NumVectorRegs; - EVT NewVT = EVT::getVectorVT(Context, EltTy, NumElts); + EVT NewVT = EVT::getVectorVT(Context, EltTy, NumElts, IsScalable); if (!isTypeLegal(NewVT)) NewVT = EltTy; IntermediateVT = NewVT; Index: llvm/test/CodeGen/AArch64/llvm-ir-to-intrinsic.ll =================================================================== --- llvm/test/CodeGen/AArch64/llvm-ir-to-intrinsic.ll +++ 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 ; @@ -43,3 +74,34 @@ %div = udiv %a, %b 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 +}