1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-19 02:52:53 +02:00

[ARM] Make PerformSHLSimplify add nodes to the DAG worklist correctly.

Intentionally excluding nodes from the DAGCombine worklist is likely to
lead to weird optimizations and infinite loops, so it's generally a bad
idea.

To avoid the infinite loops, fix DAGCombine to use the
isDesirableToCommuteWithShift target hook before performing the
transforms in question, and implement the target hook in the ARM backend
disable the transforms in question.

Fixes https://bugs.llvm.org/show_bug.cgi?id=38530 . (I don't have a
reduced testcase for that bug. But we should have sufficient test
coverage for PerformSHLSimplify given that we're not playing weird
tricks with the worklist. I can try to bugpoint it if necessary,
though.)

Differential Revision: https://reviews.llvm.org/D50667

llvm-svn: 339734
This commit is contained in:
Eli Friedman 2018-08-14 22:10:25 +00:00
parent ad250a25cd
commit 23b65e265f
6 changed files with 41 additions and 13 deletions

View File

@ -2942,12 +2942,16 @@ public:
/// ///
virtual SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const; virtual SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const;
/// Return true if it is profitable to move a following shift through this /// Return true if it is profitable to move this shift by a constant amount
// node, adjusting any immediate operands as necessary to preserve semantics. /// though its operand, adjusting any immediate operands as necessary to
// This transformation may not be desirable if it disrupts a particularly /// preserve semantics. This transformation may not be desirable if it
// auspicious target-specific tree (e.g. bitfield extraction in AArch64). /// disrupts a particularly auspicious target-specific tree (e.g. bitfield
// By default, it returns true. /// extraction in AArch64). By default, it returns true.
virtual bool isDesirableToCommuteWithShift(const SDNode *N) const { ///
/// @param N the shift node
/// @param Level the current DAGCombine legalization level.
virtual bool isDesirableToCommuteWithShift(const SDNode *N,
CombineLevel Level) const {
return true; return true;
} }

View File

@ -6206,7 +6206,7 @@ SDValue DAGCombiner::visitShiftByConstant(SDNode *N, ConstantSDNode *Amt) {
return SDValue(); return SDValue();
} }
if (!TLI.isDesirableToCommuteWithShift(LHS)) if (!TLI.isDesirableToCommuteWithShift(N, Level))
return SDValue(); return SDValue();
// Fold the constants, shifting the binop RHS by the shift amount. // Fold the constants, shifting the binop RHS by the shift amount.
@ -6510,7 +6510,8 @@ SDValue DAGCombiner::visitSHL(SDNode *N) {
if ((N0.getOpcode() == ISD::ADD || N0.getOpcode() == ISD::OR) && if ((N0.getOpcode() == ISD::ADD || N0.getOpcode() == ISD::OR) &&
N0.getNode()->hasOneUse() && N0.getNode()->hasOneUse() &&
isConstantOrConstantVector(N1, /* No Opaques */ true) && isConstantOrConstantVector(N1, /* No Opaques */ true) &&
isConstantOrConstantVector(N0.getOperand(1), /* No Opaques */ true)) { isConstantOrConstantVector(N0.getOperand(1), /* No Opaques */ true) &&
TLI.isDesirableToCommuteWithShift(N, Level)) {
SDValue Shl0 = DAG.getNode(ISD::SHL, SDLoc(N0), VT, N0.getOperand(0), N1); SDValue Shl0 = DAG.getNode(ISD::SHL, SDLoc(N0), VT, N0.getOperand(0), N1);
SDValue Shl1 = DAG.getNode(ISD::SHL, SDLoc(N1), VT, N0.getOperand(1), N1); SDValue Shl1 = DAG.getNode(ISD::SHL, SDLoc(N1), VT, N0.getOperand(1), N1);
AddToWorklist(Shl0.getNode()); AddToWorklist(Shl0.getNode());

View File

@ -8473,7 +8473,9 @@ AArch64TargetLowering::getScratchRegisters(CallingConv::ID) const {
} }
bool bool
AArch64TargetLowering::isDesirableToCommuteWithShift(const SDNode *N) const { AArch64TargetLowering::isDesirableToCommuteWithShift(const SDNode *N,
CombineLevel Level) const {
N = N->getOperand(0).getNode();
EVT VT = N->getValueType(0); EVT VT = N->getValueType(0);
// If N is unsigned bit extraction: ((x >> C) & mask), then do not combine // If N is unsigned bit extraction: ((x >> C) & mask), then do not combine
// it with shift to let it be lowered to UBFX. // it with shift to let it be lowered to UBFX.

View File

@ -363,7 +363,8 @@ public:
const MCPhysReg *getScratchRegisters(CallingConv::ID CC) const override; const MCPhysReg *getScratchRegisters(CallingConv::ID CC) const override;
/// Returns false if N is a bit extraction pattern of (X >> C) & Mask. /// Returns false if N is a bit extraction pattern of (X >> C) & Mask.
bool isDesirableToCommuteWithShift(const SDNode *N) const override; bool isDesirableToCommuteWithShift(const SDNode *N,
CombineLevel Level) const override;
/// Returns true if it is beneficial to convert a load of a constant /// Returns true if it is beneficial to convert a load of a constant
/// to just the constant itself. /// to just the constant itself.

View File

@ -10447,6 +10447,25 @@ static SDValue PerformADDCombineWithOperands(SDNode *N, SDValue N0, SDValue N1,
return SDValue(); return SDValue();
} }
bool
ARMTargetLowering::isDesirableToCommuteWithShift(const SDNode *N,
CombineLevel Level) const {
if (Level == BeforeLegalizeTypes)
return true;
if (Subtarget->isThumb() && Subtarget->isThumb1Only())
return true;
if (N->getOpcode() != ISD::SHL)
return true;
// Turn off commute-with-shift transform after legalization, so it doesn't
// conflict with PerformSHLSimplify. (We could try to detect when
// PerformSHLSimplify would trigger more precisely, but it isn't
// really necessary.)
return false;
}
static SDValue PerformSHLSimplify(SDNode *N, static SDValue PerformSHLSimplify(SDNode *N,
TargetLowering::DAGCombinerInfo &DCI, TargetLowering::DAGCombinerInfo &DCI,
const ARMSubtarget *ST) { const ARMSubtarget *ST) {
@ -10546,9 +10565,7 @@ static SDValue PerformSHLSimplify(SDNode *N,
LLVM_DEBUG(dbgs() << "Simplify shl use:\n"; SHL.getOperand(0).dump(); LLVM_DEBUG(dbgs() << "Simplify shl use:\n"; SHL.getOperand(0).dump();
SHL.dump(); N->dump()); SHL.dump(); N->dump());
LLVM_DEBUG(dbgs() << "Into:\n"; X.dump(); BinOp.dump(); Res.dump()); LLVM_DEBUG(dbgs() << "Into:\n"; X.dump(); BinOp.dump(); Res.dump());
return Res;
DAG.ReplaceAllUsesWith(SDValue(N, 0), Res);
return SDValue(N, 0);
} }

View File

@ -586,6 +586,9 @@ class VectorType;
unsigned getABIAlignmentForCallingConv(Type *ArgTy, unsigned getABIAlignmentForCallingConv(Type *ArgTy,
DataLayout DL) const override; DataLayout DL) const override;
bool isDesirableToCommuteWithShift(const SDNode *N,
CombineLevel Level) const override;
protected: protected:
std::pair<const TargetRegisterClass *, uint8_t> std::pair<const TargetRegisterClass *, uint8_t>
findRepresentativeClass(const TargetRegisterInfo *TRI, findRepresentativeClass(const TargetRegisterInfo *TRI,