Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 48 additions & 4 deletions llvm/lib/Target/Mips/MipsISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2324,15 +2324,59 @@ SDValue MipsTargetLowering::lowerBRCOND(SDValue Op, SelectionDAG &DAG) const {
// The first operand is the chain, the second is the condition, the third is
// the block to branch to if the condition is true.
SDValue Chain = Op.getOperand(0);
SDValue Cond = Op.getOperand(1);
SDValue Dest = Op.getOperand(2);
SDLoc DL(Op);
SDNode *Node = Op.getNode();

SDLoc DL(Op);
assert(!Subtarget.hasMips32r6() && !Subtarget.hasMips64r6());
SDValue CondRes = createFPCmp(DAG, Op.getOperand(1));

// Return if flag is not set by a floating point comparison.
if (CondRes.getOpcode() != MipsISD::FPCmp)
return Op;
if (CondRes.getOpcode() != MipsISD::FPCmp) {
// For NanoMips we can try to optimize conditional branches. Try to
// recognize the following pattern:
// COND: CondV, TrueV, FalseV
// i32 = select t25, t22, t23
// CondV: t25: i32 = setcc t4, t8, seteq:ch
// TrueV: t22: i32 = setcc t2, t6, setult:ch
// FalseV: t23: i32 = setcc t4, t8, setlt:ch
if (!(Subtarget.hasNanoMips() && DAG.shouldOptForSize() &&
Cond.getOpcode() == ISD::SELECT && Node->hasOneUse()))
return Op;
auto BrNode = *Node->use_begin();
if (BrNode->getOpcode() != ISD::BR)
return Op;
SDValue ThenDest = BrNode->getOperand(1);
//DAG.DeleteNode(BrNode);
SDValue CondV = Cond.getOperand(0);
SDValue TrueV = Cond.getOperand(1);
SDValue FalseV = Cond.getOperand(2);
if (CondV.getOpcode() != ISD::SETCC || TrueV.getOpcode() != ISD::SETCC ||
FalseV.getOpcode() != ISD::SETCC)
return Op;
CondCodeSDNode *condCodeCV = dyn_cast<CondCodeSDNode>(CondV.getOperand(2));
CondCodeSDNode *condCodeTV = dyn_cast<CondCodeSDNode>(TrueV.getOperand(2));
CondCodeSDNode *condCodeFV = dyn_cast<CondCodeSDNode>(FalseV.getOperand(2));
if (!condCodeCV || !condCodeTV || !condCodeFV)
return Op;
// Form NanoMips conditional branch nodes:
SDValue BrFalse =
DAG.getNode(ISD::BRCOND, DL, MVT::Other, Chain, FalseV, Dest);
SDValue BrCond =
DAG.getNode(ISD::BRCOND, DL, MVT::Other, BrFalse,
DAG.getSetCC(DL, CondV->getValueType(0),
CondV->getOperand(0), CondV->getOperand(1),
ISD::getSetCCInverse(
condCodeCV->get(),
CondV->getOperand(0)->getValueType(0))),
ThenDest);
SDValue BrTrue =
DAG.getNode(ISD::BRCOND, DL, MVT::Other, BrCond, TrueV, Dest);
// Instruction selection will be able to match these BRCOND nodes with the
// nanoMIPS conditional branch instructions.

return BrTrue;
}

SDValue CCNode = CondRes.getOperand(2);
Mips::CondCode CC =
Expand Down
43 changes: 41 additions & 2 deletions llvm/lib/Target/Mips/MipsInstrInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -272,8 +272,47 @@ MipsInstrInfo::BranchType MipsInstrInfo::analyzeBranch(

// If we reached here, there are two branches.
// If there are three terminators, we don't know what sort of block this is.
if (++I != REnd && isUnpredicatedTerminator(*I))
return BT_None;
if (++I != REnd && isUnpredicatedTerminator(*I)) {
if (!Subtarget.hasNanoMips() ||
!MBB.getParent()->getFunction().hasOptSize())
return BT_None;
// For nanoMIPS: When comparing two 64-bit data, there are three comparisons
// to determine whether the condition is met. Two conditional branches
// branch to the If.Else block, while the third branches to the If.then
// block. If this pattern is followed by the unconditional branch - that
// branch is redundant.
auto ThirdLastInst = &(*I);
if (!LastInst->isUnconditionalBranch() ||
!SecondLastInst->isConditionalBranch() ||
!ThirdLastInst->isConditionalBranch() || (++I) == REnd)
return BT_None;

auto FourthLastInst = &(*I);
if (!FourthLastInst->isConditionalBranch())
return BT_None;
auto IfElseSLI = SecondLastInst->getOperand(2).getMBB();
auto IfElseFLI = FourthLastInst->getOperand(2).getMBB();
auto IfThenLI = LastInst->getOperand(0).getMBB();
auto IfThenTLI = ThirdLastInst->getOperand(2).getMBB();
if (IfElseFLI != IfElseSLI || IfThenLI != IfThenTLI)
return BT_None;
auto HigherRegFLIFirst = FourthLastInst->getOperand(0).getReg();
auto HigherRegTLIFirst = ThirdLastInst->getOperand(0).getReg();
auto HigherRegFLISecond = FourthLastInst->getOperand(1).getReg();
auto HigherRegTLISecond = ThirdLastInst->getOperand(1).getReg();
if (HigherRegFLIFirst != HigherRegTLIFirst ||
HigherRegFLISecond != HigherRegTLISecond)
return BT_None;
auto LowerRegSLIFirst = SecondLastInst->getOperand(0).getReg();
auto LowerRegSLISecond = SecondLastInst->getOperand(1).getReg();

if (HigherRegFLIFirst.id() != (LowerRegSLIFirst.id() + 1) ||
HigherRegFLISecond.id() != (LowerRegSLISecond.id() + 1))
return BT_None;
// If the pattern matches, set the LabelMustBeEmitted flag for If.then block
// and continue with the analysis.
IfThenTLI->setLabelMustBeEmitted();
}

BranchInstrs.insert(BranchInstrs.begin(), SecondLastInst);

Expand Down
31 changes: 31 additions & 0 deletions llvm/test/CodeGen/Mips/nanomips/64bit-comparison.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
; RUN: llc -mtriple=nanomips -asm-show-inst -verify-machineinstrs < %s | FileCheck %s

; CHECK: bltc $a1, $a3, .LBB0_2
; CHECK: bnec $a1, $a3, .LBB0_1
; CHECK: bltuc $a0, $a2, .LBB0_2
; CHECK: .LBB0_1:
; CHECK: .LBB0_2:

; Function Attrs: optsize
define void @test(i64 signext %a, i64 signext %b) #0 {
entry:
%cmp.not = icmp slt i64 %a, %b
br i1 %cmp.not, label %if.else, label %if.then

if.then: ; preds = %entry
tail call void bitcast (void (...)* @aa to void ()*)()
br label %if.end

if.else: ; preds = %entry
tail call void bitcast (void (...)* @bb to void ()*)()
br label %if.end

if.end: ; preds = %if.else, %if.then
ret void
}

declare void @aa(...)

declare void @bb(...)

attributes #0 = { optsize }