@@ -1379,40 +1379,49 @@ bool RISCVInstrInfo::isFromLoadImm(const MachineRegisterInfo &MRI,
1379
1379
}
1380
1380
1381
1381
bool 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
+
1382
1400
MachineBasicBlock *MBB = MI.getParent ();
1383
1401
MachineRegisterInfo &MRI = MBB->getParent ()->getRegInfo ();
1384
1402
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 ();
1389
1406
1390
- RISCVCC::CondCode CC = static_cast <RISCVCC::CondCode>(Cond[ 0 ]. getImm ());
1407
+ RISCVCC::CondCode CC = getCondFromBranchOpc (MI. getOpcode ());
1391
1408
assert (CC != RISCVCC::COND_INVALID);
1392
1409
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
-
1403
1410
// Canonicalize conditional branches which can be constant folded into
1404
1411
// beqz or bnez. We can't modify the CFG here.
1405
1412
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 ();
1412
1421
return true ;
1413
1422
}
1414
1423
1415
- if (CC == RISCVCC::COND_EQ || CC == RISCVCC::COND_NE )
1424
+ if (IsEquality )
1416
1425
return false ;
1417
1426
1418
1427
// For two constants C0 and C1 from
@@ -1432,8 +1441,6 @@ bool RISCVInstrInfo::optimizeCondBranch(MachineInstr &MI) const {
1432
1441
//
1433
1442
// To make sure this optimization is really beneficial, we only
1434
1443
// 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 );
1437
1444
// Try to find the register for constant Z; return
1438
1445
// invalid register otherwise.
1439
1446
auto searchConst = [&](int64_t C1) -> Register {
@@ -1449,23 +1456,25 @@ bool RISCVInstrInfo::optimizeCondBranch(MachineInstr &MI) const {
1449
1456
return Register ();
1450
1457
};
1451
1458
1459
+ unsigned NewOpc = RISCVCC::getBrCond (getOppositeBranchCondition (CC));
1460
+
1452
1461
// Might be case 1.
1453
1462
// Don't change 0 to 1 since we can use x0.
1454
1463
// For unsigned cases changing -1U to 0 would be incorrect.
1455
1464
// The incorrect case for signed would be INT_MAX, but isFromLoadImm can't
1456
1465
// return that.
1457
1466
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 )) {
1460
1468
assert (isInt<12 >(C0) && " Unexpected immediate" );
1461
1469
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);
1465
1474
// We might extend the live range of Z, clear its kill flag to
1466
1475
// account for this.
1467
1476
MRI.clearKillFlags (RegZ);
1468
- modifyBranch ();
1477
+ MI. eraseFromParent ();
1469
1478
return true ;
1470
1479
}
1471
1480
}
@@ -1479,13 +1488,14 @@ bool RISCVInstrInfo::optimizeCondBranch(MachineInstr &MI) const {
1479
1488
MRI.hasOneUse (RHS.getReg ())) {
1480
1489
assert (isInt<12 >(C0) && " Unexpected immediate" );
1481
1490
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);
1485
1495
// We might extend the live range of Z, clear its kill flag to
1486
1496
// account for this.
1487
1497
MRI.clearKillFlags (RegZ);
1488
- modifyBranch ();
1498
+ MI. eraseFromParent ();
1489
1499
return true ;
1490
1500
}
1491
1501
}
0 commit comments