[PATCH] D78812: [SVE][CodeGen] Fix legalisation for scalable types
This revision was automatically updated to reflect the committed changes. Closed by commit rGa31f4c52bf85: [SVE][CodeGen] Fix legalisation for scalable types (authored by kmclaughlin). Changed prior to commit: https://reviews.llvm.org/D78812?vs=260603=262580#toc Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D78812/new/ 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 %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, #0x +; CHECK-DAG: and z0.d, z0.d, #0x +; 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 ; Index: llvm/lib/CodeGen/TargetLoweringBase.cpp === --- llvm/lib/CodeGen/TargetLoweringBase.cpp +++ llvm/lib/CodeGen/TargetLoweringBase.cpp @@ -1392,7 +1392,7 @@ EVT , unsigned , MVT ) 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; Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp === --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ 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 =
[PATCH] D78812: [SVE][CodeGen] Fix legalisation for scalable types
efriedma accepted this revision. efriedma added a comment. This revision is now accepted and ready to land. LGTM CHANGES SINCE LAST ACTION https://reviews.llvm.org/D78812/new/ https://reviews.llvm.org/D78812 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D78812: [SVE][CodeGen] Fix legalisation for scalable types
kmclaughlin marked an inline comment as done. kmclaughlin added inline comments. Comment at: llvm/lib/CodeGen/TargetLoweringBase.cpp:1429 + !isTypeLegal(EVT::getVectorVT(Context, EltTy, EltCnt))) { +EltCnt.Min >>= 1; NumVectorRegs <<= 1; I will create a separate patch to clean this up a bit by adding an overloaded `operator>>` CHANGES SINCE LAST ACTION https://reviews.llvm.org/D78812/new/ https://reviews.llvm.org/D78812 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D78812: [SVE][CodeGen] Fix legalisation for scalable types
kmclaughlin marked 2 inline comments as done. kmclaughlin added inline comments. Comment at: llvm/test/CodeGen/AArch64/llvm-ir-to-intrinsic.ll:107 + ret %div +} efriedma wrote: > Maybe also worth adding a testcase for ``, assuming that > doesn't expose anything really tricky. Promotion is not possible for `` since this would result in a ``, which is also illegal. Instead will need to widen a type such as ``, which needs some more work. For fixed width vectors, the compiler will scalarise cases such as this (e.g. from 1 x i32 to just i32), which isn't something we can do for scalable vectors because of the runtime scaling. This has never had much priority because in practice the vectoriser won't pick a VF of 1, so I think we can add support for this at a later point. Currently, tests which use types such as this will trigger the assert added to FoldBUILD_VECTOR in D78636. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D78812/new/ https://reviews.llvm.org/D78812 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D78812: [SVE][CodeGen] Fix legalisation for scalable types
kmclaughlin updated this revision to Diff 260603. kmclaughlin added a comment. - Use ElementCount with getVectorVT CHANGES SINCE LAST ACTION https://reviews.llvm.org/D78812/new/ 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 %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, #0x +; CHECK-DAG: and z0.d, z0.d, #0x +; 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 +} Index: llvm/lib/CodeGen/TargetLoweringBase.cpp === --- llvm/lib/CodeGen/TargetLoweringBase.cpp +++ llvm/lib/CodeGen/TargetLoweringBase.cpp @@ -1392,7 +1392,7 @@ EVT , unsigned , MVT ) 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; Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp === --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ 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(),
[PATCH] D78812: [SVE][CodeGen] Fix legalisation for scalable types
efriedma added inline comments. Comment at: llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp:738 + *DAG.getContext(), IntermediateVT.getScalarType(), DestVectorNoElts, + ValueVT.isScalableVector()); if (ValueVT != BuiltVectorTy) { Can we use ElementCount here? Comment at: llvm/lib/CodeGen/TargetLoweringBase.cpp:1429 + while (NumElts > 1 && + !isTypeLegal(EVT::getVectorVT(Context, EltTy, NumElts, IsScalable))) { NumElts >>= 1; Can we use ElementCount here? Comment at: llvm/test/CodeGen/AArch64/llvm-ir-to-intrinsic.ll:107 + ret %div +} Maybe also worth adding a testcase for ``, assuming that doesn't expose anything really tricky. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D78812/new/ https://reviews.llvm.org/D78812 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D78812: [SVE][CodeGen] Fix legalisation for scalable types
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 , this means splitting the operations. In this example, we would split it into two operations of type for the low and high halves. In cases such as , the elements in the vector will be promoted. In this case they will be promoted to i64 (with a vector of type ) 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 %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, #0x +; CHECK-DAG: and z0.d, z0.d, #0x +; 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 +} Index: llvm/lib/CodeGen/TargetLoweringBase.cpp === --- llvm/lib/CodeGen/TargetLoweringBase.cpp +++ llvm/lib/CodeGen/TargetLoweringBase.cpp @@ -1393,6 +1393,7 @@ unsigned , MVT ) 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