Skip to content

Commit d463c7c

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 e47e9f3 commit d463c7c

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
@@ -3762,19 +3762,13 @@ static SDValue emitComparison(SDValue LHS, SDValue RHS, ISD::CondCode CC,
37623762
Opcode = AArch64ISD::ADDS;
37633763
LHS = LHS.getOperand(1);
37643764
} else if (isNullConstant(RHS) && !isUnsignedIntSetCC(CC)) {
3765-
if (LHS.getOpcode() == ISD::AND) {
3765+
if (LHS.getOpcode() == ISD::AND && LHS.hasOneUse()) {
37663766
// Similarly, (CMP (and X, Y), 0) can be implemented with a TST
3767-
// (a.k.a. ANDS) except that the flags are only guaranteed to work for one
3768-
// of the signed comparisons.
3769-
const SDValue ANDSNode =
3770-
DAG.getNode(AArch64ISD::ANDS, DL, DAG.getVTList(VT, FlagsVT),
3771-
LHS.getOperand(0), LHS.getOperand(1));
3772-
// Replace all users of (and X, Y) with newly generated (ands X, Y)
3773-
DAG.ReplaceAllUsesWith(LHS, ANDSNode);
3774-
return ANDSNode.getValue(1);
3775-
} else if (LHS.getOpcode() == AArch64ISD::ANDS) {
3776-
// Use result of ANDS
3777-
return LHS.getValue(1);
3767+
// (a.k.a. ANDS) except that the flags are only guaranteed to work for
3768+
// signed comparisons.
3769+
Opcode = AArch64ISD::ANDS;
3770+
RHS = LHS.getOperand(1);
3771+
LHS = LHS.getOperand(0);
37783772
}
37793773
}
37803774

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)