[lanai] Add custom lowering for SRL_PARTS i32.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@266349 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Jacques Pienaar 2016-04-14 17:59:22 +00:00
parent bd1372842e
commit 26f23b1dfa
3 changed files with 56 additions and 1 deletions

View File

@ -104,7 +104,7 @@ LanaiTargetLowering::LanaiTargetLowering(const TargetMachine &TM,
setOperationAction(ISD::ROTR, MVT::i32, Expand);
setOperationAction(ISD::ROTL, MVT::i32, Expand);
setOperationAction(ISD::SHL_PARTS, MVT::i32, Expand);
setOperationAction(ISD::SRL_PARTS, MVT::i32, Expand);
setOperationAction(ISD::SRL_PARTS, MVT::i32, Custom);
setOperationAction(ISD::SRA_PARTS, MVT::i32, Expand);
setOperationAction(ISD::BSWAP, MVT::i32, Expand);
@ -169,6 +169,8 @@ SDValue LanaiTargetLowering::LowerOperation(SDValue Op,
return LowerSELECT_CC(Op, DAG);
case ISD::SETCC:
return LowerSETCC(Op, DAG);
case ISD::SRL_PARTS:
return LowerSRL_PARTS(Op, DAG);
case ISD::VASTART:
return LowerVASTART(Op, DAG);
case ISD::DYNAMIC_STACKALLOC:
@ -1205,3 +1207,43 @@ SDValue LanaiTargetLowering::LowerJumpTable(SDValue Op,
return Result;
}
}
SDValue LanaiTargetLowering::LowerSRL_PARTS(SDValue Op,
SelectionDAG &DAG) const {
MVT VT = Op.getSimpleValueType();
unsigned VTBits = VT.getSizeInBits();
SDLoc dl(Op);
SDValue ShOpLo = Op.getOperand(0);
SDValue ShOpHi = Op.getOperand(1);
SDValue ShAmt = Op.getOperand(2);
// Performs the following for a >> b:
// unsigned r_high = a_high >> b;
// r_high = (32 - b <= 0) ? 0 : r_high;
//
// unsigned r_low = a_low >> b;
// r_low = (32 - b <= 0) ? r_high : r_low;
// r_low = (b == 0) ? r_low : r_low | (a_high << (32 - b));
// return (unsigned long long)r_high << 32 | r_low;
// Note: This takes advantage of Lanai's shift behavior to avoid needing to
// mask the shift amount.
SDValue Zero = DAG.getConstant(0, dl, MVT::i32);
SDValue NegatedPlus32 = DAG.getNode(
ISD::SUB, dl, MVT::i32, DAG.getConstant(VTBits, dl, MVT::i32), ShAmt);
SDValue SetCC = DAG.getSetCC(dl, MVT::i32, NegatedPlus32, Zero, ISD::SETLE);
SDValue Hi = DAG.getNode(ISD::SRL, dl, MVT::i32, ShOpHi, ShAmt);
Hi = DAG.getSelect(dl, MVT::i32, SetCC, Zero, Hi);
SDValue Lo = DAG.getNode(ISD::SRL, dl, MVT::i32, ShOpLo, ShAmt);
Lo = DAG.getSelect(dl, MVT::i32, SetCC, Hi, Lo);
SDValue CarryBits =
DAG.getNode(ISD::SHL, dl, MVT::i32, ShOpHi, NegatedPlus32);
SDValue ShiftIsZero = DAG.getSetCC(dl, MVT::i32, ShAmt, Zero, ISD::SETEQ);
Lo = DAG.getSelect(dl, MVT::i32, ShiftIsZero, Lo,
DAG.getNode(ISD::OR, dl, MVT::i32, Lo, CarryBits));
SDValue Ops[2] = {Lo, Hi};
return DAG.getMergeValues(Ops, dl);
}

View File

@ -87,6 +87,7 @@ public:
SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerSRL_PARTS(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) const;
unsigned getRegisterByName(const char *RegName, EVT VT,

View File

@ -0,0 +1,12 @@
; RUN: llc < %s -mtriple=lanai-unknown-unknown | FileCheck %s
; Test right-shift i64 lowering does not result in call being inserted.
; CHECK-LABEL: shift
; CHECK-NOT: bt __lshrdi3
; CHECK: %rv
define i64 @shift(i64 inreg, i32 inreg) {
%3 = zext i32 %1 to i64
%4 = lshr i64 %0, %3
ret i64 %4
}