Skip to content

Commit fdf863c

Browse files
committed
[AArch64] Correctness fix: Turn cmn 0 into cmp 0
When we change the condition, in the edge case of -1, we need to change this from cmn 1 to cmp 0. We were returning cmn 0, which is not the same as cmp 0.
1 parent b66d8d3 commit fdf863c

File tree

1 file changed

+19
-3
lines changed

1 file changed

+19
-3
lines changed

llvm/lib/Target/AArch64/AArch64ConditionOptimizer.cpp

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,13 @@ AArch64ConditionOptimizer::CmpInfo AArch64ConditionOptimizer::adjustCmp(
255255
const int OldImm = (int)CmpMI->getOperand(2).getImm();
256256
const int NewImm = std::abs(OldImm + Correction);
257257

258-
// Handle +0 -> -1 and -0 -> +1 (CMN with 0 immediate) transitions by
258+
// Handle cmn 1 -> cmp 0, because we prefer CMP 0 over cmn 0.
259+
if (OldImm == 1 && (Negative && Correction == -1)) {
260+
// If we are adjusting from -1 to 0, we need to change the opcode.
261+
Opc = getComplementOpc(Opc);
262+
}
263+
264+
// Handle +0 -> -1 and -0 -> +1 (CMN with 0 immediate.) transitions by
259265
// adjusting compare instruction opcode.
260266
if (OldImm == 0 && ((Negative && Correction == 1) ||
261267
(!Negative && Correction == -1))) {
@@ -380,8 +386,8 @@ bool AArch64ConditionOptimizer::runOnMachineFunction(MachineFunction &MF) {
380386
continue;
381387
}
382388

383-
const int HeadImm = (int)HeadCmpMI->getOperand(2).getImm();
384-
const int TrueImm = (int)TrueCmpMI->getOperand(2).getImm();
389+
int HeadImm = (int)HeadCmpMI->getOperand(2).getImm();
390+
int TrueImm = (int)TrueCmpMI->getOperand(2).getImm();
385391

386392
LLVM_DEBUG(dbgs() << "Head branch:\n");
387393
LLVM_DEBUG(dbgs() << "\tcondition: " << AArch64CC::getCondCodeName(HeadCmp)
@@ -393,6 +399,14 @@ bool AArch64ConditionOptimizer::runOnMachineFunction(MachineFunction &MF) {
393399
<< '\n');
394400
LLVM_DEBUG(dbgs() << "\timmediate: " << TrueImm << '\n');
395401

402+
unsigned Opc = HeadCmpMI->getOpcode();
403+
if (Opc == AArch64::ADDSWri || Opc == AArch64::ADDSXri)
404+
HeadImm = -HeadImm;
405+
406+
Opc = TrueCmpMI->getOpcode();
407+
if (Opc == AArch64::ADDSWri || Opc == AArch64::ADDSXri)
408+
TrueImm = -TrueImm;
409+
396410
if (((HeadCmp == AArch64CC::GT && TrueCmp == AArch64CC::LT) ||
397411
(HeadCmp == AArch64CC::LT && TrueCmp == AArch64CC::GT)) &&
398412
std::abs(TrueImm - HeadImm) == 2) {
@@ -434,6 +448,8 @@ bool AArch64ConditionOptimizer::runOnMachineFunction(MachineFunction &MF) {
434448
adjustHeadCond = !adjustHeadCond;
435449
}
436450

451+
TrueImm = std::abs(TrueImm);
452+
HeadImm = std::abs(HeadImm);
437453
if (adjustHeadCond) {
438454
Changed |= adjustTo(HeadCmpMI, HeadCmp, TrueCmpMI, TrueImm);
439455
} else {

0 commit comments

Comments
 (0)