Changes in directory llvm/lib/Target/X86:
X86ISelLowering.cpp updated: 1.312 -> 1.313 X86ISelLowering.h updated: 1.82 -> 1.83 X86InstrSSE.td updated: 1.175 -> 1.176 --- Log message: - FCOPYSIGN custom lowering bug. Clear the sign bit of operand 0 first before or'ing in the sign bit of operand 1. - Tweaking: rather than left shift the sign bit, fp_extend operand 1 first before taking its sign bit if its type is smaller than that of operand 0. --- Diffs of the changes: (+39 -21) X86ISelLowering.cpp | 51 +++++++++++++++++++++++++++++++++++++-------------- X86ISelLowering.h | 6 ++---- X86InstrSSE.td | 3 --- 3 files changed, 39 insertions(+), 21 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.312 llvm/lib/Target/X86/X86ISelLowering.cpp:1.313 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.312 Fri Jan 5 02:32:24 2007 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Fri Jan 5 15:37:56 2007 @@ -4127,9 +4127,18 @@ } SDOperand X86TargetLowering::LowerFCOPYSIGN(SDOperand Op, SelectionDAG &DAG) { + SDOperand Op0 = Op.getOperand(0); + SDOperand Op1 = Op.getOperand(1); MVT::ValueType VT = Op.getValueType(); - MVT::ValueType SrcVT = Op.getOperand(1).getValueType(); + MVT::ValueType SrcVT = Op1.getValueType(); const Type *SrcTy = MVT::getTypeForValueType(SrcVT); + + // If second operand is smaller, extend it first. + if (MVT::getSizeInBits(SrcVT) < MVT::getSizeInBits(VT)) { + Op1 = DAG.getNode(ISD::FP_EXTEND, VT, Op1); + SrcVT = VT; + } + // First get the sign bit of second operand. std::vector<Constant*> CV; if (SrcVT == MVT::f64) { @@ -4150,8 +4159,8 @@ Ops.push_back(DAG.getEntryNode()); Ops.push_back(CPIdx); Ops.push_back(DAG.getSrcValue(NULL)); - SDOperand Mask = DAG.getNode(X86ISD::LOAD_PACK, Tys, &Ops[0], Ops.size()); - SDOperand SignBit = DAG.getNode(X86ISD::FAND, SrcVT, Op.getOperand(1), Mask); + SDOperand Mask1 = DAG.getNode(X86ISD::LOAD_PACK, Tys, &Ops[0], Ops.size()); + SDOperand SignBit = DAG.getNode(X86ISD::FAND, SrcVT, Op1, Mask1); // Shift sign bit right or left if the two operands have different types. if (MVT::getSizeInBits(SrcVT) > MVT::getSizeInBits(VT)) { @@ -4162,18 +4171,33 @@ SignBit = DAG.getNode(ISD::BIT_CONVERT, MVT::v4f32, SignBit); SignBit = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, MVT::f32, SignBit, DAG.getConstant(0, getPointerTy())); - } else if (MVT::getSizeInBits(SrcVT) < MVT::getSizeInBits(VT)) { - // Op0 is MVT::f64, Op1 is MVT::f32. - SignBit = DAG.getNode(ISD::SCALAR_TO_VECTOR, MVT::v4f32, SignBit); - SignBit = DAG.getNode(X86ISD::FSHL, MVT::v4f32, SignBit, - DAG.getConstant(32, MVT::i32)); - SignBit = DAG.getNode(ISD::BIT_CONVERT, MVT::v2f64, SignBit); - SignBit = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, MVT::f64, SignBit, - DAG.getConstant(0, getPointerTy())); } - // Or the first operand with the sign bit. - return DAG.getNode(X86ISD::FOR, VT, Op.getOperand(0), SignBit); + // Clear first operand sign bit. + CV.clear(); + if (VT == MVT::f64) { + CV.push_back(ConstantFP::get(SrcTy, BitsToDouble(~(1ULL << 63)))); + CV.push_back(ConstantFP::get(SrcTy, 0.0)); + } else { + CV.push_back(ConstantFP::get(SrcTy, BitsToFloat(~(1U << 31)))); + CV.push_back(ConstantFP::get(SrcTy, 0.0)); + CV.push_back(ConstantFP::get(SrcTy, 0.0)); + CV.push_back(ConstantFP::get(SrcTy, 0.0)); + } + CS = ConstantStruct::get(CV); + CPIdx = DAG.getConstantPool(CS, getPointerTy(), 4); + Tys.clear(); + Tys.push_back(VT); + Tys.push_back(MVT::Other); + Ops.clear(); + Ops.push_back(DAG.getEntryNode()); + Ops.push_back(CPIdx); + Ops.push_back(DAG.getSrcValue(NULL)); + SDOperand Mask2 = DAG.getNode(X86ISD::LOAD_PACK, Tys, &Ops[0], Ops.size()); + SDOperand Val = DAG.getNode(X86ISD::FAND, VT, Op0, Mask2); + + // Or the value with the sign bit. + return DAG.getNode(X86ISD::FOR, VT, Val, SignBit); } SDOperand X86TargetLowering::LowerSETCC(SDOperand Op, SelectionDAG &DAG, @@ -5032,7 +5056,6 @@ case X86ISD::FAND: return "X86ISD::FAND"; case X86ISD::FOR: return "X86ISD::FOR"; case X86ISD::FXOR: return "X86ISD::FXOR"; - case X86ISD::FSHL: return "X86ISD::FSHL"; case X86ISD::FSRL: return "X86ISD::FSRL"; case X86ISD::FILD: return "X86ISD::FILD"; case X86ISD::FILD_FLAG: return "X86ISD::FILD_FLAG"; Index: llvm/lib/Target/X86/X86ISelLowering.h diff -u llvm/lib/Target/X86/X86ISelLowering.h:1.82 llvm/lib/Target/X86/X86ISelLowering.h:1.83 --- llvm/lib/Target/X86/X86ISelLowering.h:1.82 Fri Jan 5 01:55:56 2007 +++ llvm/lib/Target/X86/X86ISelLowering.h Fri Jan 5 15:37:56 2007 @@ -43,10 +43,8 @@ /// to X86::XORPS or X86::XORPD. FXOR, - /// FSHL, FSRL - Shift a floating point value (in SSE register) by n bits - /// while shifting in 0's. These corresponds to X86::PSLLDQ or - /// X86::PSRLDQ. - FSHL, + /// FSRL - Bitwise logical right shift of floating point values. These + /// corresponds to X86::PSRLDQ. FSRL, /// FILD, FILD_FLAG - This instruction implements SINT_TO_FP with the Index: llvm/lib/Target/X86/X86InstrSSE.td diff -u llvm/lib/Target/X86/X86InstrSSE.td:1.175 llvm/lib/Target/X86/X86InstrSSE.td:1.176 --- llvm/lib/Target/X86/X86InstrSSE.td:1.175 Fri Jan 5 01:55:56 2007 +++ llvm/lib/Target/X86/X86InstrSSE.td Fri Jan 5 15:37:56 2007 @@ -31,7 +31,6 @@ [SDNPCommutative, SDNPAssociative]>; def X86fxor : SDNode<"X86ISD::FXOR", SDTFPBinOp, [SDNPCommutative, SDNPAssociative]>; -def X86fshl : SDNode<"X86ISD::FSHL", SDTX86FPShiftOp>; def X86fsrl : SDNode<"X86ISD::FSRL", SDTX86FPShiftOp>; def X86comi : SDNode<"X86ISD::COMI", SDTX86CmpTest, [SDNPHasChain, SDNPOutFlag]>; @@ -1377,8 +1376,6 @@ (v2i64 (PSLLDQri VR128:$src1, (PSxLDQ_imm imm:$src2)))>; def : Pat<(int_x86_sse2_psrl_dq VR128:$src1, imm:$src2), (v2i64 (PSRLDQri VR128:$src1, (PSxLDQ_imm imm:$src2)))>; - def : Pat<(v4f32 (X86fshl VR128:$src1, i32immSExt8:$src2)), - (v4f32 (PSLLDQri VR128:$src1, (PSxLDQ_imm imm:$src2)))>; def : Pat<(v2f64 (X86fsrl VR128:$src1, i32immSExt8:$src2)), (v2f64 (PSRLDQri VR128:$src1, (PSxLDQ_imm imm:$src2)))>; } _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits