From 772837778b831a52231ff33ef42d7970e9aa8467 Mon Sep 17 00:00:00 2001 From: Bruno Cardoso Lopes Date: Thu, 31 Jul 2008 18:31:28 +0000 Subject: [PATCH] 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 --- lib/Target/Mips/MipsISelLowering.cpp | 68 +++++++++++++++++----------- lib/Target/Mips/MipsISelLowering.h | 9 ++-- 2 files changed, 47 insertions(+), 30 deletions(-) diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index 4bceb20a37e..2b2c0cf403a 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -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(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:: diff --git a/lib/Target/Mips/MipsISelLowering.h b/lib/Target/Mips/MipsISelLowering.h index ee0df3ddf91..c8c9f8bb5fe 100644 --- a/lib/Target/Mips/MipsISelLowering.h +++ b/lib/Target/Mips/MipsISelLowering.h @@ -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);