Skip to content

Commit dc7f807

Browse files
committed
[AArch64] Only fold into ands directly if AND is one-use
Otherwise, we can be too aggressive, and when it comes time to split along edges, we can end up duplicating more than we bargained for.
1 parent 306b5a3 commit dc7f807

File tree

9 files changed

+3362
-3477
lines changed

9 files changed

+3362
-3477
lines changed

llvm/lib/Target/AArch64/AArch64ISelLowering.cpp

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3750,19 +3750,13 @@ static SDValue emitComparison(SDValue LHS, SDValue RHS, ISD::CondCode CC,
37503750
Opcode = AArch64ISD::ADDS;
37513751
LHS = LHS.getOperand(1);
37523752
} else if (isNullConstant(RHS) && !isUnsignedIntSetCC(CC)) {
3753-
if (LHS.getOpcode() == ISD::AND) {
3753+
if (LHS.getOpcode() == ISD::AND && LHS.hasOneUse()) {
37543754
// Similarly, (CMP (and X, Y), 0) can be implemented with a TST
3755-
// (a.k.a. ANDS) except that the flags are only guaranteed to work for one
3756-
// of the signed comparisons.
3757-
const SDValue ANDSNode =
3758-
DAG.getNode(AArch64ISD::ANDS, DL, DAG.getVTList(VT, FlagsVT),
3759-
LHS.getOperand(0), LHS.getOperand(1));
3760-
// Replace all users of (and X, Y) with newly generated (ands X, Y)
3761-
DAG.ReplaceAllUsesWith(LHS, ANDSNode);
3762-
return ANDSNode.getValue(1);
3763-
} else if (LHS.getOpcode() == AArch64ISD::ANDS) {
3764-
// Use result of ANDS
3765-
return LHS.getValue(1);
3755+
// (a.k.a. ANDS) except that the flags are only guaranteed to work for
3756+
// signed comparisons.
3757+
Opcode = AArch64ISD::ANDS;
3758+
RHS = LHS.getOperand(1);
3759+
LHS = LHS.getOperand(0);
37663760
}
37673761
}
37683762

llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5118,14 +5118,14 @@ MachineInstr *AArch64InstructionSelector::tryFoldIntegerCompare(
51185118
//
51195119
// tst x, y
51205120
if (!CmpInst::isUnsigned(P) && LHSDef &&
5121-
LHSDef->getOpcode() == TargetOpcode::G_AND) {
5121+
LHSDef->getOpcode() == TargetOpcode::G_AND &&
5122+
MRI.hasOneNonDBGUse(LHS.getReg())) {
51225123
// Make sure that the RHS is 0.
51235124
auto ValAndVReg = getIConstantVRegValWithLookThrough(RHS.getReg(), MRI);
51245125
if (!ValAndVReg || ValAndVReg->Value != 0)
51255126
return nullptr;
51265127

5127-
return emitTST(LHSDef->getOperand(1),
5128-
LHSDef->getOperand(2), MIRBuilder);
5128+
return emitTST(LHSDef->getOperand(1), LHSDef->getOperand(2), MIRBuilder);
51295129
}
51305130

51315131
return nullptr;

0 commit comments

Comments
 (0)