Changeset 4136 for parabix-LLVM/llvm_git


Ignore:
Timestamp:
Sep 8, 2014, 2:23:36 PM (5 years ago)
Author:
linmengl
Message:

long stream addition for i128

Location:
parabix-LLVM/llvm_git
Files:
1 deleted
3 edited

Legend:

Unmodified
Added
Removed
  • parabix-LLVM/llvm_git/lib/Target/X86/X86ISelLowering.cpp

    r4078 r4136  
    15971597    AddPromotedToType (ISD::LOAD,  ParabixVTs[i], getFullRegisterType(ParabixVTs[i]));
    15981598  }
     1599  // Parabix: custom lowering ISD::UADDO for long stream addition.
     1600  // ref: LegalizeDAG.cpp 3693. UADDO is expanded to ADD and SetCC
     1601  // ref: this file, lowerXALUO, UADDO to X86ISD::ADD and SetCC X86::Cond_B
     1602  setTargetDAGCombine(ISD::UADDO);
    15991603
    16001604  // We have target-specific dag combine patterns for the following nodes:
  • parabix-LLVM/llvm_git/lib/Target/X86/X86ParabixISelLowering.cpp

    r4078 r4136  
    6363using namespace llvm;
    6464
    65 #define DEBUG_TYPE "x86-isel"
     65#define DEBUG_TYPE "parabix"
    6666
    6767//v32i1 => i32, v32i2 => i64, etc
     
    539539//get zero vector for parabix
    540540static SDValue getPXZeroVector(EVT VT, SDNodeTreeBuilder b) {
    541   assert(VT.isParabixVector() && "This function only lower parabix vectors");
    542 
    543541  SDValue Vec;
    544542  if (VT.isSimple() && VT.getSimpleVT().is32BitVector()) {
     
    549547  } else if (VT.isSimple() && VT.getSimpleVT().is128BitVector()) {
    550548    Vec = b.ConstantVector(MVT::v4i32, 0);
     549  } else if (VT.isSimple() && VT.getSimpleVT().is256BitVector()) {
     550    Vec = b.ConstantVector(MVT::v8i32, 0);
    551551  } else
    552552    llvm_unreachable("Unexpected vector type");
     
    556556
    557557static SDValue getPXOnesVector(EVT VT, SDNodeTreeBuilder b) {
    558   assert(VT.isParabixVector() && "This function only lower parabix vectors");
    559 
    560558  SDValue Vec;
    561559  if (VT.isSimple() && VT.getSimpleVT().is32BitVector()) {
     
    566564  } else if (VT.isSimple() && VT.getSimpleVT().is128BitVector()) {
    567565    Vec = b.ConstantVector(MVT::v4i32, -1);
     566  } else if (VT.isSimple() && VT.getSimpleVT().is256BitVector()) {
     567    Vec = b.ConstantVector(MVT::v8i32, -1);
    568568  } else
    569569    llvm_unreachable("Unexpected vector type");
     
    731731SDValue X86TargetLowering::LowerParabixOperation(SDValue Op, SelectionDAG &DAG) const {
    732732  //NEED: setOperationAction in target specific lowering (X86ISelLowering.cpp)
    733   dbgs() << "Parabix Lowering:" << "\n"; Op.dump();
     733  DEBUG(dbgs() << "Parabix Lowering:" << "\n"; Op.dump());
    734734
    735735  //Only resetOperations for the first time.
     
    779779    //v128i1 (select v128i1, v128i1, v128i1) can be combined into logical ops
    780780    if (MaskTy == MVT::v128i1 && VT == MVT::v128i1) {
    781       dbgs() << "Combining select v128i1 \n";
     781      DEBUG(dbgs() << "Combining select v128i1 \n");
    782782      return b.IFH1(Mask, N->getOperand(0), N->getOperand(1));
    783783   }
     
    848848  if (Subtarget->hasSSE2() && VT == MVT::v16i8 && isPackLowMask(SVOp) &&
    849849      V1.getOpcode() != ISD::UNDEF && V2.getOpcode() != ISD::UNDEF) {
    850     dbgs() << "Parabix combine: \n";
    851     N->dumpr();
     850    DEBUG(dbgs() << "Parabix combine: \n"; N->dumpr());
    852851
    853852    //00000000111111110000000011111111
     
    870869  if (Subtarget->hasSSE2() && VT == MVT::v16i8 && isPackHighMask(SVOp) &&
    871870      V1.getOpcode() != ISD::UNDEF && V2.getOpcode() != ISD::UNDEF) {
    872     dbgs() << "Parabix combine: \n";
    873     N->dumpr();
     871    DEBUG(dbgs() << "Parabix combine: \n"; N->dumpr());
    874872
    875873    SDValue Cst = b.Constant(8, MVT::i16);
     
    892890      (isPackLowMask(SVOp) || isPackHighMask(SVOp)) &&
    893891      (VT == MVT::v32i4 || VT == MVT::v64i2 || VT == MVT::v128i1)) {
    894     dbgs() << "Parabix combine: \n";
    895     N->dumpr();
     892    DEBUG(dbgs() << "Parabix combine: \n"; N->dumpr());
    896893
    897894    std::string Mask;
     
    10141011
    10151012    if (N->getOpcode() == ISD::SHL) {
    1016       dbgs() << "Parabix combining: ";
    1017       N->dump();
     1013      DEBUG(dbgs() << "Parabix combining: "; N->dump());
    10181014
    10191015      SDValue R = b.AND(b.SHL(imm, b.BITCAST(V1, I32VecType)),
     
    10221018    }
    10231019    else if (N->getOpcode() == ISD::SRL) {
    1024       dbgs() << "Parabix combining: ";
    1025       N->dump();
     1020      DEBUG(dbgs() << "Parabix combining: "; N->dump());
    10261021
    10271022      SDValue R = b.AND(b.SRL(imm, b.BITCAST(V1, I32VecType)),
     
    10291024      return b.BITCAST(R, VT);
    10301025    }
     1026  }
     1027
     1028  return SDValue();
     1029}
     1030
     1031static SDValue PXPerformUADDO(SDNode *N, SelectionDAG &DAG,
     1032                                     TargetLowering::DAGCombinerInfo &DCI,
     1033                                     const X86Subtarget *Subtarget) {
     1034  MVT VT = N->getSimpleValueType(0);
     1035  SDLoc dl(N);
     1036  SDValue V1 = N->getOperand(0);
     1037  SDValue V2 = N->getOperand(1);
     1038  SDNodeTreeBuilder b(&DAG, dl);
     1039
     1040  if (DCI.isBeforeLegalize() && Subtarget->hasSSE2() && VT == MVT::i128) {
     1041    DEBUG(dbgs() << "Parabix combining: "; N->dump());
     1042
     1043    //general logic for uadd.with.overflow.iXXX
     1044    int RegisterWidth = VT.getSizeInBits();
     1045    int f = RegisterWidth / 64;
     1046    MVT VXi64Ty = MVT::getVectorVT(MVT::i64, f);
     1047    MVT MaskTy = MVT::getIntegerVT(f);
     1048    MVT MaskVecTy = MVT::getVectorVT(MVT::i1, f);
     1049
     1050    SDValue X = b.BITCAST(V1, VXi64Ty);
     1051    SDValue Y = b.BITCAST(V2, VXi64Ty);
     1052    SDValue R = b.ADD(X, Y);
     1053
     1054    SDValue Ones = getPXOnesVector(VXi64Ty, b);
     1055
     1056    //x = hsimd<64>::signmask(X), x, y, r are all i32 type
     1057    SDValue x, y, r;
     1058    if (f == 2) {
     1059      //i128, v2i1 to i2 seems to be problematic
     1060      x = b.SignMask2x64(X);
     1061      y = b.SignMask2x64(Y);
     1062      r = b.SignMask2x64(R);
     1063    }
     1064    else if (f == 4) {
     1065      //i256
     1066      x = b.SignMask4x64(X);
     1067      y = b.SignMask4x64(Y);
     1068      r = b.SignMask4x64(R);
     1069    }
     1070    else
     1071    {
     1072      //i512, i1024, ..., i4096
     1073      SDValue Zero = getPXZeroVector(VXi64Ty, b);
     1074      x = b.ZERO_EXTEND(b.BITCAST(b.SETCC(X, Zero, ISD::SETLT), MaskTy), MVT::i32);
     1075      y = b.ZERO_EXTEND(b.BITCAST(b.SETCC(Y, Zero, ISD::SETLT), MaskTy), MVT::i32);
     1076      r = b.ZERO_EXTEND(b.BITCAST(b.SETCC(R, Zero, ISD::SETLT), MaskTy), MVT::i32);
     1077    }
     1078
     1079    SDValue carry = b.OR(b.AND(x, y), b.AND(b.OR(x, y), b.NOT(r)));
     1080    SDValue bubble = b.ZERO_EXTEND(b.BITCAST(b.SETCC(R, Ones, ISD::SETEQ), MaskTy), MVT::i32);
     1081
     1082    SDValue increments = b.MatchStar(b.SHL(carry, b.Constant(1, MVT::i32)), bubble);
     1083    SDValue carry_out = b.TRUNCATE(b.SRL(increments, b.Constant(f, MVT::i32)), MVT::i1);
     1084
     1085    SDValue spread = b.ZERO_EXTEND(b.BITCAST(b.TRUNCATE(increments, MaskTy), MaskVecTy),
     1086                                   VXi64Ty);
     1087    SDValue sum = b.BITCAST(b.ADD(R, spread), VT);
     1088
     1089    SDValue Pool[] = {sum, carry_out};
     1090    SDValue Ret = DAG.getMergeValues(Pool, dl);
     1091
     1092    DEBUG(dbgs() << "Combined into: \n"; Ret.dumpr());
     1093
     1094    return Ret;
    10311095  }
    10321096
     
    10461110  case ISD::SHL:
    10471111  case ISD::SRL:                return PXPerformShiftCombine(N, DAG, DCI, Subtarget);
    1048   }
    1049 
    1050   return SDValue();
    1051 }
    1052 
     1112  case ISD::UADDO:              return PXPerformUADDO(N, DAG, DCI, Subtarget);
     1113  }
     1114
     1115  return SDValue();
     1116}
     1117
  • parabix-LLVM/llvm_git/lib/Target/X86/X86ParabixISelLowering.h

    r4078 r4136  
    150150    }
    151151
     152    SDValue ADD(SDValue A, SDValue B) {
     153      MVT VT = A.getSimpleValueType();
     154      return DAG->getNode(ISD::ADD, dl, VT, A, B);
     155    }
     156
    152157    SDValue AND(SDValue A, SDValue B) {
    153158      MVT VT = A.getSimpleValueType();
     
    245250
    246251      return SRL(A, BUILD_VECTOR(VT, Pool));
     252    }
     253
     254    //C can be ISD::SETNE, ISD::SETLT, etc.
     255    SDValue SETCC(SDValue A, SDValue B, ISD::CondCode C) {
     256      MVT OpVT = A.getSimpleValueType();
     257      MVT VT = MVT::getVectorVT(MVT::i1, OpVT.getVectorNumElements());
     258
     259      return DAG->getNode(ISD::SETCC, dl, VT, A, B, DAG->getCondCode(C));
    247260    }
    248261
     
    281294    }
    282295
     296    //X86 specific function
    283297    SDValue PEXT64(SDValue A, SDValue B) {
    284298      assert(A.getSimpleValueType() == MVT::i64 &&
     
    290304                              DAG->getConstant(Intrinsic::x86_bmi_pext_64, MVT::i32),
    291305                              A,B);
     306      return V;
     307    }
     308
     309    //X86 specific function
     310    //Collect sign bit of each 64-bit field into i32
     311    SDValue SignMask2x64(SDValue A) {
     312      assert(A.getSimpleValueType().getSizeInBits() == 128 &&
     313             "SignMask get wrong sized type.");
     314      if (A.getSimpleValueType() != MVT::v2f64)
     315        A = BITCAST(A, MVT::v2f64);
     316
     317      SDValue V = DAG->getNode(ISD::INTRINSIC_WO_CHAIN, dl,
     318                               MVT::i32,
     319                               DAG->getConstant(Intrinsic::x86_sse2_movmsk_pd, MVT::i32),
     320                               A);
     321      return V;
     322    }
     323
     324    //X86 specific function
     325    //Collect sign bit of each 64-bit field into i32
     326    SDValue SignMask4x64(SDValue A) {
     327      assert(A.getSimpleValueType().getSizeInBits() == 256 &&
     328             "SignMask get wrong sized type.");
     329      if (A.getSimpleValueType() != MVT::v4f64)
     330        A = BITCAST(A, MVT::v4f64);
     331
     332      SDValue V = DAG->getNode(ISD::INTRINSIC_WO_CHAIN, dl,
     333                               MVT::i32,
     334                               DAG->getConstant(Intrinsic::x86_avx_movmsk_pd_256, MVT::i32),
     335                               A);
    292336      return V;
    293337    }
     
    311355      return BITCAST(R, VT);
    312356    }
     357
     358    SDValue MatchStar(SDValue M, SDValue C) {
     359      assert(M.getSimpleValueType().SimpleTy == C.getSimpleValueType().SimpleTy &&
     360             "MatchStar operands of different type");
     361      return OR(XOR(ADD(AND(M, C), C), C), M);
     362    }
    313363  };
    314364}
Note: See TracChangeset for help on using the changeset viewer.