@@ -1379,40 +1379,49 @@ bool RISCVInstrInfo::isFromLoadImm(const MachineRegisterInfo &MRI,
13791379}
13801380
13811381bool RISCVInstrInfo::optimizeCondBranch (MachineInstr &MI) const {
1382+ bool IsSigned = false ;
1383+ bool IsEquality = false ;
1384+ switch (MI.getOpcode ()) {
1385+ default :
1386+ return false ;
1387+ case RISCV::BEQ:
1388+ case RISCV::BNE:
1389+ IsEquality = true ;
1390+ break ;
1391+ case RISCV::BGE:
1392+ case RISCV::BLT:
1393+ IsSigned = true ;
1394+ break ;
1395+ case RISCV::BGEU:
1396+ case RISCV::BLTU:
1397+ break ;
1398+ }
1399+
13821400 MachineBasicBlock *MBB = MI.getParent ();
13831401 MachineRegisterInfo &MRI = MBB->getParent ()->getRegInfo ();
13841402
1385- MachineBasicBlock *TBB, *FBB;
1386- SmallVector<MachineOperand, 3 > Cond;
1387- if (analyzeBranch (*MBB, TBB, FBB, Cond, /* AllowModify=*/ false ))
1388- return false ;
1403+ const MachineOperand &LHS = MI.getOperand (0 );
1404+ const MachineOperand &RHS = MI.getOperand (1 );
1405+ MachineBasicBlock *TBB = MI.getOperand (2 ).getMBB ();
13891406
1390- RISCVCC::CondCode CC = static_cast <RISCVCC::CondCode>(Cond[ 0 ]. getImm ());
1407+ RISCVCC::CondCode CC = getCondFromBranchOpc (MI. getOpcode ());
13911408 assert (CC != RISCVCC::COND_INVALID);
13921409
1393- auto modifyBranch = [&]() {
1394- // Build the new branch and remove the old one.
1395- BuildMI (*MBB, MI, MI.getDebugLoc (),
1396- getBrCond (static_cast <RISCVCC::CondCode>(Cond[0 ].getImm ())))
1397- .add (Cond[1 ])
1398- .add (Cond[2 ])
1399- .addMBB (TBB);
1400- MI.eraseFromParent ();
1401- };
1402-
14031410 // Canonicalize conditional branches which can be constant folded into
14041411 // beqz or bnez. We can't modify the CFG here.
14051412 int64_t C0, C1;
1406- if (isFromLoadImm (MRI, Cond[1 ], C0) && isFromLoadImm (MRI, Cond[2 ], C1)) {
1407- unsigned NewCC =
1408- evaluateCondBranch (CC, C0, C1) ? RISCVCC::COND_EQ : RISCVCC::COND_NE;
1409- Cond[0 ] = MachineOperand::CreateImm (NewCC);
1410- Cond[1 ] = Cond[2 ] = MachineOperand::CreateReg (RISCV::X0, /* isDef=*/ false );
1411- modifyBranch ();
1413+ if (isFromLoadImm (MRI, LHS, C0) && isFromLoadImm (MRI, RHS, C1)) {
1414+ unsigned NewOpc = evaluateCondBranch (CC, C0, C1) ? RISCV::BEQ : RISCV::BNE;
1415+ // Build the new branch and remove the old one.
1416+ BuildMI (*MBB, MI, MI.getDebugLoc (), get (NewOpc))
1417+ .addReg (RISCV::X0)
1418+ .addReg (RISCV::X0)
1419+ .addMBB (TBB);
1420+ MI.eraseFromParent ();
14121421 return true ;
14131422 }
14141423
1415- if (CC == RISCVCC::COND_EQ || CC == RISCVCC::COND_NE )
1424+ if (IsEquality )
14161425 return false ;
14171426
14181427 // For two constants C0 and C1 from
@@ -1432,8 +1441,6 @@ bool RISCVInstrInfo::optimizeCondBranch(MachineInstr &MI) const {
14321441 //
14331442 // To make sure this optimization is really beneficial, we only
14341443 // optimize for cases where Y had only one use (i.e. only used by the branch).
1435- MachineOperand &LHS = MI.getOperand (0 );
1436- MachineOperand &RHS = MI.getOperand (1 );
14371444 // Try to find the register for constant Z; return
14381445 // invalid register otherwise.
14391446 auto searchConst = [&](int64_t C1) -> Register {
@@ -1449,23 +1456,25 @@ bool RISCVInstrInfo::optimizeCondBranch(MachineInstr &MI) const {
14491456 return Register ();
14501457 };
14511458
1459+ unsigned NewOpc = RISCVCC::getBrCond (getOppositeBranchCondition (CC));
1460+
14521461 // Might be case 1.
14531462 // Don't change 0 to 1 since we can use x0.
14541463 // For unsigned cases changing -1U to 0 would be incorrect.
14551464 // The incorrect case for signed would be INT_MAX, but isFromLoadImm can't
14561465 // return that.
14571466 if (isFromLoadImm (MRI, LHS, C0) && C0 != 0 && LHS.getReg ().isVirtual () &&
1458- MRI.hasOneUse (LHS.getReg ()) &&
1459- (CC == RISCVCC::COND_GE || CC == RISCVCC::COND_LT || C0 != -1 )) {
1467+ MRI.hasOneUse (LHS.getReg ()) && (IsSigned || C0 != -1 )) {
14601468 assert (isInt<12 >(C0) && " Unexpected immediate" );
14611469 if (Register RegZ = searchConst (C0 + 1 )) {
1462- reverseBranchCondition (Cond);
1463- Cond[1 ] = MachineOperand::CreateReg (RHS.getReg (), /* isDef=*/ false );
1464- Cond[2 ] = MachineOperand::CreateReg (RegZ, /* isDef=*/ false );
1470+ BuildMI (*MBB, MI, MI.getDebugLoc (), get (NewOpc))
1471+ .add (RHS)
1472+ .addReg (RegZ)
1473+ .addMBB (TBB);
14651474 // We might extend the live range of Z, clear its kill flag to
14661475 // account for this.
14671476 MRI.clearKillFlags (RegZ);
1468- modifyBranch ();
1477+ MI. eraseFromParent ();
14691478 return true ;
14701479 }
14711480 }
@@ -1479,13 +1488,14 @@ bool RISCVInstrInfo::optimizeCondBranch(MachineInstr &MI) const {
14791488 MRI.hasOneUse (RHS.getReg ())) {
14801489 assert (isInt<12 >(C0) && " Unexpected immediate" );
14811490 if (Register RegZ = searchConst (C0 - 1 )) {
1482- reverseBranchCondition (Cond);
1483- Cond[1 ] = MachineOperand::CreateReg (RegZ, /* isDef=*/ false );
1484- Cond[2 ] = MachineOperand::CreateReg (LHS.getReg (), /* isDef=*/ false );
1491+ BuildMI (*MBB, MI, MI.getDebugLoc (), get (NewOpc))
1492+ .addReg (RegZ)
1493+ .add (LHS)
1494+ .addMBB (TBB);
14851495 // We might extend the live range of Z, clear its kill flag to
14861496 // account for this.
14871497 MRI.clearKillFlags (RegZ);
1488- modifyBranch ();
1498+ MI. eraseFromParent ();
14891499 return true ;
14901500 }
14911501 }
0 commit comments