Skip to content

Commit

Permalink
[TargetLowering][DAGCombine][MSP430] add/use hook for Shift Amount Th…
Browse files Browse the repository at this point in the history
…reshold (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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@375347 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
rotateright committed Oct 19, 2019
1 parent 3166412 commit 0d04cbb
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 26 deletions.
6 changes: 6 additions & 0 deletions include/llvm/CodeGen/TargetLowering.h
Original file line number Diff line number Diff line change
Expand Up @@ -2608,6 +2608,12 @@ class TargetLoweringBase {
// 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
//
Expand Down
26 changes: 14 additions & 12 deletions lib/CodeGen/SelectionDAG/TargetLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)));
}
}
}
Expand Down
3 changes: 3 additions & 0 deletions lib/Target/MSP430/MSP430ISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,9 @@ SDValue MSP430TargetLowering::LowerOperation(SDValue Op,
}
}

unsigned MSP430TargetLowering::getShiftAmountThreshold(EVT VT) const {
return 2;
}
//===----------------------------------------------------------------------===//
// MSP430 Inline Assembly Support
//===----------------------------------------------------------------------===//
Expand Down
2 changes: 2 additions & 0 deletions lib/Target/MSP430/MSP430ISelLowering.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
20 changes: 6 additions & 14 deletions test/CodeGen/MSP430/shift-amount-threshold.ll
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down

0 comments on commit 0d04cbb

Please sign in to comment.