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

long stream addition for i128

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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
Note: See TracChangeset for help on using the changeset viewer.