Skip to content

Commit 3f7a24e

Browse files
committed
Refactor LowerFABS and LowerFNEG into one function (x86) (NFC)
We duplicate ~30 lines of code to lower FABS and FNEG for x86, so this patch combines them into one function. No functional change intended, so no additional test cases. Test-suite behavior is unchanged. Differential Revision: http://reviews.llvm.org/D5064 llvm-svn: 216942
1 parent a3fc923 commit 3f7a24e

File tree

1 file changed

+31
-42
lines changed

1 file changed

+31
-42
lines changed

llvm/lib/Target/X86/X86ISelLowering.cpp

Lines changed: 31 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -12221,67 +12221,56 @@ static SDValue LowerFP_EXTEND(SDValue Op, SelectionDAG &DAG) {
1222112221
In, DAG.getUNDEF(SVT)));
1222212222
}
1222312223

12224-
static SDValue LowerFABS(SDValue Op, SelectionDAG &DAG) {
12225-
LLVMContext *Context = DAG.getContext();
12226-
SDLoc dl(Op);
12227-
MVT VT = Op.getSimpleValueType();
12228-
MVT EltVT = VT;
12229-
unsigned NumElts = VT == MVT::f64 ? 2 : 4;
12230-
if (VT.isVector()) {
12231-
EltVT = VT.getVectorElementType();
12232-
NumElts = VT.getVectorNumElements();
12233-
}
12234-
12235-
unsigned EltBits = EltVT.getSizeInBits();
12236-
Constant *C = ConstantInt::get(*Context, APInt::getSignedMaxValue(EltBits));
12237-
C = ConstantVector::getSplat(NumElts, C);
12238-
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
12239-
SDValue CPIdx = DAG.getConstantPool(C, TLI.getPointerTy());
12240-
unsigned Alignment = cast<ConstantPoolSDNode>(CPIdx)->getAlignment();
12241-
SDValue Mask = DAG.getLoad(VT, dl, DAG.getEntryNode(), CPIdx,
12242-
MachinePointerInfo::getConstantPool(),
12243-
false, false, false, Alignment);
12244-
if (VT.isVector()) {
12245-
MVT ANDVT = VT.is128BitVector() ? MVT::v2i64 : MVT::v4i64;
12246-
return DAG.getNode(ISD::BITCAST, dl, VT,
12247-
DAG.getNode(ISD::AND, dl, ANDVT,
12248-
DAG.getNode(ISD::BITCAST, dl, ANDVT,
12249-
Op.getOperand(0)),
12250-
DAG.getNode(ISD::BITCAST, dl, ANDVT, Mask)));
12251-
}
12252-
return DAG.getNode(X86ISD::FAND, dl, VT, Op.getOperand(0), Mask);
12253-
}
12224+
// The only differences between FABS and FNEG are the mask and the logic op.
12225+
static SDValue LowerFABSorFNEG(SDValue Op, SelectionDAG &DAG) {
12226+
assert((Op.getOpcode() == ISD::FABS || Op.getOpcode() == ISD::FNEG) &&
12227+
"Wrong opcode for lowering FABS or FNEG.");
1225412228

12255-
static SDValue LowerFNEG(SDValue Op, SelectionDAG &DAG) {
12256-
LLVMContext *Context = DAG.getContext();
12229+
bool IsFABS = (Op.getOpcode() == ISD::FABS);
1225712230
SDLoc dl(Op);
1225812231
MVT VT = Op.getSimpleValueType();
12232+
// Assume scalar op for initialization; update for vector if needed.
12233+
// Note that there are no scalar bitwise logical SSE/AVX instructions, so we
12234+
// generate a 16-byte vector constant and logic op even for the scalar case.
12235+
// Using a 16-byte mask allows folding the load of the mask with
12236+
// the logic op, so it can save (~4 bytes) on code size.
1225912237
MVT EltVT = VT;
1226012238
unsigned NumElts = VT == MVT::f64 ? 2 : 4;
12239+
// FIXME: Use function attribute "OptimizeForSize" and/or CodeGenOpt::Level to
12240+
// decide if we should generate a 16-byte constant mask when we only need 4 or
12241+
// 8 bytes for the scalar case.
1226112242
if (VT.isVector()) {
1226212243
EltVT = VT.getVectorElementType();
1226312244
NumElts = VT.getVectorNumElements();
1226412245
}
1226512246

1226612247
unsigned EltBits = EltVT.getSizeInBits();
12267-
Constant *C = ConstantInt::get(*Context, APInt::getSignBit(EltBits));
12248+
LLVMContext *Context = DAG.getContext();
12249+
// For FABS, mask is 0x7f...; for FNEG, mask is 0x80...
12250+
APInt MaskElt =
12251+
IsFABS ? APInt::getSignedMaxValue(EltBits) : APInt::getSignBit(EltBits);
12252+
Constant *C = ConstantInt::get(*Context, MaskElt);
1226812253
C = ConstantVector::getSplat(NumElts, C);
1226912254
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
1227012255
SDValue CPIdx = DAG.getConstantPool(C, TLI.getPointerTy());
1227112256
unsigned Alignment = cast<ConstantPoolSDNode>(CPIdx)->getAlignment();
1227212257
SDValue Mask = DAG.getLoad(VT, dl, DAG.getEntryNode(), CPIdx,
1227312258
MachinePointerInfo::getConstantPool(),
1227412259
false, false, false, Alignment);
12260+
1227512261
if (VT.isVector()) {
12276-
MVT XORVT = MVT::getVectorVT(MVT::i64, VT.getSizeInBits()/64);
12262+
// For a vector, cast operands to a vector type, perform the logic op,
12263+
// and cast the result back to the original value type.
12264+
MVT VecVT = MVT::getVectorVT(MVT::i64, VT.getSizeInBits() / 64);
12265+
SDValue Op0Casted = DAG.getNode(ISD::BITCAST, dl, VecVT, Op.getOperand(0));
12266+
SDValue MaskCasted = DAG.getNode(ISD::BITCAST, dl, VecVT, Mask);
12267+
unsigned LogicOp = IsFABS ? ISD::AND : ISD::XOR;
1227712268
return DAG.getNode(ISD::BITCAST, dl, VT,
12278-
DAG.getNode(ISD::XOR, dl, XORVT,
12279-
DAG.getNode(ISD::BITCAST, dl, XORVT,
12280-
Op.getOperand(0)),
12281-
DAG.getNode(ISD::BITCAST, dl, XORVT, Mask)));
12269+
DAG.getNode(LogicOp, dl, VecVT, Op0Casted, MaskCasted));
1228212270
}
12283-
12284-
return DAG.getNode(X86ISD::FXOR, dl, VT, Op.getOperand(0), Mask);
12271+
// If not vector, then scalar.
12272+
unsigned LogicOp = IsFABS ? X86ISD::FAND : X86ISD::FXOR;
12273+
return DAG.getNode(LogicOp, dl, VT, Op.getOperand(0), Mask);
1228512274
}
1228612275

1228712276
static SDValue LowerFCOPYSIGN(SDValue Op, SelectionDAG &DAG) {
@@ -16908,8 +16897,8 @@ SDValue X86TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
1690816897
case ISD::FP_TO_UINT: return LowerFP_TO_UINT(Op, DAG);
1690916898
case ISD::FP_EXTEND: return LowerFP_EXTEND(Op, DAG);
1691016899
case ISD::LOAD: return LowerExtendedLoad(Op, Subtarget, DAG);
16911-
case ISD::FABS: return LowerFABS(Op, DAG);
16912-
case ISD::FNEG: return LowerFNEG(Op, DAG);
16900+
case ISD::FABS:
16901+
case ISD::FNEG: return LowerFABSorFNEG(Op, DAG);
1691316902
case ISD::FCOPYSIGN: return LowerFCOPYSIGN(Op, DAG);
1691416903
case ISD::FGETSIGN: return LowerFGETSIGN(Op, DAG);
1691516904
case ISD::SETCC: return LowerSETCC(Op, DAG);

0 commit comments

Comments
 (0)