Handle more SELECT corner cases considering legalize types, probabily wont work with

the default legalizer.



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@54249 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Bruno Cardoso Lopes 2008-07-31 18:31:28 +00:00
parent 7232464bda
commit 772837778b
2 changed files with 47 additions and 30 deletions

View File

@ -85,6 +85,12 @@ MipsTargetLowering(MipsTargetMachine &TM): TargetLowering(TM)
setLoadXAction(ISD::ZEXTLOAD, MVT::i1, Promote);
setLoadXAction(ISD::SEXTLOAD, MVT::i1, Promote);
// Used by legalize types to correctly generate the setcc result.
// Without this, every float setcc comes with a AND with the result,
// we don't want this, since the fpcmp result goes to a flag register,
// which is used implicitly by brcond and select operations.
AddPromotedToType(ISD::SETCC, MVT::i1, MVT::i32);
// Mips Custom Operations
setOperationAction(ISD::GlobalAddress, MVT::i32, Custom);
setOperationAction(ISD::GlobalTLSAddress, MVT::i32, Custom);
@ -97,6 +103,11 @@ MipsTargetLowering(MipsTargetMachine &TM): TargetLowering(TM)
setOperationAction(ISD::SETCC, MVT::f32, Custom);
setOperationAction(ISD::BRCOND, MVT::Other, Custom);
// We custom lower AND to handle the case where the DAG contain 'ands'
// setcc results with fp operands. This is necessary since the result
// from these are in a flag register (FCR31).
setOperationAction(ISD::AND, MVT::i32, Custom);
// Operations not directly supported by Mips.
setOperationAction(ISD::BR_JT, MVT::Other, Expand);
setOperationAction(ISD::BR_CC, MVT::Other, Expand);
@ -148,6 +159,7 @@ LowerOperation(SDValue Op, SelectionDAG &DAG)
{
switch (Op.getOpcode())
{
case ISD::AND: return LowerAND(Op, DAG);
case ISD::BRCOND: return LowerBRCOND(Op, DAG);
case ISD::CALL: return LowerCALL(Op, DAG);
case ISD::ConstantPool: return LowerConstantPool(Op, DAG);
@ -346,6 +358,26 @@ MipsTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
// Misc Lower Operation implementation
//===----------------------------------------------------------------------===//
SDValue MipsTargetLowering::
LowerAND(SDValue Op, SelectionDAG &DAG)
{
SDValue LHS = Op.getOperand(0);
SDValue RHS = Op.getOperand(1);
if (LHS.getOpcode() != MipsISD::FPCmp || RHS.getOpcode() != MipsISD::FPCmp)
return Op;
SDValue True = DAG.getConstant(1, MVT::i32);
SDValue False = DAG.getConstant(0, MVT::i32);
SDValue LSEL = DAG.getNode(MipsISD::FPSelectCC, True.getValueType(),
LHS, True, False, LHS.getOperand(2));
SDValue RSEL = DAG.getNode(MipsISD::FPSelectCC, True.getValueType(),
RHS, True, False, RHS.getOperand(2));
return DAG.getNode(ISD::AND, MVT::i32, LSEL, RSEL);
}
SDValue MipsTargetLowering::
LowerBRCOND(SDValue Op, SelectionDAG &DAG)
{
@ -353,18 +385,12 @@ LowerBRCOND(SDValue Op, SelectionDAG &DAG)
// the block to branch to if the condition is true.
SDValue Chain = Op.getOperand(0);
SDValue Dest = Op.getOperand(2);
SDValue CondRes;
if (Op.getOperand(1).getOpcode() == ISD::AND) {
CondRes = Op.getOperand(1).getOperand(0);
if (CondRes.getOpcode() != MipsISD::FPCmp)
return Op;
} else if (Op.getOperand(1).getOpcode() == MipsISD::FPCmp)
CondRes = Op.getOperand(1);
else
if (Op.getOperand(1).getOpcode() != MipsISD::FPCmp)
return Op;
SDValue CCNode = CondRes.getOperand(2);
SDValue CondRes = Op.getOperand(1);
SDValue CCNode = CondRes.getOperand(2);
Mips::CondCode CC = (Mips::CondCode)cast<ConstantSDNode>(CCNode)->getValue();
SDValue BrCode = DAG.getConstant(GetFPBranchCodeFromCond(CC), MVT::i32);
@ -394,25 +420,15 @@ LowerSELECT(SDValue Op, SelectionDAG &DAG)
SDValue True = Op.getOperand(1);
SDValue False = Op.getOperand(2);
// this can be a fp select but with a setcc comming from a
// integer compare.
if (Cond.getOpcode() == ISD::SETCC)
if (Cond.getOperand(0).getValueType().isInteger())
return DAG.getNode(MipsISD::SelectCC, True.getValueType(),
Cond, True, False);
// Otherwise we're dealing with floating point compare.
SDValue CondRes;
if (Cond.getOpcode() == ISD::AND)
CondRes = Cond.getOperand(0);
else if (Cond.getOpcode() == MipsISD::FPCmp)
CondRes = Cond;
else
assert(0 && "Incoming condition flag unknown");
// if the incomming condition comes from fpcmp, the select
// operation must use FPSelectCC, otherwise SelectCC.
if (Cond.getOpcode() != MipsISD::FPCmp)
return DAG.getNode(MipsISD::SelectCC, True.getValueType(),
Cond, True, False);
SDValue CCNode = CondRes.getOperand(2);
SDValue CCNode = Cond.getOperand(2);
return DAG.getNode(MipsISD::FPSelectCC, True.getValueType(),
CondRes, True, False, CCNode);
Cond, True, False, CCNode);
}
SDValue MipsTargetLowering::

View File

@ -91,17 +91,18 @@ namespace llvm {
bool IsInSmallSection(unsigned Size);
// Lower Operand specifics
SDValue LowerRET(SDValue Op, SelectionDAG &DAG);
SDValue LowerAND(SDValue Op, SelectionDAG &DAG);
SDValue LowerBRCOND(SDValue Op, SelectionDAG &DAG);
SDValue LowerCALL(SDValue Op, SelectionDAG &DAG);
SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG);
SDValue LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG);
SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG);
SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG);
SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG);
SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG);
SDValue LowerSELECT(SDValue Op, SelectionDAG &DAG);
SDValue LowerRET(SDValue Op, SelectionDAG &DAG);
SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG);
SDValue LowerSELECT(SDValue Op, SelectionDAG &DAG);
SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG);
SDValue LowerBRCOND(SDValue Op, SelectionDAG &DAG);
virtual MachineBasicBlock *EmitInstrWithCustomInserter(MachineInstr *MI,
MachineBasicBlock *MBB);