[llvm-commits] [llvm] r57926 - in /llvm/trunk/lib: CodeGen/SelectionDAG/LegalizeDAG.cpp Target/X86/X86ISelLowering.cpp Target/X86/X86ISelLowering.h

Evan Cheng evan.cheng at apple.com
Tue Oct 21 14:58:03 PDT 2008


On Oct 21, 2008, at 1:50 PM, Dale Johannesen wrote:

> Author: johannes
> Date: Tue Oct 21 15:50:01 2008
> New Revision: 57926
>
> URL: http://llvm.org/viewvc/llvm-project?rev=57926&view=rev
> Log:
> Add an SSE2 algorithm for uint64->f64 conversion.
> The same one Apple gcc uses, faster.  Also gets the
> extreme case in gcc.c-torture/execute/ieee/rbug.c
> correct which we weren't before; this is not
> sufficient to get the test to pass though, there
> is another bug.
>

Awesome!

>
> +SDValue X86TargetLowering::LowerUINT_TO_FP(SDValue Op, SelectionDAG  
> &DAG) {
> +  MVT SrcVT = Op.getOperand(0).getValueType();
> +  assert(SrcVT.getSimpleVT() == MVT::i64 && "Unknown UINT_TO_FP to  
> lower!");
> +
> +  // We only handle SSE2 f64 target here; caller can handle the rest.
> +  if (Op.getValueType() != MVT::f64 || !X86ScalarSSEf64)
> +    return SDValue();
> +
> +  // Get a XMM-vector-sized stack slot.
> +  unsigned Size = 128/8;
> +  MachineFunction &MF = DAG.getMachineFunction();
> +  int SSFI = MF.getFrameInfo()->CreateStackObject(Size, Size);
> +  SDValue StackSlot = DAG.getFrameIndex(SSFI, getPointerTy());
> +
> +  // Build some magic constants.

Can you add comments describing the algorithm? I can't figure out  
what's going on here.

Thanks,

Evan

>
> +  std::vector<Constant*>CV0;
> +  CV0.push_back(ConstantInt::get(APInt(32, 0x45300000)));
> +  CV0.push_back(ConstantInt::get(APInt(32, 0x43300000)));
> +  CV0.push_back(ConstantInt::get(APInt(32, 0)));
> +  CV0.push_back(ConstantInt::get(APInt(32, 0)));
> +  Constant *C0 = ConstantVector::get(CV0);
> +  SDValue CPIdx0 = DAG.getConstantPool(C0, getPointerTy(), 4);
> +
> +  std::vector<Constant*>CV1;
> +  CV1.push_back(ConstantFP::get(APFloat(APInt(64,  
> 0x4530000000000000ULL))));
> +  CV1.push_back(ConstantFP::get(APFloat(APInt(64,  
> 0x4330000000000000ULL))));
> +  Constant *C1 = ConstantVector::get(CV1);
> +  SDValue CPIdx1 = DAG.getConstantPool(C1, getPointerTy(), 4);
> +
> +  SmallVector<SDValue, 4> MaskVec;
> +  MaskVec.push_back(DAG.getConstant(0, MVT::i32));
> +  MaskVec.push_back(DAG.getConstant(4, MVT::i32));
> +  MaskVec.push_back(DAG.getConstant(1, MVT::i32));
> +  MaskVec.push_back(DAG.getConstant(5, MVT::i32));
> +  SDValue UnpcklMask = DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,  
> &MaskVec[0],
> +                                   MaskVec.size());
> +  SmallVector<SDValue, 4> MaskVec2;
> +  MaskVec2.push_back(DAG.getConstant(1, MVT::i64));
> +  MaskVec2.push_back(DAG.getConstant(0, MVT::i64));
> +  SDValue ShufMask = DAG.getNode(ISD::BUILD_VECTOR, MVT::v2i64,  
> &MaskVec2[0],
> +                                 MaskVec2.size());
> +
> +  SDValue XR1 = DAG.getNode(ISD::SCALAR_TO_VECTOR, MVT::v4i32,
> +                            Op.getOperand(0).getOperand(1));
> +  SDValue XR2 = DAG.getNode(ISD::SCALAR_TO_VECTOR, MVT::v4i32,
> +                            Op.getOperand(0).getOperand(0));
> +  SDValue Unpck1 = DAG.getNode(ISD::VECTOR_SHUFFLE, MVT::v4i32,
> +                                XR1, XR2, UnpcklMask);
> +  SDValue CLod0 = DAG.getLoad(MVT::v4i32, DAG.getEntryNode(), CPIdx0,
> +                         PseudoSourceValue::getConstantPool(), 0,  
> false, 16);
> +  SDValue Unpck2 = DAG.getNode(ISD::VECTOR_SHUFFLE, MVT::v4i32,
> +                                Unpck1, CLod0, UnpcklMask);
> +  SDValue XR2F = DAG.getNode(ISD::BIT_CONVERT, MVT::v2f64, Unpck2);
> +  SDValue CLod1 = DAG.getLoad(MVT::v2f64, CLod0.getValue(1), CPIdx1,
> +                         PseudoSourceValue::getConstantPool(), 0,  
> false, 16);
> +  SDValue Sub = DAG.getNode(ISD::FSUB, MVT::v2f64, XR2F, CLod1);
> +  // Add the halves; easiest way is to swap them into another reg  
> first.
> +  SDValue Shuf = DAG.getNode(ISD::VECTOR_SHUFFLE, MVT::v2f64,
> +                             Sub, Sub, ShufMask);
> +  SDValue Add = DAG.getNode(ISD::FADD, MVT::v2f64, Shuf, Sub);
> +  return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, MVT::f64, Add,
> +                     DAG.getIntPtrConstant(0));
> +}
> +
> std::pair<SDValue,SDValue> X86TargetLowering::
> FP_TO_SINTHelper(SDValue Op, SelectionDAG &DAG) {
>   assert(Op.getValueType().getSimpleVT() <= MVT::i64 &&
> @@ -6184,6 +6250,7 @@
>   case ISD::SRA_PARTS:
>   case ISD::SRL_PARTS:          return LowerShift(Op, DAG);
>   case ISD::SINT_TO_FP:         return LowerSINT_TO_FP(Op, DAG);
> +  case ISD::UINT_TO_FP:         return LowerUINT_TO_FP(Op, DAG);
>   case ISD::FP_TO_SINT:         return LowerFP_TO_SINT(Op, DAG);
>   case ISD::FABS:               return LowerFABS(Op, DAG);
>   case ISD::FNEG:               return LowerFNEG(Op, DAG);
>
> Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.h?rev=57926&r1=57925&r2=57926&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/lib/Target/X86/X86ISelLowering.h (original)
> +++ llvm/trunk/lib/Target/X86/X86ISelLowering.h Tue Oct 21 15:50:01  
> 2008
> @@ -558,6 +558,7 @@
>     SDValue LowerExternalSymbol(SDValue Op, SelectionDAG &DAG);
>     SDValue LowerShift(SDValue Op, SelectionDAG &DAG);
>     SDValue LowerSINT_TO_FP(SDValue Op, SelectionDAG &DAG);
> +    SDValue LowerUINT_TO_FP(SDValue Op, SelectionDAG &DAG);
>     SDValue LowerFP_TO_SINT(SDValue Op, SelectionDAG &DAG);
>     SDValue LowerFABS(SDValue Op, SelectionDAG &DAG);
>     SDValue LowerFNEG(SDValue Op, SelectionDAG &DAG);
>
>
> _______________________________________________
> 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