Author: Justin Hibbits Date: 2020-05-12T16:53:25-05:00 New Revision: b901070f406129e71f9057357486ef8e1101ad6d
URL: https://github.com/llvm/llvm-project/commit/b901070f406129e71f9057357486ef8e1101ad6d DIFF: https://github.com/llvm/llvm-project/commit/b901070f406129e71f9057357486ef8e1101ad6d.diff LOG: [PowerPC] Relax the restrictions on loading doubles with SPE The original commit forced all 64-bit values to be loaded from indexed registers, regardless of how close they were located to a given base register. This relaxes that, and permits some to be immediate-indexed if they fit within a signed 255 (really 248, 8-byte aligned mask) byte window. Patch by kthomsen. Added: Modified: llvm/lib/Target/PowerPC/PPCISelLowering.cpp llvm/lib/Target/PowerPC/PPCISelLowering.h Removed: ################################################################################ diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp index 79fbb160e8bf..4a733986412c 100644 --- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp @@ -2359,19 +2359,42 @@ bool llvm::isIntS16Immediate(SDValue Op, int16_t &Imm) { return isIntS16Immediate(Op.getNode(), Imm); } +/// isIntU8Immediate - This method tests to see if the node is either a 32-bit +/// or 64-bit immediate, and if the value can be accurately represented as a +/// zero (unsigned) extension from an 8-bit value. If so, this returns true and +/// the immediate. +bool llvm::isIntU8Immediate(SDNode *N, uint8_t &Imm) { + if (!isa<ConstantSDNode>(N)) + return false; + Imm = (uint8_t)cast<ConstantSDNode>(N)->getZExtValue(); + if (N->getValueType(0) == MVT::i32) + return Imm == (int32_t)cast<ConstantSDNode>(N)->getZExtValue(); + else + return Imm == (int64_t)cast<ConstantSDNode>(N)->getZExtValue(); +} +bool llvm::isIntU8Immediate(SDValue Op, uint8_t &Imm) { + return isIntU8Immediate(Op.getNode(), Imm); +} -/// SelectAddressEVXRegReg - Given the specified address, check to see if it can -/// be represented as an indexed [r+r] operation. +/// SelectAddressEVXRegReg - Given the specified address, check to see if it +/// must be represented as an indexed [r+r] operation for EVLDD and EVSTD +/// instructions. If the address is known now, it will be checked if it fits +/// into the 8-bit offset, with an alignment of 8. bool PPCTargetLowering::SelectAddressEVXRegReg(SDValue N, SDValue &Base, SDValue &Index, SelectionDAG &DAG) const { + const unsigned EVXEncodingAlignment = 8; for (SDNode::use_iterator UI = N->use_begin(), E = N->use_end(); UI != E; ++UI) { if (MemSDNode *Memop = dyn_cast<MemSDNode>(*UI)) { if (Memop->getMemoryVT() == MVT::f64) { - Base = N.getOperand(0); - Index = N.getOperand(1); - return true; + uint8_t imm = 0; + if (isIntU8Immediate(N.getOperand(1), imm) && + !(imm % EVXEncodingAlignment)) + return false; // Offset is okay for the 8-bit index + Base = N.getOperand(0); + Index = N.getOperand(1); + return true; // Offset is unknown or too large, so use [r+r] } } } diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.h b/llvm/lib/Target/PowerPC/PPCISelLowering.h index 41046df6c043..9235d3f30f4e 100644 --- a/llvm/lib/Target/PowerPC/PPCISelLowering.h +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.h @@ -1265,6 +1265,9 @@ namespace llvm { bool isIntS16Immediate(SDNode *N, int16_t &Imm); bool isIntS16Immediate(SDValue Op, int16_t &Imm); + bool isIntU8Immediate(SDNode *N, uint8_t &Imm); + bool isIntU8Immediate(SDValue Op, uint8_t &Imm); + } // end namespace llvm #endif // LLVM_TARGET_POWERPC_PPC32ISELLOWERING_H _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits