@@ -416,6 +416,9 @@ namespace {
416
416
SDValue SimplifySelectCC(const SDLoc &DL, SDValue N0, SDValue N1,
417
417
SDValue N2, SDValue N3, ISD::CondCode CC,
418
418
bool NotExtCompare = false);
419
+ SDValue convertSelectOfFPConstantsToLoadOffset(
420
+ const SDLoc &DL, SDValue N0, SDValue N1, SDValue N2, SDValue N3,
421
+ ISD::CondCode CC);
419
422
SDValue foldSelectCCToShiftAnd(const SDLoc &DL, SDValue N0, SDValue N1,
420
423
SDValue N2, SDValue N3, ISD::CondCode CC);
421
424
SDValue foldLogicOfSetCCs(bool IsAnd, SDValue N0, SDValue N1,
@@ -18166,6 +18169,60 @@ SDValue DAGCombiner::foldSelectCCToShiftAnd(const SDLoc &DL, SDValue N0,
18166
18169
return DAG.getNode(ISD::AND, DL, AType, Shift, N2);
18167
18170
}
18168
18171
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
+
18169
18226
/// Simplify an expression of the form (N0 cond N1) ? N2 : N3
18170
18227
/// where 'cond' is the comparison specified by CC.
18171
18228
SDValue DAGCombiner::SimplifySelectCC(const SDLoc &DL, SDValue N0, SDValue N1,
@@ -18191,59 +18248,9 @@ SDValue DAGCombiner::SimplifySelectCC(const SDLoc &DL, SDValue N0, SDValue N1,
18191
18248
return !SCCC->isNullValue() ? N2 : N3;
18192
18249
}
18193
18250
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;
18247
18254
18248
18255
if (SDValue V = foldSelectCCToShiftAnd(DL, N0, N1, N2, N3, CC))
18249
18256
return V;
0 commit comments