Skip to content

Commit d6b12cf

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 b7ceda3 commit d6b12cf

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
@@ -3745,19 +3745,13 @@ static SDValue emitComparison(SDValue LHS, SDValue RHS, ISD::CondCode CC,
37453745
Opcode = AArch64ISD::ADDS;
37463746
LHS = LHS.getOperand(1);
37473747
} else if (isNullConstant(RHS) && !isUnsignedIntSetCC(CC)) {
3748-
if (LHS.getOpcode() == ISD::AND) {
3748+
if (LHS.getOpcode() == ISD::AND && LHS.hasOneUse()) {
37493749
// Similarly, (CMP (and X, Y), 0) can be implemented with a TST
3750-
// (a.k.a. ANDS) except that the flags are only guaranteed to work for one
3751-
// of the signed comparisons.
3752-
const SDValue ANDSNode =
3753-
DAG.getNode(AArch64ISD::ANDS, DL, DAG.getVTList(VT, FlagsVT),
3754-
LHS.getOperand(0), LHS.getOperand(1));
3755-
// Replace all users of (and X, Y) with newly generated (ands X, Y)
3756-
DAG.ReplaceAllUsesWith(LHS, ANDSNode);
3757-
return ANDSNode.getValue(1);
3758-
} else if (LHS.getOpcode() == AArch64ISD::ANDS) {
3759-
// Use result of ANDS
3760-
return LHS.getValue(1);
3750+
// (a.k.a. ANDS) except that the flags are only guaranteed to work for
3751+
// signed comparisons.
3752+
Opcode = AArch64ISD::ANDS;
3753+
RHS = LHS.getOperand(1);
3754+
LHS = LHS.getOperand(0);
37613755
}
37623756
}
37633757

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5109,14 +5109,14 @@ MachineInstr *AArch64InstructionSelector::tryFoldIntegerCompare(
51095109
//
51105110
// tst x, y
51115111
if (!CmpInst::isUnsigned(P) && LHSDef &&
5112-
LHSDef->getOpcode() == TargetOpcode::G_AND) {
5112+
LHSDef->getOpcode() == TargetOpcode::G_AND &&
5113+
MRI.hasOneNonDBGUse(LHS.getReg())) {
51135114
// Make sure that the RHS is 0.
51145115
auto ValAndVReg = getIConstantVRegValWithLookThrough(RHS.getReg(), MRI);
51155116
if (!ValAndVReg || ValAndVReg->Value != 0)
51165117
return nullptr;
51175118

5118-
return emitTST(LHSDef->getOperand(1),
5119-
LHSDef->getOperand(2), MIRBuilder);
5119+
return emitTST(LHSDef->getOperand(1), LHSDef->getOperand(2), MIRBuilder);
51205120
}
51215121

51225122
return nullptr;

0 commit comments

Comments
 (0)