Changes in directory llvm/lib/Target/PowerPC:
README.txt updated: 1.92 -> 1.93 PPCInstrInfo.td updated: 1.237 -> 1.238 PPCISelLowering.cpp updated: 1.197 -> 1.198 PPCISelLowering.h updated: 1.50 -> 1.51 PPCHazardRecognizers.cpp updated: 1.12 -> 1.13 --- Log message: Implement Regression/CodeGen/PowerPC/bswap-load-store.ll by folding bswaps into i16/i32 load/stores. --- Diffs of the changes: (+103 -6) PPCHazardRecognizers.cpp | 4 +++ PPCISelLowering.cpp | 59 +++++++++++++++++++++++++++++++++++++++++++++++ PPCISelLowering.h | 14 ++++++++++- PPCInstrInfo.td | 27 +++++++++++++++++++++ README.txt | 5 --- 5 files changed, 103 insertions(+), 6 deletions(-) Index: llvm/lib/Target/PowerPC/README.txt diff -u llvm/lib/Target/PowerPC/README.txt:1.92 llvm/lib/Target/PowerPC/README.txt:1.93 --- llvm/lib/Target/PowerPC/README.txt:1.92 Wed May 17 14:02:25 2006 +++ llvm/lib/Target/PowerPC/README.txt Mon Jul 10 15:56:58 2006 @@ -3,7 +3,6 @@ TODO: * gpr0 allocation * implement do-loop -> bdnz transform -* implement powerpc-64 for darwin ===-------------------------------------------------------------------------=== @@ -238,10 +237,6 @@ ===-------------------------------------------------------------------------=== -Generate lwbrx and other byteswapping load/store instructions when reasonable. - -===-------------------------------------------------------------------------=== - Compile this: int foo(int a) { Index: llvm/lib/Target/PowerPC/PPCInstrInfo.td diff -u llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.237 llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.238 --- llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.237 Tue Jun 27 13:36:44 2006 +++ llvm/lib/Target/PowerPC/PPCInstrInfo.td Mon Jul 10 15:56:58 2006 @@ -37,6 +37,13 @@ SDTCisVT<1, i32>, SDTCisVT<2, OtherVT> ]>; +def SDT_PPClbrx : SDTypeProfile<1, 3, [ + SDTCisVT<0, i32>, SDTCisPtrTy<1>, SDTCisVT<2, OtherVT>, SDTCisVT<3, OtherVT> +]>; +def SDT_PPCstbrx : SDTypeProfile<0, 4, [ + SDTCisVT<0, i32>, SDTCisPtrTy<1>, SDTCisVT<2, OtherVT>, SDTCisVT<3, OtherVT> +]>; + //===----------------------------------------------------------------------===// // PowerPC specific DAG Nodes. // @@ -88,6 +95,9 @@ def PPCcondbranch : SDNode<"PPCISD::COND_BRANCH", SDT_PPCcondbr, [SDNPHasChain, SDNPOptInFlag]>; +def PPClbrx : SDNode<"PPCISD::LBRX", SDT_PPClbrx, [SDNPHasChain]>; +def PPCstbrx : SDNode<"PPCISD::STBRX", SDT_PPCstbrx, [SDNPHasChain]>; + //===----------------------------------------------------------------------===// // PowerPC specific transformation functions and pattern fragments. // @@ -464,6 +474,15 @@ def LWZX : XForm_1<31, 23, (ops GPRC:$rD, memrr:$src), "lwzx $rD, $src", LdStGeneral, [(set GPRC:$rD, (load xaddr:$src))]>; + + +def LHBRX : XForm_1<31, 790, (ops GPRC:$rD, memrr:$src), + "lhbrx $rD, $src", LdStGeneral, + [(set GPRC:$rD, (PPClbrx xaddr:$src,srcvalue:$dummy, i16))]>; +def LWBRX : XForm_1<31, 534, (ops GPRC:$rD, memrr:$src), + "lwbrx $rD, $src", LdStGeneral, + [(set GPRC:$rD, (PPClbrx xaddr:$src,srcvalue:$dummy, i32))]>; + } let PPC970_Unit = 1 in { // FXU Operations. @@ -517,6 +536,14 @@ def STWUX : XForm_8<31, 183, (ops GPRC:$rS, GPRC:$rA, GPRC:$rB), "stwux $rS, $rA, $rB", LdStGeneral, []>; +def STHBRX: XForm_8<31, 918, (ops GPRC:$rS, memrr:$dst), + "sthbrx $rS, $dst", LdStGeneral, + [(PPCstbrx GPRC:$rS, xaddr:$dst, srcvalue:$dummy, i16)]>, + PPC970_DGroup_Cracked; +def STWBRX: XForm_8<31, 662, (ops GPRC:$rS, memrr:$dst), + "stwbrx $rS, $dst", LdStGeneral, + [(PPCstbrx GPRC:$rS, xaddr:$dst, srcvalue:$dummy, i32)]>, + PPC970_DGroup_Cracked; } let PPC970_Unit = 1 in { // FXU Operations. def SRAWI : XForm_10<31, 824, (ops GPRC:$rA, GPRC:$rS, u5imm:$SH), Index: llvm/lib/Target/PowerPC/PPCISelLowering.cpp diff -u llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.197 llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.198 --- llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.197 Tue Jun 27 15:14:52 2006 +++ llvm/lib/Target/PowerPC/PPCISelLowering.cpp Mon Jul 10 15:56:58 2006 @@ -266,6 +266,7 @@ setTargetDAGCombine(ISD::SINT_TO_FP); setTargetDAGCombine(ISD::STORE); setTargetDAGCombine(ISD::BR_CC); + setTargetDAGCombine(ISD::BSWAP); computeRegisterProperties(); } @@ -296,6 +297,8 @@ case PPCISD::MFCR: return "PPCISD::MFCR"; case PPCISD::VCMP: return "PPCISD::VCMP"; case PPCISD::VCMPo: return "PPCISD::VCMPo"; + case PPCISD::LBRX: return "PPCISD::LBRX"; + case PPCISD::STBRX: return "PPCISD::STBRX"; case PPCISD::COND_BRANCH: return "PPCISD::COND_BRANCH"; } } @@ -2344,6 +2347,56 @@ DCI.AddToWorklist(Val.Val); return Val; } + + // Turn STORE (BSWAP) -> sthbrx/stwbrx. + if (N->getOperand(1).getOpcode() == ISD::BSWAP && + N->getOperand(1).Val->hasOneUse() && + (N->getOperand(1).getValueType() == MVT::i32 || + N->getOperand(1).getValueType() == MVT::i16)) { + SDOperand BSwapOp = N->getOperand(1).getOperand(0); + // Do an any-extend to 32-bits if this is a half-word input. + if (BSwapOp.getValueType() == MVT::i16) + BSwapOp = DAG.getNode(ISD::ANY_EXTEND, MVT::i32, BSwapOp); + + return DAG.getNode(PPCISD::STBRX, MVT::Other, N->getOperand(0), BSwapOp, + N->getOperand(2), N->getOperand(3), + DAG.getValueType(N->getOperand(1).getValueType())); + } + break; + case ISD::BSWAP: + // Turn BSWAP (LOAD) -> lhbrx/lwbrx. + if (N->getOperand(0).getOpcode() == ISD::LOAD && + N->getOperand(0).hasOneUse() && + (N->getValueType(0) == MVT::i32 || N->getValueType(0) == MVT::i16)) { + SDOperand Load = N->getOperand(0); + // Create the byte-swapping load. + std::vector<MVT::ValueType> VTs; + VTs.push_back(MVT::i32); + VTs.push_back(MVT::Other); + std::vector<SDOperand> Ops; + Ops.push_back(Load.getOperand(0)); // Chain + Ops.push_back(Load.getOperand(1)); // Ptr + Ops.push_back(Load.getOperand(2)); // SrcValue + Ops.push_back(DAG.getValueType(N->getValueType(0))); // VT + SDOperand BSLoad = DAG.getNode(PPCISD::LBRX, VTs, Ops); + + // If this is an i16 load, insert the truncate. + SDOperand ResVal = BSLoad; + if (N->getValueType(0) == MVT::i16) + ResVal = DAG.getNode(ISD::TRUNCATE, MVT::i16, BSLoad); + + // First, combine the bswap away. This makes the value produced by the + // load dead. + DCI.CombineTo(N, ResVal); + + // Next, combine the load away, we give it a bogus result value but a real + // chain result. The result value is dead because the bswap is dead. + DCI.CombineTo(Load.Val, ResVal, BSLoad.getValue(1)); + + // Return N so it doesn't get rechecked! + return SDOperand(N, 0); + } + break; case PPCISD::VCMP: { // If a VCMPo node already exists with exactly the same operands as this @@ -2477,6 +2530,12 @@ KnownOne = 0; switch (Op.getOpcode()) { default: break; + case PPCISD::LBRX: { + // lhbrx is known to have the top bits cleared out. + if (cast<VTSDNode>(Op.getOperand(3))->getVT() == MVT::i16) + KnownZero = 0xFFFF0000; + break; + } case ISD::INTRINSIC_WO_CHAIN: { switch (cast<ConstantSDNode>(Op.getOperand(0))->getValue()) { default: break; Index: llvm/lib/Target/PowerPC/PPCISelLowering.h diff -u llvm/lib/Target/PowerPC/PPCISelLowering.h:1.50 llvm/lib/Target/PowerPC/PPCISelLowering.h:1.51 --- llvm/lib/Target/PowerPC/PPCISelLowering.h:1.50 Wed May 17 14:00:46 2006 +++ llvm/lib/Target/PowerPC/PPCISelLowering.h Mon Jul 10 15:56:58 2006 @@ -111,7 +111,19 @@ /// condition register to branch on, OPC is the branch opcode to use (e.g. /// PPC::BLE), DESTBB is the destination block to branch to, and INFLAG is /// an optional input flag argument. - COND_BRANCH + COND_BRANCH, + + /// CHAIN = STBRX CHAIN, GPRC, Ptr, SRCVALUE, Type - This is a + /// byte-swapping store instruction. It byte-swaps the low "Type" bits of + /// the GPRC input, then stores it through Ptr. Type can be either i16 or + /// i32. + STBRX, + + /// GPRC, CHAIN = LBRX CHAIN, Ptr, SRCVALUE, Type - This is a + /// byte-swapping load instruction. It loads "Type" bits, byte swaps it, + /// then puts it in the bottom bits of the GPRC. TYPE can be either i16 + /// or i32. + LBRX }; } Index: llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp diff -u llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp:1.12 llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp:1.13 --- llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp:1.12 Tue Mar 21 23:30:33 2006 +++ llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp Mon Jul 10 15:56:58 2006 @@ -178,6 +178,7 @@ case PPC::LHZ: case PPC::LHZX: case PPC::LVEHX: + case PPC::LHBRX: LoadSize = 2; break; case PPC::LFS: @@ -188,6 +189,7 @@ case PPC::LWA: case PPC::LWAX: case PPC::LVEWX: + case PPC::LWBRX: LoadSize = 4; break; case PPC::LFD: @@ -233,6 +235,7 @@ case PPC::STHX: case PPC::STH: case PPC::STVEHX: + case PPC::STHBRX: ThisStoreSize = 2; break; case PPC::STFS: @@ -243,6 +246,7 @@ case PPC::STW: case PPC::STVEWX: case PPC::STFIWX: + case PPC::STWBRX: ThisStoreSize = 4; break; case PPC::STD_32: _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits