From a298964d22a203d21bafe1f649a46ba8a2592ca4 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Sat, 19 Oct 2019 16:57:02 +0000 Subject: [PATCH] [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 --- llvm/include/llvm/CodeGen/TargetLowering.h | 6 +++++ llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp | 26 ++++++++++++---------- llvm/lib/Target/MSP430/MSP430ISelLowering.cpp | 3 +++ llvm/lib/Target/MSP430/MSP430ISelLowering.h | 2 ++ llvm/test/CodeGen/MSP430/shift-amount-threshold.ll | 20 +++++------------ 5 files changed, 31 insertions(+), 26 deletions(-) diff --git a/llvm/include/llvm/CodeGen/TargetLowering.h b/llvm/include/llvm/CodeGen/TargetLowering.h index 72c2593..d346d09 100644 --- a/llvm/include/llvm/CodeGen/TargetLowering.h +++ b/llvm/include/llvm/CodeGen/TargetLowering.h @@ -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 // diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp index 0163ec3..9ab1324 100644 --- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -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(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(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))); } } } diff --git a/llvm/lib/Target/MSP430/MSP430ISelLowering.cpp b/llvm/lib/Target/MSP430/MSP430ISelLowering.cpp index a83fd13..64169d1 100644 --- a/llvm/lib/Target/MSP430/MSP430ISelLowering.cpp +++ b/llvm/lib/Target/MSP430/MSP430ISelLowering.cpp @@ -353,6 +353,9 @@ SDValue MSP430TargetLowering::LowerOperation(SDValue Op, } } +unsigned MSP430TargetLowering::getShiftAmountThreshold(EVT VT) const { + return 2; +} //===----------------------------------------------------------------------===// // MSP430 Inline Assembly Support //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/MSP430/MSP430ISelLowering.h b/llvm/lib/Target/MSP430/MSP430ISelLowering.h index ee6b631..9224e5e 100644 --- a/llvm/lib/Target/MSP430/MSP430ISelLowering.h +++ b/llvm/lib/Target/MSP430/MSP430ISelLowering.h @@ -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; diff --git a/llvm/test/CodeGen/MSP430/shift-amount-threshold.ll b/llvm/test/CodeGen/MSP430/shift-amount-threshold.ll index a9c25a4..633cd785 100644 --- a/llvm/test/CodeGen/MSP430/shift-amount-threshold.ll +++ b/llvm/test/CodeGen/MSP430/shift-amount-threshold.ll @@ -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 -- 2.7.4