Skip to content

Commit 20935e0

Browse files
committed
[DAGCombiner] refactor select-of-FP-constants transform
This transform needs to be limited. We are converting to a constant pool load very early, and we are turning loads that are independent of the select condition (and therefore speculatable) into a dependent non-speculatable load. We may also be transferring a condition code from an FP register to integer to create that dependent load. llvm-svn: 347424
1 parent 91614db commit 20935e0

File tree

1 file changed

+60
-53
lines changed

1 file changed

+60
-53
lines changed

llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp

Lines changed: 60 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -416,6 +416,9 @@ namespace {
416416
SDValue SimplifySelectCC(const SDLoc &DL, SDValue N0, SDValue N1,
417417
SDValue N2, SDValue N3, ISD::CondCode CC,
418418
bool NotExtCompare = false);
419+
SDValue convertSelectOfFPConstantsToLoadOffset(
420+
const SDLoc &DL, SDValue N0, SDValue N1, SDValue N2, SDValue N3,
421+
ISD::CondCode CC);
419422
SDValue foldSelectCCToShiftAnd(const SDLoc &DL, SDValue N0, SDValue N1,
420423
SDValue N2, SDValue N3, ISD::CondCode CC);
421424
SDValue foldLogicOfSetCCs(bool IsAnd, SDValue N0, SDValue N1,
@@ -18166,6 +18169,60 @@ SDValue DAGCombiner::foldSelectCCToShiftAnd(const SDLoc &DL, SDValue N0,
1816618169
return DAG.getNode(ISD::AND, DL, AType, Shift, N2);
1816718170
}
1816818171

18172+
/// Turn "(a cond b) ? 1.0f : 2.0f" into "load (tmp + ((a cond b) ? 0 : 4)"
18173+
/// where "tmp" is a constant pool entry containing an array with 1.0 and 2.0
18174+
/// in it. This may be a win when the constant is not otherwise available
18175+
/// because it replaces two constant pool loads with one.
18176+
SDValue DAGCombiner::convertSelectOfFPConstantsToLoadOffset(
18177+
const SDLoc &DL, SDValue N0, SDValue N1, SDValue N2, SDValue N3,
18178+
ISD::CondCode CC) {
18179+
// If we are before legalize types, we want the other legalization to happen
18180+
// first (for example, to avoid messing with soft float).
18181+
auto *TV = dyn_cast<ConstantFPSDNode>(N2);
18182+
auto *FV = dyn_cast<ConstantFPSDNode>(N3);
18183+
EVT VT = N2.getValueType();
18184+
if (!TV || !FV || !TLI.isTypeLegal(VT))
18185+
return SDValue();
18186+
18187+
// If a constant can be materialized without loads, this does not make sense.
18188+
if (TLI.getOperationAction(ISD::ConstantFP, VT) == TargetLowering::Legal ||
18189+
TLI.isFPImmLegal(TV->getValueAPF(), TV->getValueType(0)) ||
18190+
TLI.isFPImmLegal(FV->getValueAPF(), FV->getValueType(0)))
18191+
return SDValue();
18192+
18193+
// If both constants have multiple uses, then we won't need to do an extra
18194+
// load. The values are likely around in registers for other users.
18195+
if (!TV->hasOneUse() && !FV->hasOneUse())
18196+
return SDValue();
18197+
18198+
Constant *Elts[] = { const_cast<ConstantFP*>(FV->getConstantFPValue()),
18199+
const_cast<ConstantFP*>(TV->getConstantFPValue()) };
18200+
Type *FPTy = Elts[0]->getType();
18201+
const DataLayout &TD = DAG.getDataLayout();
18202+
18203+
// Create a ConstantArray of the two constants.
18204+
Constant *CA = ConstantArray::get(ArrayType::get(FPTy, 2), Elts);
18205+
SDValue CPIdx = DAG.getConstantPool(CA, TLI.getPointerTy(DAG.getDataLayout()),
18206+
TD.getPrefTypeAlignment(FPTy));
18207+
unsigned Alignment = cast<ConstantPoolSDNode>(CPIdx)->getAlignment();
18208+
18209+
// Get offsets to the 0 and 1 elements of the array, so we can select between
18210+
// them.
18211+
SDValue Zero = DAG.getIntPtrConstant(0, DL);
18212+
unsigned EltSize = (unsigned)TD.getTypeAllocSize(Elts[0]->getType());
18213+
SDValue One = DAG.getIntPtrConstant(EltSize, SDLoc(FV));
18214+
SDValue Cond =
18215+
DAG.getSetCC(DL, getSetCCResultType(N0.getValueType()), N0, N1, CC);
18216+
AddToWorklist(Cond.getNode());
18217+
SDValue CstOffset = DAG.getSelect(DL, Zero.getValueType(), Cond, One, Zero);
18218+
AddToWorklist(CstOffset.getNode());
18219+
CPIdx = DAG.getNode(ISD::ADD, DL, CPIdx.getValueType(), CPIdx, CstOffset);
18220+
AddToWorklist(CPIdx.getNode());
18221+
return DAG.getLoad(TV->getValueType(0), DL, DAG.getEntryNode(), CPIdx,
18222+
MachinePointerInfo::getConstantPool(
18223+
DAG.getMachineFunction()), Alignment);
18224+
}
18225+
1816918226
/// Simplify an expression of the form (N0 cond N1) ? N2 : N3
1817018227
/// where 'cond' is the comparison specified by CC.
1817118228
SDValue DAGCombiner::SimplifySelectCC(const SDLoc &DL, SDValue N0, SDValue N1,
@@ -18191,59 +18248,9 @@ SDValue DAGCombiner::SimplifySelectCC(const SDLoc &DL, SDValue N0, SDValue N1,
1819118248
return !SCCC->isNullValue() ? N2 : N3;
1819218249
}
1819318250

18194-
// Turn "(a cond b) ? 1.0f : 2.0f" into "load (tmp + ((a cond b) ? 0 : 4)"
18195-
// where "tmp" is a constant pool entry containing an array with 1.0 and 2.0
18196-
// in it. This is a win when the constant is not otherwise available because
18197-
// it replaces two constant pool loads with one. We only do this if the FP
18198-
// type is known to be legal, because if it isn't, then we are before legalize
18199-
// types an we want the other legalization to happen first (e.g. to avoid
18200-
// messing with soft float) and if the ConstantFP is not legal, because if
18201-
// it is legal, we may not need to store the FP constant in a constant pool.
18202-
if (auto *TV = dyn_cast<ConstantFPSDNode>(N2))
18203-
if (auto *FV = dyn_cast<ConstantFPSDNode>(N3)) {
18204-
if (TLI.isTypeLegal(VT) &&
18205-
(TLI.getOperationAction(ISD::ConstantFP, VT) !=
18206-
TargetLowering::Legal &&
18207-
!TLI.isFPImmLegal(TV->getValueAPF(), TV->getValueType(0)) &&
18208-
!TLI.isFPImmLegal(FV->getValueAPF(), FV->getValueType(0))) &&
18209-
// If both constants have multiple uses, then we won't need to do an
18210-
// extra load, they are likely around in registers for other users.
18211-
(TV->hasOneUse() || FV->hasOneUse())) {
18212-
Constant *Elts[] = {
18213-
const_cast<ConstantFP*>(FV->getConstantFPValue()),
18214-
const_cast<ConstantFP*>(TV->getConstantFPValue())
18215-
};
18216-
Type *FPTy = Elts[0]->getType();
18217-
const DataLayout &TD = DAG.getDataLayout();
18218-
18219-
// Create a ConstantArray of the two constants.
18220-
Constant *CA = ConstantArray::get(ArrayType::get(FPTy, 2), Elts);
18221-
SDValue CPIdx =
18222-
DAG.getConstantPool(CA, TLI.getPointerTy(DAG.getDataLayout()),
18223-
TD.getPrefTypeAlignment(FPTy));
18224-
unsigned Alignment = cast<ConstantPoolSDNode>(CPIdx)->getAlignment();
18225-
18226-
// Get the offsets to the 0 and 1 element of the array so that we can
18227-
// select between them.
18228-
SDValue Zero = DAG.getIntPtrConstant(0, DL);
18229-
unsigned EltSize = (unsigned)TD.getTypeAllocSize(Elts[0]->getType());
18230-
SDValue One = DAG.getIntPtrConstant(EltSize, SDLoc(FV));
18231-
18232-
SDValue Cond = DAG.getSetCC(DL, getSetCCResultType(CmpOpVT), N0, N1,
18233-
CC);
18234-
AddToWorklist(Cond.getNode());
18235-
SDValue CstOffset = DAG.getSelect(DL, Zero.getValueType(),
18236-
Cond, One, Zero);
18237-
AddToWorklist(CstOffset.getNode());
18238-
CPIdx = DAG.getNode(ISD::ADD, DL, CPIdx.getValueType(), CPIdx,
18239-
CstOffset);
18240-
AddToWorklist(CPIdx.getNode());
18241-
return DAG.getLoad(
18242-
TV->getValueType(0), DL, DAG.getEntryNode(), CPIdx,
18243-
MachinePointerInfo::getConstantPool(DAG.getMachineFunction()),
18244-
Alignment);
18245-
}
18246-
}
18251+
if (SDValue V =
18252+
convertSelectOfFPConstantsToLoadOffset(DL, N0, N1, N2, N3, CC))
18253+
return V;
1824718254

1824818255
if (SDValue V = foldSelectCCToShiftAnd(DL, N0, N1, N2, N3, CC))
1824918256
return V;

0 commit comments

Comments
 (0)