Changeset 4295 for parabix-LLVM


Ignore:
Timestamp:
Nov 6, 2014, 6:15:30 PM (5 years ago)
Author:
linmengl
Message:

sync with git repo: long integer shifting.

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

Legend:

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

    r4241 r4295  
    965965
    966966static bool isImmediateShiftingMask(SDValue Mask, int &imm) {
     967  if (isa<ConstantSDNode>(Mask)) {
     968    // immediate shift for long integer. e.g. i128, i256
     969    imm = (int) (cast<ConstantSDNode>(Mask)->getZExtValue());
     970    return true;
     971  }
     972
    967973  if (Mask.getOpcode() != ISD::BUILD_VECTOR)
    968974    return false;
     
    10261032  }
    10271033
     1034  // long integer shift for MVT::i128
     1035  if (Subtarget->hasSSE2() && VT == MVT::i128 && isImmediateShiftingMask(V2, imm)) {
     1036    if (imm % 8 == 0)
     1037    {
     1038      // for 128 bit SIMD register, there is pslldq and psrldq intrinsic
     1039      if (N->getOpcode() == ISD::SHL)
     1040      {
     1041        SDValue B = b.ShiftLeftInByte(V1, imm / 8);
     1042        return b.BITCAST(B, VT);
     1043      }
     1044      else if (N->getOpcode() == ISD::SRL)
     1045      {
     1046        return b.BITCAST(b.ShiftRightLogicInByte(V1, imm / 8), VT);
     1047      }
     1048
     1049      return SDValue();
     1050    }
     1051
     1052    if (N->getOpcode() == ISD::SHL) {
     1053      DEBUG(dbgs() << "Parabix combining: "; N->dump());
     1054
     1055      if (imm >= 64) {
     1056        int mask[] = {2, 0};
     1057        SDValue Shift64 = b.VECTOR_SHUFFLE(b.BITCAST(V1, MVT::v2i64),
     1058                                           b.ConstantVector(MVT::v2i64, 0), mask);
     1059        if (imm > 64) Shift64 = b.SHL(imm - 64, Shift64);
     1060        return b.BITCAST(Shift64, VT);
     1061      }
     1062      else {
     1063        //Double shift
     1064        SDValue ShiftField = b.SHL(imm, b.BITCAST(V1, MVT::v2i64));
     1065        SDValue ShiftInPart = b.SRL(64 - imm, b.BITCAST(V1, MVT::v2i64));
     1066        int mask[] = {2, 0};
     1067        ShiftInPart = b.VECTOR_SHUFFLE(ShiftInPart, b.ConstantVector(MVT::v2i64, 0), mask);
     1068        SDValue R = b.OR(ShiftInPart, ShiftField);
     1069
     1070        return b.BITCAST(R, VT);
     1071      }
     1072    }
     1073    else if (N->getOpcode() == ISD::SRL) {
     1074      DEBUG(dbgs() << "Parabix combining: "; N->dump());
     1075
     1076      if (imm >= 64) {
     1077        int mask[] = {3, 0};
     1078        SDValue Shift64 = b.VECTOR_SHUFFLE(b.ConstantVector(MVT::v2i64, 0),
     1079                                           b.BITCAST(V1, MVT::v2i64), mask);
     1080        if (imm > 64) Shift64 = b.SRL(imm - 64, Shift64);
     1081        return b.BITCAST(Shift64, VT);
     1082      }
     1083      else {
     1084        //Double shift
     1085        SDValue ShiftField = b.SRL(imm, b.BITCAST(V1, MVT::v2i64));
     1086        SDValue ShiftInPart = b.SHL(64 - imm, b.BITCAST(V1, MVT::v2i64));
     1087        int mask[] = {1, 2};
     1088        ShiftInPart = b.VECTOR_SHUFFLE(ShiftInPart, b.ConstantVector(MVT::v2i64, 0), mask);
     1089        SDValue R = b.OR(ShiftInPart, ShiftField);
     1090
     1091        return b.BITCAST(R, VT);
     1092      }
     1093    }
     1094  }
     1095
    10281096  return SDValue();
    10291097}
     
    10821150  SDValue carry_out = b.TRUNCATE(b.SRL(increments, b.Constant(f, MVT::i32)), MVT::i1);
    10831151
    1084   SDValue spread = b.ZERO_EXTEND(b.BITCAST(b.TRUNCATE(increments, MaskTy), MaskVecTy),
    1085                                  VXi64Ty);
     1152  SDValue spread;
     1153
     1154  if (f == 2) {
     1155    // <2 x i1> increments to <2 x i64>
     1156    SDValue spreadV2I16 = b.BITCAST(b.AND(b.MUL(increments, b.Constant(0x8001, MVT::i32)),
     1157                                          b.Constant(0x10001, MVT::i32)), MVT::v2i16);
     1158    spread = b.ZERO_EXTEND(spreadV2I16, VXi64Ty);
     1159  }
     1160  else if (f == 4) {
     1161    SDValue increments64 = b.ZERO_EXTEND(increments, MVT::i64);
     1162    SDValue spreadV4I16 = b.BITCAST(b.AND(b.MUL(increments64,
     1163                                                b.Constant(0x0000200040008001ull, MVT::i64)),
     1164                                          b.Constant(0x0001000100010001ull, MVT::i64)),
     1165                                    MVT::v4i16);
     1166    spread = b.ZERO_EXTEND(spreadV4I16, VXi64Ty);
     1167  }
     1168  else
     1169  {
     1170    // calc spread with zero extend: e.g. <4 x i1> to <4 x i64>
     1171    spread = b.ZERO_EXTEND(b.BITCAST(b.TRUNCATE(increments, MaskTy), MaskVecTy), VXi64Ty);
     1172  }
    10861173  SDValue sum = b.BITCAST(b.ADD(R, spread), VT);
    10871174
     
    11371224}
    11381225
     1226static SDValue PXPerformLogic(SDNode *N, SelectionDAG &DAG,
     1227                                     TargetLowering::DAGCombinerInfo &DCI,
     1228                                     const X86Subtarget *Subtarget) {
     1229  MVT VT = N->getSimpleValueType(0);
     1230  SDLoc dl(N);
     1231  SDValue V1 = N->getOperand(0);
     1232  SDValue V2 = N->getOperand(1);
     1233  SDNodeTreeBuilder b(&DAG, dl);
     1234
     1235  assert(((N->getOpcode() == ISD::OR) || (N->getOpcode() == ISD::AND) ||
     1236          (N->getOpcode() == ISD::XOR)) &&
     1237         "PXPerformLogic only works for AND / OR / XOR");
     1238
     1239  if (N->getOpcode() == ISD::OR && VT == MVT::i128 &&
     1240     ((V1.getOpcode() == ISD::SHL && V2.getOpcode() == ISD::SRL) ||
     1241      (V1.getOpcode() == ISD::SRL && V2.getOpcode() == ISD::SHL))) {
     1242    //possibly its advance with carry
     1243    //now check if the shl amount + shr amount is 128
     1244    if (V1.getOpcode() != ISD::SHL) {
     1245      std::swap(V1, V2);
     1246    }
     1247
     1248    int immLeft, immRight;
     1249    if (isImmediateShiftingMask(V1.getOperand(1), immLeft) &&
     1250        isImmediateShiftingMask(V2.getOperand(1), immRight))
     1251    {
     1252      if (immLeft + immRight == 128) {
     1253        //finally, it is advance with carry
     1254        SDValue A = b.BITCAST(V1.getOperand(0), MVT::v2i64);
     1255        SDValue B = b.BITCAST(V2.getOperand(0), MVT::v2i64);
     1256
     1257        int pool[] = {1, 2};
     1258        SDValue C = b.VECTOR_SHUFFLE(B, A, pool);
     1259        if (immLeft < 64) {
     1260          SDValue D = b.SHL(immLeft, A);
     1261          SDValue E = b.SRL(64 - immLeft, C);
     1262          SDValue R = b.OR(D, E);
     1263          return b.BITCAST(R, VT);
     1264        }
     1265        else
     1266        {
     1267          SDValue D = b.SHL(immLeft - 64, C);
     1268          SDValue E = b.SRL(128 - immLeft, B);
     1269          SDValue R = b.OR(D, E);
     1270          return b.BITCAST(R, VT);
     1271        }
     1272      }
     1273    }
     1274  }
     1275
     1276  if (VT == MVT::i128 && Subtarget->hasSSE2()) {
     1277    return b.BITCAST(DAG.getNode(N->getOpcode(), dl, MVT::v2i64,
     1278                                 b.BITCAST(V1, MVT::v2i64),
     1279                                 b.BITCAST(V2, MVT::v2i64)), VT);
     1280  }
     1281  else if (VT == MVT::i256 && Subtarget->hasAVX2()) {
     1282    return b.BITCAST(DAG.getNode(N->getOpcode(), dl, MVT::v4i64,
     1283                                 b.BITCAST(V1, MVT::v4i64),
     1284                                 b.BITCAST(V2, MVT::v4i64)), VT);
     1285  }
     1286
     1287  return SDValue();
     1288}
     1289
    11391290SDValue X86TargetLowering::PerformParabixDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const
    11401291{
     
    11511302  case ISD::UADDO:              return PXPerformUADDO(N, DAG, DCI, Subtarget);
    11521303  case ISD::UADDE:              return PXPerformUADDE(N, DAG, DCI, Subtarget);
    1153   }
    1154 
    1155   return SDValue();
    1156 }
    1157 
     1304  case ISD::AND:
     1305  case ISD::XOR:
     1306  case ISD::OR:                 return PXPerformLogic(N, DAG, DCI, Subtarget);
     1307  }
     1308
     1309  return SDValue();
     1310}
     1311
  • parabix-LLVM/llvm_git/lib/Target/X86/X86ParabixISelLowering.h

    r4241 r4295  
    6060    }
    6161
    62     SDValue Constant(int Num, MVT NumType = MVT::i32) {
     62    SDValue Constant(uint64_t Num, MVT NumType = MVT::i32) {
    6363      return DAG->getConstant(Num, NumType);
    6464    }
     
    341341    }
    342342
     343    //X86 Specific function
     344    //Shift left the i128 or i256 operand A by immInByte * 8 bits.
     345    //Return v2i64 for i128
     346    SDValue ShiftLeftInByte(SDValue A, int immInByte) {
     347      MVT VT = A.getSimpleValueType();
     348      assert((VT.getSizeInBits() == 128 ||
     349              VT.getSizeInBits() == 256) &&
     350             "Shift left in bytes get wrong sized input.");
     351
     352      if (VT.getSizeInBits() == 128 && VT != MVT::v2i64)
     353        A = BITCAST(A, MVT::v2i64);
     354
     355      SDValue B = DAG->getNode(ISD::INTRINSIC_WO_CHAIN, dl,
     356                               MVT::v2i64,
     357                               DAG->getConstant(Intrinsic::x86_sse2_psll_dq, MVT::i32),
     358                               A, Constant(immInByte * 8, MVT::i32));
     359      return B;
     360    }
     361
     362    //X86 Specific function
     363    //Shift right the i128 or i256 operand A by immInByte * 8 bits
     364    //Return v2i64 for i128
     365    SDValue ShiftRightLogicInByte(SDValue A, int immInByte) {
     366      MVT VT = A.getSimpleValueType();
     367      assert((VT.getSizeInBits() == 128 ||
     368              VT.getSizeInBits() == 256) &&
     369             "Shift right logic in bytes get wrong sized input.");
     370
     371      if (VT.getSizeInBits() == 128 && VT != MVT::v2i64)
     372        A = BITCAST(A, MVT::v2i64);
     373
     374      SDValue B = DAG->getNode(ISD::INTRINSIC_WO_CHAIN, dl,
     375                               MVT::v2i64,
     376                               DAG->getConstant(Intrinsic::x86_sse2_psrl_dq, MVT::i32),
     377                               A, Constant(immInByte * 8, MVT::i32));
     378      return B;
     379    }
     380
     381
     382
    343383    //simd<1>::ifh
    344384    //just like SELECT, but for v128i1 vectors. if Mask[i] == 1, A[i] is chosen.
  • parabix-LLVM/llvm_git/test/Parabix/i256.ll

    r4078 r4295  
    2929}
    3030
     31declare {i256, i1} @llvm.uadd.with.overflow.i256(i256 %a, i256 %b)
     32
     33define <4 x i64> @uadd_with_overflow_i256(<4 x i64> %a, <4 x i64> %b) {
     34entry:
     35  ;CHECK-LABEL: uadd_with_overflow_i256
     36  %aa = bitcast <4 x i64> %a to i256
     37  %bb = bitcast <4 x i64> %b to i256
     38
     39  %res = call {i256, i1} @llvm.uadd.with.overflow.i256(i256 %aa, i256 %bb)
     40  %sum = extractvalue {i256, i1} %res, 0
     41  %obit = extractvalue {i256, i1} %res, 1
     42  %obit1 = zext i1 %obit to i32
     43
     44  %sum1 = bitcast i256 %sum to <8 x i32>
     45  %sum2 = insertelement <8 x i32> %sum1, i32 %obit1, i32 1
     46  %sum3 = bitcast <8 x i32> %sum2 to <4 x i64>
     47
     48  ret <4 x i64> %sum3
     49}
Note: See TracChangeset for help on using the changeset viewer.