forked from OSchip/llvm-project
[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
This commit is contained in:
parent
12c7a96064
commit
4df19b75c0
|
@ -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
|
||||
|
|
|
@ -5,6 +5,7 @@ target triple = "msp430-elf"
|
|||
define zeroext i8 @lshr8(i8 zeroext %a, i8 zeroext %cnt) nounwind readnone {
|
||||
entry:
|
||||
; CHECK-LABEL: lshr8:
|
||||
; CHECK: clrc
|
||||
; CHECK: rrc.b
|
||||
%shr = lshr i8 %a, %cnt
|
||||
ret i8 %shr
|
||||
|
@ -29,6 +30,7 @@ entry:
|
|||
define zeroext i16 @lshr16(i16 zeroext %a, i16 zeroext %cnt) nounwind readnone {
|
||||
entry:
|
||||
; CHECK-LABEL: lshr16:
|
||||
; CHECK: clrc
|
||||
; CHECK: rrc
|
||||
%shr = lshr i16 %a, %cnt
|
||||
ret i16 %shr
|
||||
|
@ -49,3 +51,26 @@ entry:
|
|||
%shl = shl i16 %a, %cnt
|
||||
ret i16 %shl
|
||||
}
|
||||
|
||||
define i16 @ashr10_i16(i16 %a) #0 {
|
||||
entry:
|
||||
; CHECK-LABEL: ashr10_i16:
|
||||
; CHECK: swpb r12
|
||||
; CHECK-NEXT: sxt r12
|
||||
; CHECK-NEXT: rra r12
|
||||
; CHECK-NEXT: rra r12
|
||||
%shr = ashr i16 %a, 10
|
||||
ret i16 %shr
|
||||
}
|
||||
|
||||
define i16 @lshr10_i16(i16 %a) #0 {
|
||||
entry:
|
||||
; CHECK-LABEL: lshr10_i16:
|
||||
; CHECK: swpb r12
|
||||
; CHECK-NEXT: mov.b r12, r12
|
||||
; CHECK-NEXT: clrc
|
||||
; CHECK-NEXT: rrc r12
|
||||
; CHECK-NEXT: rra r12
|
||||
%shr = lshr i16 %a, 10
|
||||
ret i16 %shr
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue