Please use GitHub pull requests for new patches. Phabricator shutdown timeline
Changeset View
Changeset View
Standalone View
Standalone View
llvm/lib/Target/PowerPC/PPCISelLowering.cpp
- This file is larger than 256 KB, so syntax highlighting is disabled by default.
Show First 20 Lines • Show All 604 Lines • ▼ Show 20 Lines | PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM, | ||||
// To handle counter-based loop conditions. | // To handle counter-based loop conditions. | ||||
setOperationAction(ISD::INTRINSIC_W_CHAIN, MVT::i1, Custom); | setOperationAction(ISD::INTRINSIC_W_CHAIN, MVT::i1, Custom); | ||||
setOperationAction(ISD::INTRINSIC_VOID, MVT::i8, Custom); | setOperationAction(ISD::INTRINSIC_VOID, MVT::i8, Custom); | ||||
setOperationAction(ISD::INTRINSIC_VOID, MVT::i16, Custom); | setOperationAction(ISD::INTRINSIC_VOID, MVT::i16, Custom); | ||||
setOperationAction(ISD::INTRINSIC_VOID, MVT::i32, Custom); | setOperationAction(ISD::INTRINSIC_VOID, MVT::i32, Custom); | ||||
setOperationAction(ISD::INTRINSIC_VOID, MVT::Other, Custom); | setOperationAction(ISD::INTRINSIC_VOID, MVT::Other, Custom); | ||||
setOperationAction(ISD::VP_LOAD, MVT::i32, Promote); | |||||
setOperationAction(ISD::VP_STORE, MVT::i32, Promote); | |||||
// Comparisons that require checking two conditions. | // Comparisons that require checking two conditions. | ||||
if (Subtarget.hasSPE()) { | if (Subtarget.hasSPE()) { | ||||
setCondCodeAction(ISD::SETO, MVT::f32, Expand); | setCondCodeAction(ISD::SETO, MVT::f32, Expand); | ||||
setCondCodeAction(ISD::SETO, MVT::f64, Expand); | setCondCodeAction(ISD::SETO, MVT::f64, Expand); | ||||
setCondCodeAction(ISD::SETUO, MVT::f32, Expand); | setCondCodeAction(ISD::SETUO, MVT::f32, Expand); | ||||
setCondCodeAction(ISD::SETUO, MVT::f64, Expand); | setCondCodeAction(ISD::SETUO, MVT::f64, Expand); | ||||
} | } | ||||
setCondCodeAction(ISD::SETULT, MVT::f32, Expand); | setCondCodeAction(ISD::SETULT, MVT::f32, Expand); | ||||
▲ Show 20 Lines • Show All 700 Lines • ▼ Show 20 Lines | |||||
setTargetDAGCombine(ISD::MUL); | setTargetDAGCombine(ISD::MUL); | ||||
setTargetDAGCombine(ISD::FMA); | setTargetDAGCombine(ISD::FMA); | ||||
setTargetDAGCombine(ISD::SINT_TO_FP); | setTargetDAGCombine(ISD::SINT_TO_FP); | ||||
setTargetDAGCombine(ISD::BUILD_VECTOR); | setTargetDAGCombine(ISD::BUILD_VECTOR); | ||||
if (Subtarget.hasFPCVT()) | if (Subtarget.hasFPCVT()) | ||||
setTargetDAGCombine(ISD::UINT_TO_FP); | setTargetDAGCombine(ISD::UINT_TO_FP); | ||||
setTargetDAGCombine(ISD::LOAD); | setTargetDAGCombine(ISD::LOAD); | ||||
setTargetDAGCombine(ISD::STORE); | setTargetDAGCombine(ISD::STORE); | ||||
setTargetDAGCombine(ISD::VP_LOAD); | |||||
setTargetDAGCombine(ISD::VP_STORE); | |||||
setTargetDAGCombine(ISD::BR_CC); | setTargetDAGCombine(ISD::BR_CC); | ||||
if (Subtarget.useCRBits()) | if (Subtarget.useCRBits()) | ||||
setTargetDAGCombine(ISD::BRCOND); | setTargetDAGCombine(ISD::BRCOND); | ||||
setTargetDAGCombine(ISD::BSWAP); | setTargetDAGCombine(ISD::BSWAP); | ||||
setTargetDAGCombine(ISD::INTRINSIC_WO_CHAIN); | setTargetDAGCombine(ISD::INTRINSIC_WO_CHAIN); | ||||
setTargetDAGCombine(ISD::INTRINSIC_W_CHAIN); | setTargetDAGCombine(ISD::INTRINSIC_W_CHAIN); | ||||
setTargetDAGCombine(ISD::INTRINSIC_VOID); | setTargetDAGCombine(ISD::INTRINSIC_VOID); | ||||
▲ Show 20 Lines • Show All 13,873 Lines • ▼ Show 20 Lines | if (LD->isUnindexed() && VT.isVector() && | ||||
// The output of the permutation is our loaded result, the TokenFactor is | // The output of the permutation is our loaded result, the TokenFactor is | ||||
// our new chain. | // our new chain. | ||||
DCI.CombineTo(N, Perm, TF); | DCI.CombineTo(N, Perm, TF); | ||||
return SDValue(N, 0); | return SDValue(N, 0); | ||||
} | } | ||||
} | } | ||||
break; | break; | ||||
case ISD::VP_LOAD: { | |||||
if (!DCI.isAfterLegalizeDAG()) | |||||
break; | |||||
auto *LD = cast<VPLoadSDNode>(N); | |||||
SDValue Length = LD->getVectorLength(); | |||||
SDNode *LengthNode = Length.getNode(); | |||||
// We don't want to shift on subsequent combines. | |||||
// As a workaround, we check if the length node is a constant shift of at | |||||
// least 56. The shift+mul might get combined, so we also check for a | |||||
// corresponding constant multiplication. | |||||
if (LengthNode->getOpcode() == ISD::SHL) | |||||
if (isa<ConstantSDNode>(Length.getOperand(1).getNode())) | |||||
if (Length.getConstantOperandVal(1) >= 56) | |||||
return SDValue(); | |||||
if (LengthNode->getOpcode() == ISD::MUL) | |||||
if (isa<ConstantSDNode>(Length.getOperand(1).getNode())) | |||||
if (Length.getConstantOperandVal(1) >> 56) | |||||
return SDValue(); | |||||
SDLoc DL(N); | |||||
unsigned EltBytes = N->getValueType(0).getScalarSizeInBits() / 8; | |||||
nemanjai: The semantics here are very different from what I assumed. I assumed one can load 5 byte… | |||||
SDValue ExtLength = DAG.getZExtOrTrunc(Length, DL, MVT::i64); | |||||
SDValue ShiftedLength = | |||||
DAG.getNode(ISD::SHL, DL, MVT::i64, ExtLength, | |||||
DAG.getConstant(56 + countTrailingZeros(EltBytes), DL, | |||||
getPointerTy(DAG.getDataLayout()))); | |||||
SmallVector<SDValue, 5> NewOps(N->op_begin(), N->op_end()); | |||||
NewOps[4] = ShiftedLength; | |||||
Not Done ReplyInline Actionsshould this be NewOps[3] instead? bmahjour: should this be NewOps[3] instead? | |||||
return SDValue(DAG.UpdateNodeOperands(N, NewOps), 0); | |||||
break; | |||||
} | |||||
case ISD::VP_STORE: { | |||||
if (!DCI.isAfterLegalizeDAG()) | |||||
break; | |||||
auto *ST = cast<VPStoreSDNode>(N); | |||||
SDValue Length = ST->getVectorLength(); | |||||
SDNode *LengthNode = Length.getNode(); | |||||
if (LengthNode->getOpcode() == ISD::SHL) | |||||
if (isa<ConstantSDNode>(Length.getOperand(1).getNode())) | |||||
if (Length.getConstantOperandVal(1) >= 56) | |||||
return SDValue(); | |||||
if (LengthNode->getOpcode() == ISD::MUL) | |||||
if (isa<ConstantSDNode>(Length.getOperand(1).getNode())) | |||||
if (Length.getConstantOperandVal(1) >> 56) | |||||
return SDValue(); | |||||
SDLoc DL(N); | |||||
unsigned EltBytes = | |||||
N->getOperand(1).getValueType().getScalarSizeInBits() / 8; | |||||
SDValue ExtLength = DAG.getZExtOrTrunc(Length, DL, MVT::i64); | |||||
SDValue ShiftedLength = | |||||
DAG.getNode(ISD::SHL, DL, MVT::i64, ExtLength, | |||||
DAG.getConstant(56 + countTrailingZeros(EltBytes), DL, | |||||
getPointerTy(DAG.getDataLayout()))); | |||||
SmallVector<SDValue, 5> NewOps(N->op_begin(), N->op_end()); | |||||
NewOps[5] = ShiftedLength; | |||||
Not Done ReplyInline Actions5 seems out or range. Shouldn't it be NewOps[4] = ShiftedLength; ? bmahjour: 5 seems out or range. Shouldn't it be `NewOps[4] = ShiftedLength;` ? | |||||
return SDValue(DAG.UpdateNodeOperands(N, NewOps), 0); | |||||
break; | |||||
} | |||||
case ISD::INTRINSIC_WO_CHAIN: { | case ISD::INTRINSIC_WO_CHAIN: { | ||||
bool isLittleEndian = Subtarget.isLittleEndian(); | bool isLittleEndian = Subtarget.isLittleEndian(); | ||||
unsigned IID = cast<ConstantSDNode>(N->getOperand(0))->getZExtValue(); | unsigned IID = cast<ConstantSDNode>(N->getOperand(0))->getZExtValue(); | ||||
Intrinsic::ID Intr = (isLittleEndian ? Intrinsic::ppc_altivec_lvsr | Intrinsic::ID Intr = (isLittleEndian ? Intrinsic::ppc_altivec_lvsr | ||||
: Intrinsic::ppc_altivec_lvsl); | : Intrinsic::ppc_altivec_lvsl); | ||||
if (IID == Intr && N->getOperand(1)->getOpcode() == ISD::ADD) { | if (IID == Intr && N->getOperand(1)->getOpcode() == ISD::ADD) { | ||||
SDValue Add = N->getOperand(1); | SDValue Add = N->getOperand(1); | ||||
▲ Show 20 Lines • Show All 2,488 Lines • Show Last 20 Lines |
The semantics here are very different from what I assumed. I assumed one can load 5 byte elements of a v16i8 vector by using the v16i8 type and a length of 5. But we have to use a different type (i.e. v5i8)?