[TargetLowering][DAGCombine][MSP430] add/use hook for Shift Amount Threshold (1/2)
Provides a TLI hook to allow targets to relax the emission of shifts, thus enabling codegen improvements on targets with no multiple shift instructions and cheap selects or branches. Contributes to a Fix for PR43559: https://bugs.llvm.org/show_bug.cgi?id=43559 Patch by: @joanlluch (Joan LLuch) Differential Revision: https://reviews.llvm.org/D69116 llvm-svn: 375347
This commit is contained in:
parent
7d8ea71677
commit
a298964d22
|
@ -2608,6 +2608,12 @@ public:
|
|||
// same blocks of its users.
|
||||
virtual bool shouldConsiderGEPOffsetSplit() const { return false; }
|
||||
|
||||
// Return the shift amount threshold for profitable transforms into shifts.
|
||||
// Transforms creating shifts above the returned value will be avoided.
|
||||
virtual unsigned getShiftAmountThreshold(EVT VT) const {
|
||||
return VT.getScalarSizeInBits();
|
||||
}
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Runtime Library hooks
|
||||
//
|
||||
|
|
|
@ -3603,33 +3603,35 @@ SDValue TargetLowering::SimplifySetCC(EVT VT, SDValue N0, SDValue N1,
|
|||
// Back to non-vector simplifications.
|
||||
// TODO: Can we do these for vector splats?
|
||||
if (auto *N1C = dyn_cast<ConstantSDNode>(N1.getNode())) {
|
||||
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
|
||||
const APInt &C1 = N1C->getAPIntValue();
|
||||
EVT ShValTy = N0.getValueType();
|
||||
|
||||
// Fold bit comparisons when we can.
|
||||
if ((Cond == ISD::SETEQ || Cond == ISD::SETNE) &&
|
||||
(VT == N0.getValueType() ||
|
||||
(isTypeLegal(VT) && VT.bitsLE(N0.getValueType()))) &&
|
||||
(VT == ShValTy || (isTypeLegal(VT) && VT.bitsLE(ShValTy))) &&
|
||||
N0.getOpcode() == ISD::AND) {
|
||||
auto &DL = DAG.getDataLayout();
|
||||
if (auto *AndRHS = dyn_cast<ConstantSDNode>(N0.getOperand(1))) {
|
||||
EVT ShiftTy = getShiftAmountTy(N0.getValueType(), DL,
|
||||
!DCI.isBeforeLegalize());
|
||||
EVT ShiftTy = getShiftAmountTy(ShValTy, DL, !DCI.isBeforeLegalize());
|
||||
if (Cond == ISD::SETNE && C1 == 0) {// (X & 8) != 0 --> (X & 8) >> 3
|
||||
// Perform the xform if the AND RHS is a single bit.
|
||||
if (AndRHS->getAPIntValue().isPowerOf2()) {
|
||||
unsigned ShCt = AndRHS->getAPIntValue().logBase2();
|
||||
if (AndRHS->getAPIntValue().isPowerOf2() &&
|
||||
ShCt <= TLI.getShiftAmountThreshold(ShValTy)) {
|
||||
return DAG.getNode(ISD::TRUNCATE, dl, VT,
|
||||
DAG.getNode(ISD::SRL, dl, N0.getValueType(), N0,
|
||||
DAG.getConstant(AndRHS->getAPIntValue().logBase2(), dl,
|
||||
ShiftTy)));
|
||||
DAG.getNode(ISD::SRL, dl, ShValTy, N0,
|
||||
DAG.getConstant(ShCt, dl, ShiftTy)));
|
||||
}
|
||||
} else if (Cond == ISD::SETEQ && C1 == AndRHS->getAPIntValue()) {
|
||||
// (X & 8) == 8 --> (X & 8) >> 3
|
||||
// Perform the xform if C1 is a single bit.
|
||||
if (C1.isPowerOf2()) {
|
||||
unsigned ShCt = C1.logBase2();
|
||||
if (C1.isPowerOf2() &&
|
||||
ShCt <= TLI.getShiftAmountThreshold(ShValTy)) {
|
||||
return DAG.getNode(ISD::TRUNCATE, dl, VT,
|
||||
DAG.getNode(ISD::SRL, dl, N0.getValueType(), N0,
|
||||
DAG.getConstant(C1.logBase2(), dl,
|
||||
ShiftTy)));
|
||||
DAG.getNode(ISD::SRL, dl, ShValTy, N0,
|
||||
DAG.getConstant(ShCt, dl, ShiftTy)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -353,6 +353,9 @@ SDValue MSP430TargetLowering::LowerOperation(SDValue Op,
|
|||
}
|
||||
}
|
||||
|
||||
unsigned MSP430TargetLowering::getShiftAmountThreshold(EVT VT) const {
|
||||
return 2;
|
||||
}
|
||||
//===----------------------------------------------------------------------===//
|
||||
// MSP430 Inline Assembly Support
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
|
@ -124,6 +124,8 @@ namespace llvm {
|
|||
bool isZExtFree(EVT VT1, EVT VT2) const override;
|
||||
bool isZExtFree(SDValue Val, EVT VT2) const override;
|
||||
|
||||
unsigned getShiftAmountThreshold(EVT VT) const override;
|
||||
|
||||
MachineBasicBlock *
|
||||
EmitInstrWithCustomInserter(MachineInstr &MI,
|
||||
MachineBasicBlock *BB) const override;
|
||||
|
|
|
@ -4,13 +4,9 @@
|
|||
define i16 @testSimplifySetCC_0(i16 %a) {
|
||||
; CHECK-LABEL: testSimplifySetCC_0:
|
||||
; CHECK: ; %bb.0: ; %entry
|
||||
; CHECK-NEXT: and #32, r12
|
||||
; CHECK-NEXT: clrc
|
||||
; CHECK-NEXT: rrc r12
|
||||
; CHECK-NEXT: rra r12
|
||||
; CHECK-NEXT: rra r12
|
||||
; CHECK-NEXT: rra r12
|
||||
; CHECK-NEXT: rra r12
|
||||
; CHECK-NEXT: bit #32, r12
|
||||
; CHECK-NEXT: mov r2, r12
|
||||
; CHECK-NEXT: and #1, r12
|
||||
; CHECK-NEXT: ret
|
||||
entry:
|
||||
%and = and i16 %a, 32
|
||||
|
@ -22,13 +18,9 @@ entry:
|
|||
define i16 @testSimplifySetCC_1(i16 %a) {
|
||||
; CHECK-LABEL: testSimplifySetCC_1:
|
||||
; CHECK: ; %bb.0: ; %entry
|
||||
; CHECK-NEXT: and #32, r12
|
||||
; CHECK-NEXT: clrc
|
||||
; CHECK-NEXT: rrc r12
|
||||
; CHECK-NEXT: rra r12
|
||||
; CHECK-NEXT: rra r12
|
||||
; CHECK-NEXT: rra r12
|
||||
; CHECK-NEXT: rra r12
|
||||
; CHECK-NEXT: bit #32, r12
|
||||
; CHECK-NEXT: mov r2, r12
|
||||
; CHECK-NEXT: and #1, r12
|
||||
; CHECK-NEXT: ret
|
||||
entry:
|
||||
%and = and i16 %a, 32
|
||||
|
|
Loading…
Reference in New Issue