forked from OSchip/llvm-project
Teach the legalizer how to legalize FP_TO_UINT.
Teach the legalizer to promote FP_TO_UINT to FP_TO_SINT if the wider FP_TO_UINT is also illegal. This allows us on PPC to codegen unsigned short foo(float a) { return a; } as: _foo: .LBB_foo_0: ; entry fctiwz f0, f1 stfd f0, -8(r1) lwz r2, -4(r1) rlwinm r3, r2, 0, 16, 31 blr instead of: _foo: .LBB_foo_0: ; entry fctiwz f0, f1 stfd f0, -8(r1) lwz r2, -4(r1) lis r3, ha16(.CPI_foo_0) lfs f0, lo16(.CPI_foo_0)(r3) fcmpu cr0, f1, f0 blt .LBB_foo_2 ; entry .LBB_foo_1: ; entry fsubs f0, f1, f0 fctiwz f0, f0 stfd f0, -16(r1) lwz r2, -12(r1) xoris r2, r2, 32768 .LBB_foo_2: ; entry rlwinm r3, r2, 0, 16, 31 blr llvm-svn: 22785
This commit is contained in:
parent
83f6b98c42
commit
36853ee1fd
|
@ -1610,7 +1610,25 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
|
||||||
switch (TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0))){
|
switch (TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0))){
|
||||||
default: assert(0 && "Unknown operation action!");
|
default: assert(0 && "Unknown operation action!");
|
||||||
case TargetLowering::Expand:
|
case TargetLowering::Expand:
|
||||||
assert(0 && "Cannot expand FP_TO*INT yet");
|
if (Node->getOpcode() == ISD::FP_TO_UINT) {
|
||||||
|
SDOperand True, False;
|
||||||
|
MVT::ValueType VT = Node->getOperand(0).getValueType();
|
||||||
|
MVT::ValueType NVT = Node->getValueType(0);
|
||||||
|
unsigned ShiftAmt = MVT::getSizeInBits(Node->getValueType(0))-1;
|
||||||
|
Tmp2 = DAG.getConstantFP((double)(1ULL << ShiftAmt), VT);
|
||||||
|
Tmp3 = DAG.getSetCC(TLI.getSetCCResultTy(),
|
||||||
|
Node->getOperand(0), Tmp2, ISD::SETLT);
|
||||||
|
True = DAG.getNode(ISD::FP_TO_SINT, NVT, Node->getOperand(0));
|
||||||
|
False = DAG.getNode(ISD::FP_TO_SINT, NVT,
|
||||||
|
DAG.getNode(ISD::SUB, VT, Node->getOperand(0),
|
||||||
|
Tmp2));
|
||||||
|
False = DAG.getNode(ISD::XOR, NVT, False,
|
||||||
|
DAG.getConstant(1ULL << ShiftAmt, NVT));
|
||||||
|
Result = LegalizeOp(DAG.getNode(ISD::SELECT, NVT, Tmp3, True, False));
|
||||||
|
} else {
|
||||||
|
assert(0 && "Do not know how to expand FP_TO_SINT yet!");
|
||||||
|
}
|
||||||
|
break;
|
||||||
case TargetLowering::Promote:
|
case TargetLowering::Promote:
|
||||||
Result = PromoteLegalFP_TO_INT(Tmp1, Node->getValueType(0),
|
Result = PromoteLegalFP_TO_INT(Tmp1, Node->getValueType(0),
|
||||||
Node->getOpcode() == ISD::FP_TO_SINT);
|
Node->getOpcode() == ISD::FP_TO_SINT);
|
||||||
|
@ -1907,7 +1925,18 @@ SDOperand SelectionDAGLegalize::PromoteOp(SDOperand Op) {
|
||||||
case Expand:
|
case Expand:
|
||||||
assert(0 && "not implemented");
|
assert(0 && "not implemented");
|
||||||
}
|
}
|
||||||
Result = DAG.getNode(Node->getOpcode(), NVT, Tmp1);
|
// If we're promoting a UINT to a larger size, check to see if the new node
|
||||||
|
// will be legal. If it isn't, check to see if FP_TO_SINT is legal, since
|
||||||
|
// we can use that instead. This allows us to generate better code for
|
||||||
|
// FP_TO_UINT for small destination sizes on targets where FP_TO_UINT is not
|
||||||
|
// legal, such as PowerPC.
|
||||||
|
if (Node->getOpcode() == ISD::FP_TO_UINT &&
|
||||||
|
TargetLowering::Legal != TLI.getOperationAction(ISD::FP_TO_UINT, NVT) &&
|
||||||
|
TargetLowering::Legal == TLI.getOperationAction(ISD::FP_TO_SINT, NVT)) {
|
||||||
|
Result = DAG.getNode(ISD::FP_TO_SINT, NVT, Tmp1);
|
||||||
|
} else {
|
||||||
|
Result = DAG.getNode(Node->getOpcode(), NVT, Tmp1);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ISD::FABS:
|
case ISD::FABS:
|
||||||
|
@ -2078,7 +2107,7 @@ SDOperand SelectionDAGLegalize::PromoteOp(SDOperand Op) {
|
||||||
break;
|
break;
|
||||||
case ISD::CTTZ:
|
case ISD::CTTZ:
|
||||||
//if Tmp1 == sizeinbits(NVT) then Tmp1 = sizeinbits(Old VT)
|
//if Tmp1 == sizeinbits(NVT) then Tmp1 = sizeinbits(Old VT)
|
||||||
Tmp2 = DAG.getSetCC(MVT::i1, Tmp1,
|
Tmp2 = DAG.getSetCC(TLI.getSetCCResultTy(), Tmp1,
|
||||||
DAG.getConstant(getSizeInBits(NVT), NVT), ISD::SETEQ);
|
DAG.getConstant(getSizeInBits(NVT), NVT), ISD::SETEQ);
|
||||||
Result = DAG.getNode(ISD::SELECT, NVT, Tmp2,
|
Result = DAG.getNode(ISD::SELECT, NVT, Tmp2,
|
||||||
DAG.getConstant(getSizeInBits(VT),NVT), Tmp1);
|
DAG.getConstant(getSizeInBits(VT),NVT), Tmp1);
|
||||||
|
|
Loading…
Reference in New Issue