kmclaughlin created this revision. kmclaughlin added reviewers: sdesmalen, efriedma, huntergr. Herald added subscribers: psnobl, rkruppe, hiraditya, tschuett. Herald added a project: LLVM.
This patch handles illegal scalable types when lowering IR operations, addressing several places where the value of isScalableVector() is ignored. For types such as <vscale x 8 x i32>, this means splitting the operations. In this example, we would split it into two operations of type <vscale x 4 x i32> for the low and high halves. In cases such as <vscale x 2 x i32>, the elements in the vector will be promoted. In this case they will be promoted to i64 (with a vector of type <vscale x 2 x i64>) Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D78812 Files: llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp llvm/lib/CodeGen/TargetLoweringBase.cpp llvm/test/CodeGen/AArch64/llvm-ir-to-intrinsic.ll
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 <vscale x 2 x i64> %div } +define <vscale x 8 x i32> @sdiv_split_i32(<vscale x 8 x i32> %a, <vscale x 8 x i32> %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 <vscale x 8 x i32> %a, %b + ret <vscale x 8 x i32> %div +} + +define <vscale x 2 x i32> @sdiv_widen_i32(<vscale x 2 x i32> %a, <vscale x 2 x i32> %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 <vscale x 2 x i32> %a, %b + ret <vscale x 2 x i32> %div +} + +define <vscale x 4 x i64> @sdiv_split_i64(<vscale x 4 x i64> %a, <vscale x 4 x i64> %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 <vscale x 4 x i64> %a, %b + ret <vscale x 4 x i64> %div +} + ; ; UDIV ; @@ -43,3 +74,34 @@ %div = udiv <vscale x 2 x i64> %a, %b ret <vscale x 2 x i64> %div } + +define <vscale x 8 x i32> @udiv_split_i32(<vscale x 8 x i32> %a, <vscale x 8 x i32> %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 <vscale x 8 x i32> %a, %b + ret <vscale x 8 x i32> %div +} + +define <vscale x 2 x i32> @udiv_widen_i32(<vscale x 2 x i32> %a, <vscale x 2 x i32> %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 <vscale x 2 x i32> %a, %b + ret <vscale x 2 x i32> %div +} + +define <vscale x 4 x i64> @udiv_split_i64(<vscale x 4 x i64> %a, <vscale x 4 x i64> %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 <vscale x 4 x i64> %a, %b + ret <vscale x 4 x i64> %div +} 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/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;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits