summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorAnton Korobeynikov <anton@korobeynikov.info>2018-11-19 10:43:02 +0000
committerAnton Korobeynikov <anton@korobeynikov.info>2018-11-19 10:43:02 +0000
commit4df19b75c0e9f00076ba2a29199aa28c6fb648d9 (patch)
tree885b725aa15e66df826ab7280b5cd900e8e18d35 /llvm/lib
parent12c7a96064c17ba2e60b372e50839b90aaab44bb (diff)
downloadbcm5719-llvm-4df19b75c0e9f00076ba2a29199aa28c6fb648d9.tar.gz
bcm5719-llvm-4df19b75c0e9f00076ba2a29199aa28c6fb648d9.zip
[MSP430] Optimize srl/sra in case of A >> (8 + N)
There is no variable-length shifts on MSP430. Therefore "eat" 8 bits of shift via bswap & ext. Path by Kristina Bessonova! Differential Revision: https://reviews.llvm.org/D54623 llvm-svn: 347187
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/MSP430/MSP430ISelLowering.cpp14
1 files changed, 12 insertions, 2 deletions
diff --git a/llvm/lib/Target/MSP430/MSP430ISelLowering.cpp b/llvm/lib/Target/MSP430/MSP430ISelLowering.cpp
index 1b271c782a8..73c8793aa01 100644
--- a/llvm/lib/Target/MSP430/MSP430ISelLowering.cpp
+++ b/llvm/lib/Target/MSP430/MSP430ISelLowering.cpp
@@ -950,10 +950,20 @@ SDValue MSP430TargetLowering::LowerShifts(SDValue Op,
uint64_t ShiftAmount = cast<ConstantSDNode>(N->getOperand(1))->getZExtValue();
// Expand the stuff into sequence of shifts.
- // FIXME: for some shift amounts this might be done better!
- // E.g.: foo >> (8 + N) => sxt(swpb(foo)) >> N
SDValue Victim = N->getOperand(0);
+ if ((Opc == ISD::SRA || Opc == ISD::SRL) && ShiftAmount >= 8) {
+ // foo >> (8 + N) => sxt(swpb(foo)) >> N
+ assert(VT == MVT::i16 && "Can not shift i8 by 8 and more");
+ Victim = DAG.getNode(ISD::BSWAP, dl, VT, Victim);
+ if (Opc == ISD::SRA)
+ Victim = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, VT, Victim,
+ DAG.getValueType(MVT::i8));
+ else
+ Victim = DAG.getZeroExtendInReg(Victim, dl, MVT::i8);
+ ShiftAmount -= 8;
+ }
+
if (Opc == ISD::SRL && ShiftAmount) {
// Emit a special goodness here:
// srl A, 1 => clrc; rrc A
OpenPOWER on IntegriCloud