[PATCH] D69484: [PowerPC] Relax the restrictions on loading doubles with SPE

Justin Hibbits via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Sun Oct 27 12:48:56 PDT 2019


jhibbits created this revision.
jhibbits added reviewers: nemanjai, hfinkel, joerg.
Herald added subscribers: llvm-commits, shchenz, jsji, kbarton, hiraditya.
Herald added a project: LLVM.

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.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D69484

Files:
  llvm/lib/Target/PowerPC/PPCISelLowering.cpp
  llvm/lib/Target/PowerPC/PPCISelLowering.h


Index: llvm/lib/Target/PowerPC/PPCISelLowering.h
===================================================================
--- llvm/lib/Target/PowerPC/PPCISelLowering.h
+++ llvm/lib/Target/PowerPC/PPCISelLowering.h
@@ -1234,6 +1234,9 @@
   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
Index: llvm/lib/Target/PowerPC/PPCISelLowering.cpp
===================================================================
--- llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -2245,18 +2245,43 @@
 }
 
 
-/// SelectAddressEVXRegReg - Given the specified address, check to see if it can
-/// be represented as an indexed [r+r] operation.
+/// 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
+/// 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]
       }
     }
   }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D69484.226585.patch
Type: text/x-patch
Size: 2802 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20191027/18191145/attachment.bin>


More information about the llvm-commits mailing list