Legalize is no longer limited to cleverness with just constant shift amounts.

Allow it to be clever when possible and fall back to the gross code when needed.

This allows us to compile:

long long foo1(long long X, int C) {
  return X << (C|32);
}
long long foo2(long long X, int C) {
  return X << (C&~32);
}

to:
_foo1:
        rlwinm r2, r5, 0, 27, 31
        slw r3, r4, r2
        li r4, 0
        blr


        .globl  _foo2
        .align  4
_foo2:
        rlwinm r2, r5, 0, 27, 25
        subfic r5, r2, 32
        slw r3, r3, r2
        srw r5, r4, r5
        or r3, r3, r5
        slw r4, r4, r2
        blr

instead of:

_foo1:
        ori r2, r5, 32
        subfic r5, r2, 32
        addi r6, r2, -32
        srw r5, r4, r5
        slw r3, r3, r2
        slw r6, r4, r6
        or r3, r3, r5
        slw r4, r4, r2
        or r3, r3, r6
        blr


        .globl  _foo2
        .align  4
_foo2:
        rlwinm r2, r5, 0, 27, 25
        subfic r5, r2, 32
        addi r6, r2, -32
        srw r5, r4, r5
        slw r3, r3, r2
        slw r6, r4, r6
        or r3, r3, r5
        slw r4, r4, r2
        or r3, r3, r6
        blr


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@30507 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2006-09-20 03:47:40 +00:00
parent 0ea26ca45b
commit 3fe6c1d389

View File

@ -181,9 +181,9 @@ PPCTargetLowering::PPCTargetLowering(TargetMachine &TM)
setOperationAction(ISD::BUILD_PAIR, MVT::i64, Expand);
} else {
// 32 bit PowerPC wants to expand i64 shifts itself.
setOperationAction(ISD::SHL, MVT::i64, Custom);
setOperationAction(ISD::SRL, MVT::i64, Custom);
setOperationAction(ISD::SRA, MVT::i64, Custom);
setOperationAction(ISD::SHL_PARTS, MVT::i32, Custom);
setOperationAction(ISD::SRA_PARTS, MVT::i32, Custom);
setOperationAction(ISD::SRL_PARTS, MVT::i32, Custom);
}
if (TM.getSubtarget<PPCSubtarget>().hasAltivec()) {
@ -1412,20 +1412,15 @@ static SDOperand LowerSINT_TO_FP(SDOperand Op, SelectionDAG &DAG) {
return FP;
}
static SDOperand LowerSHL(SDOperand Op, SelectionDAG &DAG,
MVT::ValueType PtrVT) {
assert(Op.getValueType() == MVT::i64 &&
static SDOperand LowerSHL_PARTS(SDOperand Op, SelectionDAG &DAG) {
assert(Op.getNumOperands() == 3 && Op.getValueType() == MVT::i32 &&
Op.getOperand(1).getValueType() == MVT::i32 && "Unexpected SHL!");
// The generic code does a fine job expanding shift by a constant.
if (isa<ConstantSDNode>(Op.getOperand(1))) return SDOperand();
// Otherwise, expand into a bunch of logical ops. Note that these ops
// Expand into a bunch of logical ops. Note that these ops
// depend on the PPC behavior for oversized shift amounts.
SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op.getOperand(0),
DAG.getConstant(0, PtrVT));
SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op.getOperand(0),
DAG.getConstant(1, PtrVT));
SDOperand Amt = Op.getOperand(1);
SDOperand Lo = Op.getOperand(0);
SDOperand Hi = Op.getOperand(1);
SDOperand Amt = Op.getOperand(2);
SDOperand Tmp1 = DAG.getNode(ISD::SUB, MVT::i32,
DAG.getConstant(32, MVT::i32), Amt);
@ -1437,23 +1432,20 @@ static SDOperand LowerSHL(SDOperand Op, SelectionDAG &DAG,
SDOperand Tmp6 = DAG.getNode(PPCISD::SHL, MVT::i32, Lo, Tmp5);
SDOperand OutHi = DAG.getNode(ISD::OR, MVT::i32, Tmp4, Tmp6);
SDOperand OutLo = DAG.getNode(PPCISD::SHL, MVT::i32, Lo, Amt);
return DAG.getNode(ISD::BUILD_PAIR, MVT::i64, OutLo, OutHi);
SDOperand OutOps[] = { OutLo, OutHi };
return DAG.getNode(ISD::MERGE_VALUES, DAG.getVTList(MVT::i32, MVT::i32),
OutOps, 2);
}
static SDOperand LowerSRL(SDOperand Op, SelectionDAG &DAG,
MVT::ValueType PtrVT) {
assert(Op.getValueType() == MVT::i64 &&
Op.getOperand(1).getValueType() == MVT::i32 && "Unexpected SHL!");
// The generic code does a fine job expanding shift by a constant.
if (isa<ConstantSDNode>(Op.getOperand(1))) return SDOperand();
static SDOperand LowerSRL_PARTS(SDOperand Op, SelectionDAG &DAG) {
assert(Op.getNumOperands() == 3 && Op.getValueType() == MVT::i32 &&
Op.getOperand(1).getValueType() == MVT::i32 && "Unexpected SRL!");
// Otherwise, expand into a bunch of logical ops. Note that these ops
// depend on the PPC behavior for oversized shift amounts.
SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op.getOperand(0),
DAG.getConstant(0, PtrVT));
SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op.getOperand(0),
DAG.getConstant(1, PtrVT));
SDOperand Amt = Op.getOperand(1);
SDOperand Lo = Op.getOperand(0);
SDOperand Hi = Op.getOperand(1);
SDOperand Amt = Op.getOperand(2);
SDOperand Tmp1 = DAG.getNode(ISD::SUB, MVT::i32,
DAG.getConstant(32, MVT::i32), Amt);
@ -1465,22 +1457,19 @@ static SDOperand LowerSRL(SDOperand Op, SelectionDAG &DAG,
SDOperand Tmp6 = DAG.getNode(PPCISD::SRL, MVT::i32, Hi, Tmp5);
SDOperand OutLo = DAG.getNode(ISD::OR, MVT::i32, Tmp4, Tmp6);
SDOperand OutHi = DAG.getNode(PPCISD::SRL, MVT::i32, Hi, Amt);
return DAG.getNode(ISD::BUILD_PAIR, MVT::i64, OutLo, OutHi);
SDOperand OutOps[] = { OutLo, OutHi };
return DAG.getNode(ISD::MERGE_VALUES, DAG.getVTList(MVT::i32, MVT::i32),
OutOps, 2);
}
static SDOperand LowerSRA(SDOperand Op, SelectionDAG &DAG,
MVT::ValueType PtrVT) {
assert(Op.getValueType() == MVT::i64 &&
static SDOperand LowerSRA_PARTS(SDOperand Op, SelectionDAG &DAG) {
assert(Op.getNumOperands() == 3 && Op.getValueType() == MVT::i32 &&
Op.getOperand(1).getValueType() == MVT::i32 && "Unexpected SRA!");
// The generic code does a fine job expanding shift by a constant.
if (isa<ConstantSDNode>(Op.getOperand(1))) return SDOperand();
// Otherwise, expand into a bunch of logical ops, followed by a select_cc.
SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op.getOperand(0),
DAG.getConstant(0, PtrVT));
SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op.getOperand(0),
DAG.getConstant(1, PtrVT));
SDOperand Amt = Op.getOperand(1);
SDOperand Lo = Op.getOperand(0);
SDOperand Hi = Op.getOperand(1);
SDOperand Amt = Op.getOperand(2);
SDOperand Tmp1 = DAG.getNode(ISD::SUB, MVT::i32,
DAG.getConstant(32, MVT::i32), Amt);
@ -1493,7 +1482,9 @@ static SDOperand LowerSRA(SDOperand Op, SelectionDAG &DAG,
SDOperand OutHi = DAG.getNode(PPCISD::SRA, MVT::i32, Hi, Amt);
SDOperand OutLo = DAG.getSelectCC(Tmp5, DAG.getConstant(0, MVT::i32),
Tmp4, Tmp6, ISD::SETLE);
return DAG.getNode(ISD::BUILD_PAIR, MVT::i64, OutLo, OutHi);
SDOperand OutOps[] = { OutLo, OutHi };
return DAG.getNode(ISD::MERGE_VALUES, DAG.getVTList(MVT::i32, MVT::i32),
OutOps, 2);
}
//===----------------------------------------------------------------------===//
@ -2217,9 +2208,9 @@ SDOperand PPCTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
case ISD::SINT_TO_FP: return LowerSINT_TO_FP(Op, DAG);
// Lower 64-bit shifts.
case ISD::SHL: return LowerSHL(Op, DAG, getPointerTy());
case ISD::SRL: return LowerSRL(Op, DAG, getPointerTy());
case ISD::SRA: return LowerSRA(Op, DAG, getPointerTy());
case ISD::SHL_PARTS: return LowerSHL_PARTS(Op, DAG);
case ISD::SRL_PARTS: return LowerSRL_PARTS(Op, DAG);
case ISD::SRA_PARTS: return LowerSRA_PARTS(Op, DAG);
// Vector-related lowering.
case ISD::BUILD_VECTOR: return LowerBUILD_VECTOR(Op, DAG);