Changeset 4241


Ignore:
Timestamp:
Oct 15, 2014, 11:43:03 AM (5 years ago)
Author:
linmengl
Message:

add @llvm.uadd.with.overflow.carryin, and the internal selectionDAG UADDE. lowering for X86 is ready.

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

Legend:

Unmodified
Added
Removed
  • parabix-LLVM/llvm_git/include/llvm/CodeGen/ISDOpcodes.h

    r4078 r4241  
    217217    /// These nodes are generated from llvm.[su]add.with.overflow intrinsics.
    218218    SADDO, UADDO,
     219
     220    // llvm.uadd.with.overflow.carryin intrinsics.
     221    UADDE,
    219222
    220223    /// Same for subtraction.
  • parabix-LLVM/llvm_git/include/llvm/IR/Intrinsics.td

    r4078 r4241  
    435435                                       [IntrNoMem]>;
    436436
     437def int_uadd_with_overflow_carryin : Intrinsic<[llvm_anyint_ty, llvm_i1_ty],
     438                                       [LLVMMatchType<0>, LLVMMatchType<0>, llvm_i1_ty],
     439                                       [IntrNoMem]>;
     440
    437441def int_ssub_with_overflow : Intrinsic<[llvm_anyint_ty, llvm_i1_ty],
    438442                                       [LLVMMatchType<0>, LLVMMatchType<0>],
  • parabix-LLVM/llvm_git/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp

    r4078 r4241  
    53225322    SDVTList VTs = DAG.getVTList(Op1.getValueType(), MVT::i1);
    53235323    setValue(&I, DAG.getNode(Op, sdl, VTs, Op1, Op2));
     5324    return nullptr;
     5325  }
     5326  case Intrinsic::uadd_with_overflow_carryin: {
     5327    SDValue Op1 = getValue(I.getArgOperand(0));
     5328    SDValue Op2 = getValue(I.getArgOperand(1));
     5329    SDValue Op3 = getValue(I.getArgOperand(2));
     5330
     5331    SDVTList VTs = DAG.getVTList(Op1.getValueType(), MVT::i1);
     5332    setValue(&I, DAG.getNode(ISD::UADDE, sdl, VTs, Op1, Op2, Op3));
    53245333    return nullptr;
    53255334  }
  • parabix-LLVM/llvm_git/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp

    r4078 r4241  
    206206  case ISD::SADDO:                      return "saddo";
    207207  case ISD::UADDO:                      return "uaddo";
     208  case ISD::UADDE:                      return "uadde";
    208209  case ISD::SSUBO:                      return "ssubo";
    209210  case ISD::USUBO:                      return "usubo";
  • parabix-LLVM/llvm_git/lib/Target/X86/X86ISelLowering.cpp

    r4136 r4241  
    16011601  // ref: this file, lowerXALUO, UADDO to X86ISD::ADD and SetCC X86::Cond_B
    16021602  setTargetDAGCombine(ISD::UADDO);
     1603  setTargetDAGCombine(ISD::UADDE);
    16031604
    16041605  // We have target-specific dag combine patterns for the following nodes:
  • parabix-LLVM/llvm_git/lib/Target/X86/X86ParabixISelLowering.cpp

    r4145 r4241  
    10291029}
    10301030
     1031static SDValue LongStreamAddition(MVT VT, SDValue V1, SDValue V2, SDValue Vcarryin, SDNodeTreeBuilder &b) {
     1032  //general logic for uadd.with.overflow.iXXX
     1033  int RegisterWidth = VT.getSizeInBits();
     1034  int f = RegisterWidth / 64;
     1035  MVT VXi64Ty = MVT::getVectorVT(MVT::i64, f);
     1036  MVT MaskTy = MVT::getIntegerVT(f);
     1037  MVT MaskVecTy = MVT::getVectorVT(MVT::i1, f);
     1038
     1039  SDValue X = b.BITCAST(V1, VXi64Ty);
     1040  SDValue Y = b.BITCAST(V2, VXi64Ty);
     1041  SDValue R = b.ADD(X, Y);
     1042
     1043  SDValue Ones = getPXOnesVector(VXi64Ty, b);
     1044
     1045  //x = hsimd<64>::signmask(X), x, y, r are all i32 type
     1046  SDValue x, y, r, bubble;
     1047  if (f == 2) {
     1048    //i128, v2i1 to i2 seems to be problematic
     1049    x = b.SignMask2x64(X);
     1050    y = b.SignMask2x64(Y);
     1051    r = b.SignMask2x64(R);
     1052    bubble = b.SignMask2x64(b.SIGN_EXTEND(b.SETCC(R, Ones, ISD::SETEQ), VXi64Ty));
     1053  }
     1054  else if (f == 4) {
     1055    //i256
     1056    x = b.SignMask4x64(X);
     1057    y = b.SignMask4x64(Y);
     1058    r = b.SignMask4x64(R);
     1059    bubble = b.SignMask4x64(b.SIGN_EXTEND(b.SETCC(R, Ones, ISD::SETEQ), VXi64Ty));
     1060  }
     1061  else
     1062  {
     1063    //i512, i1024, ..., i4096
     1064    SDValue Zero = getPXZeroVector(VXi64Ty, b);
     1065    x = b.ZERO_EXTEND(b.BITCAST(b.SETCC(X, Zero, ISD::SETLT), MaskTy), MVT::i32);
     1066    y = b.ZERO_EXTEND(b.BITCAST(b.SETCC(Y, Zero, ISD::SETLT), MaskTy), MVT::i32);
     1067    r = b.ZERO_EXTEND(b.BITCAST(b.SETCC(R, Zero, ISD::SETLT), MaskTy), MVT::i32);
     1068    bubble = b.ZERO_EXTEND(b.BITCAST(b.SETCC(R, Ones, ISD::SETEQ), MaskTy), MVT::i32);
     1069  }
     1070
     1071  SDValue carry = b.OR(b.AND(x, y), b.AND(b.OR(x, y), b.NOT(r)));
     1072
     1073  SDValue increments;
     1074  if (Vcarryin.getNode()) {
     1075    //carryin is not empty
     1076    increments = b.MatchStar(b.OR(b.ZERO_EXTEND(Vcarryin, MVT::i32), b.SHL(carry, b.Constant(1, MVT::i32))),
     1077                             bubble);
     1078  } else {
     1079    increments = b.MatchStar(b.SHL(carry, b.Constant(1, MVT::i32)), bubble);
     1080  }
     1081
     1082  SDValue carry_out = b.TRUNCATE(b.SRL(increments, b.Constant(f, MVT::i32)), MVT::i1);
     1083
     1084  SDValue spread = b.ZERO_EXTEND(b.BITCAST(b.TRUNCATE(increments, MaskTy), MaskVecTy),
     1085                                 VXi64Ty);
     1086  SDValue sum = b.BITCAST(b.ADD(R, spread), VT);
     1087
     1088  SDValue Pool[] = {sum, carry_out};
     1089  return b.MergeValues(Pool);
     1090}
     1091
     1092//Perform combine for @llvm.uadd.with.overflow
    10311093static SDValue PXPerformUADDO(SDNode *N, SelectionDAG &DAG,
    10321094                                     TargetLowering::DAGCombinerInfo &DCI,
     
    10421104    DEBUG(dbgs() << "Parabix combining: "; N->dump());
    10431105
    1044     //general logic for uadd.with.overflow.iXXX
    1045     int RegisterWidth = VT.getSizeInBits();
    1046     int f = RegisterWidth / 64;
    1047     MVT VXi64Ty = MVT::getVectorVT(MVT::i64, f);
    1048     MVT MaskTy = MVT::getIntegerVT(f);
    1049     MVT MaskVecTy = MVT::getVectorVT(MVT::i1, f);
    1050 
    1051     SDValue X = b.BITCAST(V1, VXi64Ty);
    1052     SDValue Y = b.BITCAST(V2, VXi64Ty);
    1053     SDValue R = b.ADD(X, Y);
    1054 
    1055     SDValue Ones = getPXOnesVector(VXi64Ty, b);
    1056 
    1057     //x = hsimd<64>::signmask(X), x, y, r are all i32 type
    1058     SDValue x, y, r, bubble;
    1059     if (f == 2) {
    1060       //i128, v2i1 to i2 seems to be problematic
    1061       x = b.SignMask2x64(X);
    1062       y = b.SignMask2x64(Y);
    1063       r = b.SignMask2x64(R);
    1064       bubble = b.SignMask2x64(b.SIGN_EXTEND(b.SETCC(R, Ones, ISD::SETEQ), VXi64Ty));
    1065     }
    1066     else if (f == 4) {
    1067       //i256
    1068       x = b.SignMask4x64(X);
    1069       y = b.SignMask4x64(Y);
    1070       r = b.SignMask4x64(R);
    1071       bubble = b.SignMask4x64(b.SIGN_EXTEND(b.SETCC(R, Ones, ISD::SETEQ), VXi64Ty));
    1072     }
    1073     else
    1074     {
    1075       //i512, i1024, ..., i4096
    1076       SDValue Zero = getPXZeroVector(VXi64Ty, b);
    1077       x = b.ZERO_EXTEND(b.BITCAST(b.SETCC(X, Zero, ISD::SETLT), MaskTy), MVT::i32);
    1078       y = b.ZERO_EXTEND(b.BITCAST(b.SETCC(Y, Zero, ISD::SETLT), MaskTy), MVT::i32);
    1079       r = b.ZERO_EXTEND(b.BITCAST(b.SETCC(R, Zero, ISD::SETLT), MaskTy), MVT::i32);
    1080       bubble = b.ZERO_EXTEND(b.BITCAST(b.SETCC(R, Ones, ISD::SETEQ), MaskTy), MVT::i32);
    1081     }
    1082 
    1083     SDValue carry = b.OR(b.AND(x, y), b.AND(b.OR(x, y), b.NOT(r)));
    1084     SDValue increments = b.MatchStar(b.SHL(carry, b.Constant(1, MVT::i32)), bubble);
    1085     SDValue carry_out = b.TRUNCATE(b.SRL(increments, b.Constant(f, MVT::i32)), MVT::i1);
    1086 
    1087     SDValue spread = b.ZERO_EXTEND(b.BITCAST(b.TRUNCATE(increments, MaskTy), MaskVecTy),
    1088                                    VXi64Ty);
    1089     SDValue sum = b.BITCAST(b.ADD(R, spread), VT);
    1090 
    1091     SDValue Pool[] = {sum, carry_out};
    1092     SDValue Ret = DAG.getMergeValues(Pool, dl);
     1106    SDValue Ret = LongStreamAddition(VT, V1, V2, SDValue(), b);
    10931107
    10941108    DEBUG(dbgs() << "Combined into: \n"; Ret.dumpr());
    1095 
     1109    return Ret;
     1110  }
     1111
     1112  return SDValue();
     1113}
     1114
     1115//Perform combine for @llvm.uadd.with.overflow.carryin
     1116static SDValue PXPerformUADDE(SDNode *N, SelectionDAG &DAG,
     1117                                     TargetLowering::DAGCombinerInfo &DCI,
     1118                                     const X86Subtarget *Subtarget) {
     1119  MVT VT = N->getSimpleValueType(0);
     1120  SDLoc dl(N);
     1121  SDValue V1 = N->getOperand(0);
     1122  SDValue V2 = N->getOperand(1);
     1123  SDValue Vcarryin = N->getOperand(2);
     1124  SDNodeTreeBuilder b(&DAG, dl);
     1125
     1126  if (DCI.isBeforeLegalize() &&
     1127      ((Subtarget->hasSSE2() && VT == MVT::i128) || (Subtarget->hasAVX() && VT == MVT::i256))) {
     1128    DEBUG(dbgs() << "Parabix combining: "; N->dump());
     1129
     1130    SDValue Ret = LongStreamAddition(VT, V1, V2, Vcarryin, b);
     1131
     1132    DEBUG(dbgs() << "Combined into: \n"; Ret.dumpr());
    10961133    return Ret;
    10971134  }
     
    11131150  case ISD::SRL:                return PXPerformShiftCombine(N, DAG, DCI, Subtarget);
    11141151  case ISD::UADDO:              return PXPerformUADDO(N, DAG, DCI, Subtarget);
    1115   }
    1116 
    1117   return SDValue();
    1118 }
    1119 
     1152  case ISD::UADDE:              return PXPerformUADDE(N, DAG, DCI, Subtarget);
     1153  }
     1154
     1155  return SDValue();
     1156}
     1157
  • parabix-LLVM/llvm_git/lib/Target/X86/X86ParabixISelLowering.h

    r4136 r4241  
    102102
    103103      return DAG->getNode(ISD::BUILD_VECTOR, dl, VT, Elements);
     104    }
     105
     106    SDValue MergeValues(ArrayRef<SDValue> Values) {
     107      return DAG->getMergeValues(Values, dl);
    104108    }
    105109
     
    361365      return OR(XOR(ADD(AND(M, C), C), C), M);
    362366    }
     367
    363368  };
    364369}
Note: See TracChangeset for help on using the changeset viewer.