[llvm] 113181e - [DAGCombine][MSP430] use shift amount threshold in DAGCombine (2/2)
Sanjay Patel via llvm-commits
llvm-commits at lists.llvm.org
Mon Nov 4 10:44:12 PST 2019
Author: Sanjay Patel
Date: 2019-11-04T13:41:41-05:00
New Revision: 113181e9bd05353ed562ee7b971bf7f1e58cd5de
URL: https://github.com/llvm/llvm-project/commit/113181e9bd05353ed562ee7b971bf7f1e58cd5de
DIFF: https://github.com/llvm/llvm-project/commit/113181e9bd05353ed562ee7b971bf7f1e58cd5de.diff
LOG: [DAGCombine][MSP430] use shift amount threshold in DAGCombine (2/2)
Continuation of:
D69116
Contributes to a fix for PR43559:
https://bugs.llvm.org/show_bug.cgi?id=43559
See also D69099 and D69116
Use the TLI hook in DAGCombine.cpp to guard against creating
shift nodes that are not optimal for a target.
Patch by: @joanlluch (Joan LLuch)
Differential Revision: https://reviews.llvm.org/D69120
Added:
Modified:
llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
llvm/test/CodeGen/MSP430/shift-amount-threshold.ll
Removed:
################################################################################
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index f233e64e3c95..3ba45d7f4fe0 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -9399,10 +9399,15 @@ static SDValue foldExtendedSignBitTest(SDNode *N, SelectionDAG &DAG,
// sext i1 (setgt iN X, -1) --> sra (not X), (N - 1)
// zext i1 (setgt iN X, -1) --> srl (not X), (N - 1)
SDLoc DL(N);
- SDValue NotX = DAG.getNOT(DL, X, VT);
- SDValue ShiftAmount = DAG.getConstant(VT.getSizeInBits() - 1, DL, VT);
- auto ShiftOpcode = N->getOpcode() == ISD::SIGN_EXTEND ? ISD::SRA : ISD::SRL;
- return DAG.getNode(ShiftOpcode, DL, VT, NotX, ShiftAmount);
+ unsigned ShCt = VT.getSizeInBits() - 1;
+ const TargetLowering &TLI = DAG.getTargetLoweringInfo();
+ if (ShCt <= TLI.getShiftAmountThreshold(VT)) {
+ SDValue NotX = DAG.getNOT(DL, X, VT);
+ SDValue ShiftAmount = DAG.getConstant(ShCt, DL, VT);
+ auto ShiftOpcode =
+ N->getOpcode() == ISD::SIGN_EXTEND ? ISD::SRA : ISD::SRL;
+ return DAG.getNode(ShiftOpcode, DL, VT, NotX, ShiftAmount);
+ }
}
return SDValue();
}
@@ -19951,22 +19956,28 @@ SDValue DAGCombiner::foldSelectCCToShiftAnd(const SDLoc &DL, SDValue N0,
auto *N2C = dyn_cast<ConstantSDNode>(N2.getNode());
if (N2C && ((N2C->getAPIntValue() & (N2C->getAPIntValue() - 1)) == 0)) {
unsigned ShCt = XType.getSizeInBits() - N2C->getAPIntValue().logBase2() - 1;
- SDValue ShiftAmt = DAG.getConstant(ShCt, DL, ShiftAmtTy);
- SDValue Shift = DAG.getNode(ISD::SRL, DL, XType, N0, ShiftAmt);
- AddToWorklist(Shift.getNode());
-
- if (XType.bitsGT(AType)) {
- Shift = DAG.getNode(ISD::TRUNCATE, DL, AType, Shift);
+ if (ShCt <= TLI.getShiftAmountThreshold(XType)) {
+ SDValue ShiftAmt = DAG.getConstant(ShCt, DL, ShiftAmtTy);
+ SDValue Shift = DAG.getNode(ISD::SRL, DL, XType, N0, ShiftAmt);
AddToWorklist(Shift.getNode());
- }
- if (CC == ISD::SETGT)
- Shift = DAG.getNOT(DL, Shift, AType);
+ if (XType.bitsGT(AType)) {
+ Shift = DAG.getNode(ISD::TRUNCATE, DL, AType, Shift);
+ AddToWorklist(Shift.getNode());
+ }
+
+ if (CC == ISD::SETGT)
+ Shift = DAG.getNOT(DL, Shift, AType);
- return DAG.getNode(ISD::AND, DL, AType, Shift, N2);
+ return DAG.getNode(ISD::AND, DL, AType, Shift, N2);
+ }
}
- SDValue ShiftAmt = DAG.getConstant(XType.getSizeInBits() - 1, DL, ShiftAmtTy);
+ unsigned ShCt = XType.getSizeInBits() - 1;
+ if (ShCt > TLI.getShiftAmountThreshold(XType))
+ return SDValue();
+
+ SDValue ShiftAmt = DAG.getConstant(ShCt, DL, ShiftAmtTy);
SDValue Shift = DAG.getNode(ISD::SRA, DL, XType, N0, ShiftAmt);
AddToWorklist(Shift.getNode());
@@ -20076,31 +20087,29 @@ SDValue DAGCombiner::SimplifySelectCC(const SDLoc &DL, SDValue N0, SDValue N1,
// when the condition can be materialized as an all-ones register. Any
// single bit-test can be materialized as an all-ones register with
// shift-left and shift-right-arith.
- // TODO: The operation legality checks could be loosened to include "custom",
- // but that may cause regressions for targets that do not have shift
- // instructions.
if (CC == ISD::SETEQ && N0->getOpcode() == ISD::AND &&
- N0->getValueType(0) == VT && isNullConstant(N1) && isNullConstant(N2) &&
- TLI.isOperationLegal(ISD::SHL, VT) &&
- TLI.isOperationLegal(ISD::SRA, VT)) {
+ N0->getValueType(0) == VT && isNullConstant(N1) && isNullConstant(N2)) {
SDValue AndLHS = N0->getOperand(0);
auto *ConstAndRHS = dyn_cast<ConstantSDNode>(N0->getOperand(1));
if (ConstAndRHS && ConstAndRHS->getAPIntValue().countPopulation() == 1) {
// Shift the tested bit over the sign bit.
const APInt &AndMask = ConstAndRHS->getAPIntValue();
- SDValue ShlAmt =
- DAG.getConstant(AndMask.countLeadingZeros(), SDLoc(AndLHS),
- getShiftAmountTy(AndLHS.getValueType()));
- SDValue Shl = DAG.getNode(ISD::SHL, SDLoc(N0), VT, AndLHS, ShlAmt);
-
- // Now arithmetic right shift it all the way over, so the result is either
- // all-ones, or zero.
- SDValue ShrAmt =
- DAG.getConstant(AndMask.getBitWidth() - 1, SDLoc(Shl),
- getShiftAmountTy(Shl.getValueType()));
- SDValue Shr = DAG.getNode(ISD::SRA, SDLoc(N0), VT, Shl, ShrAmt);
-
- return DAG.getNode(ISD::AND, DL, VT, Shr, N3);
+ unsigned ShCt = AndMask.getBitWidth() - 1;
+ if (ShCt <= TLI.getShiftAmountThreshold(VT)) {
+ SDValue ShlAmt =
+ DAG.getConstant(AndMask.countLeadingZeros(), SDLoc(AndLHS),
+ getShiftAmountTy(AndLHS.getValueType()));
+ SDValue Shl = DAG.getNode(ISD::SHL, SDLoc(N0), VT, AndLHS, ShlAmt);
+
+ // Now arithmetic right shift it all the way over, so the result is
+ // either all-ones, or zero.
+ SDValue ShrAmt =
+ DAG.getConstant(ShCt, SDLoc(Shl),
+ getShiftAmountTy(Shl.getValueType()));
+ SDValue Shr = DAG.getNode(ISD::SRA, SDLoc(N0), VT, Shl, ShrAmt);
+
+ return DAG.getNode(ISD::AND, DL, VT, Shr, N3);
+ }
}
}
@@ -20142,10 +20151,13 @@ SDValue DAGCombiner::SimplifySelectCC(const SDLoc &DL, SDValue N0, SDValue N1,
if (N2C->isOne())
return Temp;
+ unsigned ShCt = N2C->getAPIntValue().logBase2();
+ if (ShCt > TLI.getShiftAmountThreshold(VT))
+ return SDValue();
+
// shl setcc result by log2 n2c
return DAG.getNode(ISD::SHL, DL, N2.getValueType(), Temp,
- DAG.getConstant(N2C->getAPIntValue().logBase2(),
- SDLoc(Temp),
+ DAG.getConstant(ShCt, SDLoc(Temp),
getShiftAmountTy(Temp.getValueType())));
}
diff --git a/llvm/test/CodeGen/MSP430/shift-amount-threshold.ll b/llvm/test/CodeGen/MSP430/shift-amount-threshold.ll
index b3104e725180..bb403165fd48 100644
--- a/llvm/test/CodeGen/MSP430/shift-amount-threshold.ll
+++ b/llvm/test/CodeGen/MSP430/shift-amount-threshold.ll
@@ -58,16 +58,13 @@ entry:
define i16 @testExtendSignBit_0(i16 %x) {
; CHECK-LABEL: testExtendSignBit_0:
; CHECK: ; %bb.0: ; %entry
-; CHECK-NEXT: inv r12
-; CHECK-NEXT: swpb r12
-; CHECK-NEXT: sxt r12
-; CHECK-NEXT: rra r12
-; CHECK-NEXT: rra r12
-; CHECK-NEXT: rra r12
-; CHECK-NEXT: rra r12
-; CHECK-NEXT: rra r12
-; CHECK-NEXT: rra r12
-; CHECK-NEXT: rra r12
+; CHECK-NEXT: mov r12, r13
+; CHECK-NEXT: mov #-1, r12
+; CHECK-NEXT: tst r13
+; CHECK-NEXT: jge .LBB3_2
+; CHECK-NEXT: ; %bb.1: ; %entry
+; CHECK-NEXT: clr r12
+; CHECK-NEXT: .LBB3_2: ; %entry
; CHECK-NEXT: ret
entry:
%cmp = icmp sgt i16 %x, -1
@@ -80,17 +77,13 @@ entry:
define i16 @testExtendSignBit_1(i16 %x) {
; CHECK-LABEL: testExtendSignBit_1:
; CHECK: ; %bb.0: ; %entry
-; CHECK-NEXT: inv r12
-; CHECK-NEXT: swpb r12
-; CHECK-NEXT: mov.b r12, 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: rra r12
-; CHECK-NEXT: rra r12
+; CHECK-NEXT: mov r12, r13
+; CHECK-NEXT: mov #1, r12
+; CHECK-NEXT: tst r13
+; CHECK-NEXT: jge .LBB4_2
+; CHECK-NEXT: ; %bb.1: ; %entry
+; CHECK-NEXT: clr r12
+; CHECK-NEXT: .LBB4_2: ; %entry
; CHECK-NEXT: ret
entry:
%cmp = icmp sgt i16 %x, -1
@@ -103,16 +96,12 @@ entry:
define i16 @testShiftAnd_0(i16 %x, i16 %a) {
; CHECK-LABEL: testShiftAnd_0:
; CHECK: ; %bb.0: ; %entry
-; CHECK-NEXT: swpb r12
-; CHECK-NEXT: sxt r12
-; CHECK-NEXT: rra r12
-; CHECK-NEXT: rra r12
-; CHECK-NEXT: rra r12
-; CHECK-NEXT: rra r12
-; CHECK-NEXT: rra r12
-; CHECK-NEXT: rra r12
-; CHECK-NEXT: rra r12
-; CHECK-NEXT: and r13, r12
+; CHECK-NEXT: tst r12
+; CHECK-NEXT: jl .LBB5_2
+; CHECK-NEXT: ; %bb.1: ; %entry
+; CHECK-NEXT: clr r13
+; CHECK-NEXT: .LBB5_2: ; %entry
+; CHECK-NEXT: mov r13, r12
; CHECK-NEXT: ret
entry:
%cmp = icmp slt i16 %x, 0
@@ -125,16 +114,14 @@ entry:
define i16 @testShiftAnd_1(i16 %x) {
; CHECK-LABEL: testShiftAnd_1:
; CHECK: ; %bb.0: ; %entry
-; CHECK-NEXT: swpb r12
-; CHECK-NEXT: mov.b r12, 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: rra r12
-; CHECK-NEXT: and #2, r12
+; CHECK-NEXT: mov r12, r13
+; CHECK-NEXT: mov #1, r12
+; CHECK-NEXT: tst r13
+; CHECK-NEXT: jl .LBB6_2
+; CHECK-NEXT: ; %bb.1: ; %entry
+; CHECK-NEXT: clr r12
+; CHECK-NEXT: .LBB6_2: ; %entry
+; CHECK-NEXT: add r12, r12
; CHECK-NEXT: ret
entry:
%cmp = icmp slt i16 %x, 0
@@ -148,17 +135,12 @@ define i16 @testSimplifySelectCC_1(i16 %a, i16 %b) {
; CHECK-LABEL: testSimplifySelectCC_1:
; CHECK: ; %bb.0: ; %entry
; CHECK-NEXT: mov r12, r14
-; CHECK-NEXT: mov #1, r12
+; CHECK-NEXT: mov #32, r12
; CHECK-NEXT: cmp r14, r13
; CHECK-NEXT: jl .LBB7_2
; CHECK-NEXT: ; %bb.1: ; %entry
; CHECK-NEXT: clr r12
; CHECK-NEXT: .LBB7_2: ; %entry
-; CHECK-NEXT: add r12, r12
-; CHECK-NEXT: add r12, r12
-; CHECK-NEXT: add r12, r12
-; CHECK-NEXT: add r12, r12
-; CHECK-NEXT: add r12, r12
; CHECK-NEXT: ret
entry:
%cmp = icmp sgt i16 %a, %b
More information about the llvm-commits
mailing list