diff options
| author | Sanjay Patel <spatel@rotateright.com> | 2016-09-23 23:17:29 +0000 |
|---|---|---|
| committer | Sanjay Patel <spatel@rotateright.com> | 2016-09-23 23:17:29 +0000 |
| commit | 0b36337d614531aee62f2ca885805bbcb1645ce0 (patch) | |
| tree | c45f382415bb046ce00e5640fc88eb3c0853a9c6 /llvm/lib | |
| parent | 100f99a94c8388419edec8141c0038d9313efbce (diff) | |
| download | bcm5719-llvm-0b36337d614531aee62f2ca885805bbcb1645ce0.tar.gz bcm5719-llvm-0b36337d614531aee62f2ca885805bbcb1645ce0.zip | |
[x86] fix FCOPYSIGN lowering to create constants instead of ConstantPool loads
This is similar to:
https://reviews.llvm.org/rL279958
By not prematurely lowering to loads, we should be able to more easily eliminate
the 'or' with zero instructions seen in copysign-constant-magnitude.ll.
We should also be able to extend this code to handle vectors.
llvm-svn: 282312
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Target/X86/X86ISelLowering.cpp | 65 |
1 files changed, 22 insertions, 43 deletions
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index ce4c2aee8d1..95f71eb2f88 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -14633,28 +14633,22 @@ static SDValue LowerFABSorFNEG(SDValue Op, SelectionDAG &DAG) { } static SDValue LowerFCOPYSIGN(SDValue Op, SelectionDAG &DAG) { - const TargetLowering &TLI = DAG.getTargetLoweringInfo(); - LLVMContext *Context = DAG.getContext(); SDValue Mag = Op.getOperand(0); SDValue Sign = Op.getOperand(1); SDLoc dl(Op); - MVT VT = Op.getSimpleValueType(); - MVT SignVT = Sign.getSimpleValueType(); - bool IsF128 = (VT == MVT::f128); // If the sign operand is smaller, extend it first. - if (SignVT.bitsLT(VT)) { + MVT VT = Op.getSimpleValueType(); + if (Sign.getSimpleValueType().bitsLT(VT)) Sign = DAG.getNode(ISD::FP_EXTEND, dl, VT, Sign); - SignVT = VT; - } + // And if it is bigger, shrink it first. - if (SignVT.bitsGT(VT)) { + if (Sign.getSimpleValueType().bitsGT(VT)) Sign = DAG.getNode(ISD::FP_ROUND, dl, VT, Sign, DAG.getIntPtrConstant(1, dl)); - SignVT = VT; - } // At this point the operands and the result should have the same // type, and that won't be f80 since that is not custom lowered. + bool IsF128 = (VT == MVT::f128); assert((VT == MVT::f64 || VT == MVT::f32 || IsF128) && "Unexpected type in LowerFCOPYSIGN"); @@ -14663,61 +14657,46 @@ static SDValue LowerFCOPYSIGN(SDValue Op, SelectionDAG &DAG) { (IsF128 ? APFloat::IEEEquad : APFloat::IEEEsingle); const unsigned SizeInBits = VT.getSizeInBits(); - SmallVector<Constant *, 4> CV( - VT == MVT::f64 ? 2 : (IsF128 ? 1 : 4), - ConstantFP::get(*Context, APFloat(Sem, APInt(SizeInBits, 0)))); + // Perform all logic operations as 16-byte vectors because there are no + // scalar FP logic instructions in SSE. + MVT LogicVT = + (VT == MVT::f64) ? MVT::v2f64 : (IsF128 ? MVT::f128 : MVT::v4f32); + SDValue SignMask = DAG.getConstantFP( + APFloat(Sem, APInt::getSignBit(SizeInBits)), dl, LogicVT); // First, clear all bits but the sign bit from the second operand (sign). - CV[0] = ConstantFP::get(*Context, - APFloat(Sem, APInt::getSignBit(SizeInBits))); - Constant *C = ConstantVector::get(CV); - auto PtrVT = TLI.getPointerTy(DAG.getDataLayout()); - SDValue CPIdx = DAG.getConstantPool(C, PtrVT, 16); - - // Perform all logic operations as 16-byte vectors because there are no - // scalar FP logic instructions in SSE. This allows load folding of the - // constants into the logic instructions. - MVT LogicVT = (VT == MVT::f64) ? MVT::v2f64 : (IsF128 ? MVT::f128 : MVT::v4f32); - SDValue SignMask = - DAG.getLoad(LogicVT, dl, DAG.getEntryNode(), CPIdx, - MachinePointerInfo::getConstantPool(DAG.getMachineFunction()), - /* Alignment = */ 16); if (!IsF128) Sign = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, LogicVT, Sign); SDValue SignBit = DAG.getNode(X86ISD::FAND, dl, LogicVT, Sign, SignMask); // Next, clear the sign bit from the first operand (magnitude). // If it's a constant, we can clear it here. + SDValue MagMask = DAG.getConstantFP( + APFloat(Sem, ~APInt::getSignBit(SizeInBits)), dl, LogicVT); + + // FIXME: This check shouldn't be necessary. Logic instructions with constant + // operands should be folded! + SDValue MagBits; if (ConstantFPSDNode *Op0CN = dyn_cast<ConstantFPSDNode>(Mag)) { APFloat APF = Op0CN->getValueAPF(); // If the magnitude is a positive zero, the sign bit alone is enough. if (APF.isPosZero()) return IsF128 ? SignBit : - DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, SignVT, SignBit, + DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, VT, SignBit, DAG.getIntPtrConstant(0, dl)); APF.clearSign(); - CV[0] = ConstantFP::get(*Context, APF); + MagBits = DAG.getConstantFP(APF, dl, LogicVT); } else { - CV[0] = ConstantFP::get(*Context, - APFloat(Sem, ~APInt::getSignBit(SizeInBits))); - } - C = ConstantVector::get(CV); - CPIdx = DAG.getConstantPool(C, PtrVT, 16); - SDValue MagMask = - DAG.getLoad(LogicVT, dl, DAG.getEntryNode(), CPIdx, - MachinePointerInfo::getConstantPool(DAG.getMachineFunction()), - /* Alignment = */ 16); - // If the magnitude operand wasn't a constant, we need to AND out the sign. - SDValue MagBits = MagMask; - if (!isa<ConstantFPSDNode>(Mag)) { + // If the magnitude operand wasn't a constant, we need to AND out the sign. if (!IsF128) Mag = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, LogicVT, Mag); MagBits = DAG.getNode(X86ISD::FAND, dl, LogicVT, Mag, MagMask); } + // OR the magnitude value with the sign bit. SDValue Or = DAG.getNode(X86ISD::FOR, dl, LogicVT, MagBits, SignBit); return IsF128 ? Or : - DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, SignVT, Or, + DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, VT, Or, DAG.getIntPtrConstant(0, dl)); } |

