[llvm-commits] [llvm] r106038 - in /llvm/trunk: lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp test/CodeGen/Generic/v-binop-widen.ll test/CodeGen/Generic/v-binop-widen2.ll
Daniel Dunbar
daniel at zuster.org
Wed Jun 16 14:34:57 PDT 2010
On Tue, Jun 15, 2010 at 1:29 PM, Mon P Wang <wangmp at apple.com> wrote:
> Author: wangmp
> Date: Tue Jun 15 15:29:05 2010
> New Revision: 106038
>
> URL: http://llvm.org/viewvc/llvm-project?rev=106038&view=rev
> Log:
> Fixed vector widening of binary instructions that can trap. Patch by Visa Putkinen!
>
> Added:
> llvm/trunk/test/CodeGen/Generic/v-binop-widen.ll
> llvm/trunk/test/CodeGen/Generic/v-binop-widen2.ll
Also, this test appears to be still crashing on ARM:
http://google1.osuosl.org:8011/builders/llvm-arm-linux/builds/3426/steps/test-llvm/logs/v-binop-widen2.ll
Should it be moved to x86?
- Daniel
> Modified:
> llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
>
> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp?rev=106038&r1=106037&r2=106038&view=diff
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp (original)
> +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp Tue Jun 15 15:29:05 2010
> @@ -1271,7 +1271,7 @@
> EVT WidenEltVT = WidenVT.getVectorElementType();
> EVT VT = WidenVT;
> unsigned NumElts = VT.getVectorNumElements();
> - while (!TLI.isTypeLegal(VT) && NumElts != 1) {
> + while (!TLI.isTypeSynthesizable(VT) && NumElts != 1) {
> NumElts = NumElts / 2;
> VT = EVT::getVectorVT(*DAG.getContext(), WidenEltVT, NumElts);
> }
> @@ -1286,13 +1286,20 @@
> return DAG.UnrollVectorOp(N, WidenVT.getVectorNumElements());
> } else {
> // Since the operation can trap, apply operation on the original vector.
> + EVT MaxVT = VT;
> SDValue InOp1 = GetWidenedVector(N->getOperand(0));
> SDValue InOp2 = GetWidenedVector(N->getOperand(1));
> unsigned CurNumElts = N->getValueType(0).getVectorNumElements();
>
> SmallVector<SDValue, 16> ConcatOps(CurNumElts);
> unsigned ConcatEnd = 0; // Current ConcatOps index.
> - unsigned Idx = 0; // Current Idx into input vectors.
> + int Idx = 0; // Current Idx into input vectors.
> +
> + // NumElts := greatest synthesizable vector size (at most WidenVT)
> + // while (orig. vector has unhandled elements) {
> + // take munches of size NumElts from the beginning and add to ConcatOps
> + // NumElts := next smaller supported vector size or 1
> + // }
> while (CurNumElts != 0) {
> while (CurNumElts >= NumElts) {
> SDValue EOp1 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, VT, InOp1,
> @@ -1303,26 +1310,21 @@
> Idx += NumElts;
> CurNumElts -= NumElts;
> }
> - EVT PrevVecVT = VT;
> do {
> NumElts = NumElts / 2;
> VT = EVT::getVectorVT(*DAG.getContext(), WidenEltVT, NumElts);
> - } while (!TLI.isTypeLegal(VT) && NumElts != 1);
> + } while (!TLI.isTypeSynthesizable(VT) && NumElts != 1);
>
> if (NumElts == 1) {
> - // Since we are using concat vector, build a vector from the scalar ops.
> - SDValue VecOp = DAG.getUNDEF(PrevVecVT);
> for (unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
> SDValue EOp1 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, WidenEltVT,
> InOp1, DAG.getIntPtrConstant(Idx));
> SDValue EOp2 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, WidenEltVT,
> InOp2, DAG.getIntPtrConstant(Idx));
> - VecOp = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, PrevVecVT, VecOp,
> - DAG.getNode(Opcode, dl, WidenEltVT, EOp1, EOp2),
> - DAG.getIntPtrConstant(i));
> + ConcatOps[ConcatEnd++] = DAG.getNode(Opcode, dl, WidenEltVT,
> + EOp1, EOp2);
> }
> CurNumElts = 0;
> - ConcatOps[ConcatEnd++] = VecOp;
> }
> }
>
> @@ -1333,23 +1335,65 @@
> return ConcatOps[0];
> }
>
> - // Rebuild vector to one with the widen type
> - Idx = ConcatEnd - 1;
> - while (Idx != 0) {
> + // while (Some element of ConcatOps is not of type MaxVT) {
> + // From the end of ConcatOps, collect elements of the same type and put
> + // them into an op of the next larger supported type
> + // }
> + while (ConcatOps[ConcatEnd-1].getValueType() != MaxVT) {
> + Idx = ConcatEnd - 1;
> VT = ConcatOps[Idx--].getValueType();
> - while (Idx != 0 && ConcatOps[Idx].getValueType() == VT)
> - --Idx;
> - if (Idx != 0) {
> - VT = ConcatOps[Idx].getValueType();
> - ConcatOps[Idx+1] = DAG.getNode(ISD::CONCAT_VECTORS, dl, VT,
> - &ConcatOps[Idx+1], ConcatEnd - Idx - 1);
> + while (Idx >= 0 && ConcatOps[Idx].getValueType() == VT)
> + Idx--;
> +
> + int NextSize = VT.isVector() ? VT.getVectorNumElements() : 1;
> + EVT NextVT;
> + do {
> + NextSize *= 2;
> + NextVT = EVT::getVectorVT(*DAG.getContext(), WidenEltVT, NextSize);
> + } while (!TLI.isTypeSynthesizable(NextVT));
> +
> + if (!VT.isVector()) {
> + // Scalar type, create an INSERT_VECTOR_ELEMENT of type NextVT
> + SDValue VecOp = DAG.getUNDEF(NextVT);
> + unsigned NumToInsert = ConcatEnd - Idx - 1;
> + for (unsigned i = 0, OpIdx = Idx+1; i < NumToInsert; i++, OpIdx++) {
> + VecOp = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, NextVT, VecOp,
> + ConcatOps[OpIdx], DAG.getIntPtrConstant(i));
> + }
> + ConcatOps[Idx+1] = VecOp;
> ConcatEnd = Idx + 2;
> + }
> + else {
> + // Vector type, create a CONCAT_VECTORS of type NextVT
> + SDValue undefVec = DAG.getUNDEF(VT);
> + unsigned OpsToConcat = NextSize/VT.getVectorNumElements();
> + SmallVector<SDValue, 16> SubConcatOps(OpsToConcat);
> + unsigned RealVals = ConcatEnd - Idx - 1;
> + unsigned SubConcatEnd = 0;
> + unsigned SubConcatIdx = Idx + 1;
> + while (SubConcatEnd < RealVals)
> + SubConcatOps[SubConcatEnd++] = ConcatOps[++Idx];
> + while (SubConcatEnd < OpsToConcat)
> + SubConcatOps[SubConcatEnd++] = undefVec;
> + ConcatOps[SubConcatIdx] = DAG.getNode(ISD::CONCAT_VECTORS, dl,
> + NextVT, &SubConcatOps[0],
> + OpsToConcat);
> + ConcatEnd = SubConcatIdx + 1;
> }
> }
> +
> + // Check to see if we have a single operation with the widen type.
> + if (ConcatEnd == 1) {
> + VT = ConcatOps[0].getValueType();
> + if (VT == WidenVT)
> + return ConcatOps[0];
> + }
>
> - unsigned NumOps = WidenVT.getVectorNumElements()/VT.getVectorNumElements();
> + // add undefs of size MaxVT until ConcatOps grows to length of WidenVT
> + unsigned NumOps =
> + WidenVT.getVectorNumElements()/MaxVT.getVectorNumElements();
> if (NumOps != ConcatEnd ) {
> - SDValue UndefVal = DAG.getUNDEF(VT);
> + SDValue UndefVal = DAG.getUNDEF(MaxVT);
> for (unsigned j = ConcatEnd; j < NumOps; ++j)
> ConcatOps[j] = UndefVal;
> }
> @@ -1379,7 +1423,7 @@
> return DAG.getNode(Opcode, dl, WidenVT, InOp);
> }
>
> - if (TLI.isTypeLegal(InWidenVT)) {
> + if (TLI.isTypeSynthesizable(InWidenVT)) {
> // Because the result and the input are different vector types, widening
> // the result could create a legal type but widening the input might make
> // it an illegal type that might lead to repeatedly splitting the input
> @@ -1521,7 +1565,7 @@
> NewInVT = EVT::getVectorVT(*DAG.getContext(), InVT, NewNumElts);
> }
>
> - if (TLI.isTypeLegal(NewInVT)) {
> + if (TLI.isTypeSynthesizable(NewInVT)) {
> // Because the result and the input are different vector types, widening
> // the result could create a legal type but widening the input might make
> // it an illegal type that might lead to repeatedly splitting the input
> @@ -1662,7 +1706,7 @@
> SatOp, CvtCode);
> }
>
> - if (TLI.isTypeLegal(InWidenVT)) {
> + if (TLI.isTypeSynthesizable(InWidenVT)) {
> // Because the result and the input are different vector types, widening
> // the result could create a legal type but widening the input might make
> // it an illegal type that might lead to repeatedly splitting the input
> @@ -1988,7 +2032,7 @@
> if (InWidenSize % Size == 0 && !VT.isVector()) {
> unsigned NewNumElts = InWidenSize / Size;
> EVT NewVT = EVT::getVectorVT(*DAG.getContext(), VT, NewNumElts);
> - if (TLI.isTypeLegal(NewVT)) {
> + if (TLI.isTypeSynthesizable(NewVT)) {
> SDValue BitOp = DAG.getNode(ISD::BIT_CONVERT, dl, NewVT, InOp);
> return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, VT, BitOp,
> DAG.getIntPtrConstant(0));
> @@ -2086,7 +2130,7 @@
> unsigned MemVTWidth = MemVT.getSizeInBits();
> if (MemVT.getSizeInBits() <= WidenEltWidth)
> break;
> - if (TLI.isTypeLegal(MemVT) && (WidenWidth % MemVTWidth) == 0 &&
> + if (TLI.isTypeSynthesizable(MemVT) && (WidenWidth % MemVTWidth) == 0 &&
> (MemVTWidth <= Width ||
> (Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
> RetVT = MemVT;
> @@ -2100,7 +2144,7 @@
> VT >= (unsigned)MVT::FIRST_VECTOR_VALUETYPE; --VT) {
> EVT MemVT = (MVT::SimpleValueType) VT;
> unsigned MemVTWidth = MemVT.getSizeInBits();
> - if (TLI.isTypeLegal(MemVT) && WidenEltVT == MemVT.getVectorElementType() &&
> + if (TLI.isTypeSynthesizable(MemVT) && WidenEltVT == MemVT.getVectorElementType() &&
> (WidenWidth % MemVTWidth) == 0 &&
> (MemVTWidth <= Width ||
> (Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
>
> Added: llvm/trunk/test/CodeGen/Generic/v-binop-widen.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Generic/v-binop-widen.ll?rev=106038&view=auto
> ==============================================================================
> --- llvm/trunk/test/CodeGen/Generic/v-binop-widen.ll (added)
> +++ llvm/trunk/test/CodeGen/Generic/v-binop-widen.ll Tue Jun 15 15:29:05 2010
> @@ -0,0 +1,8 @@
> +; RUN: llc -march=x86 %s
> +
> +%vec = type <9 x float>
> +define %vec @vecdiv( %vec %p1, %vec %p2)
> +{
> + %result = fdiv %vec %p1, %p2
> + ret %vec %result
> +}
>
> Added: llvm/trunk/test/CodeGen/Generic/v-binop-widen2.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Generic/v-binop-widen2.ll?rev=106038&view=auto
> ==============================================================================
> --- llvm/trunk/test/CodeGen/Generic/v-binop-widen2.ll (added)
> +++ llvm/trunk/test/CodeGen/Generic/v-binop-widen2.ll Tue Jun 15 15:29:05 2010
> @@ -0,0 +1,37 @@
> +; RUN: llvm-as < %s | lli
> +
> +%vec = type <6 x float>
> +
> +define %vec @vecdiv( %vec %p1, %vec %p2)
> +{
> + %result = fdiv %vec %p1, %p2
> + ret %vec %result
> +}
> +
> + at a = constant %vec < float 2.0, float 4.0, float 8.0, float 16.0, float 32.0, float 64.0 >
> + at b = constant %vec < float 2.0, float 2.0, float 2.0, float 2.0, float 2.0, float 2.0 >
> +
> +; Expected result: < 1.0, 2.0, 4.0, ..., 2.0^(n-1) >
> +; main() returns 0 if the result is expected and 1 otherwise
> +define i32 @main() nounwind {
> +entry:
> + %avec = load %vec* @a
> + %bvec = load %vec* @b
> +
> + %res = call %vec @vecdiv(%vec %avec, %vec %bvec)
> + br label %loop
> +loop:
> + %idx = phi i32 [0, %entry], [%nextInd, %looptail]
> + %expected = phi float [1.0, %entry], [%nextExpected, %looptail]
> + %elem = extractelement %vec %res, i32 %idx
> + %expcmp = fcmp oeq float %elem, %expected
> + br i1 %expcmp, label %looptail, label %return
> +looptail:
> + %nextExpected = fmul float %expected, 2.0
> + %nextInd = add i32 %idx, 1
> + %cmp = icmp slt i32 %nextInd, 6
> + br i1 %cmp, label %loop, label %return
> +return:
> + %retval = phi i32 [0, %looptail], [1, %loop]
> + ret i32 %retval
> +}
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
More information about the llvm-commits
mailing list