From ffd48e3c27b2dc92629acb27d1cd5beb57b4cfbf Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Fri, 10 Nov 2017 22:50:50 +0000 Subject: [SelectionDAG] Teach SelectionDAGBuilder's getUniformBase for gather/scatter handling to accept GEPs with more than 2 operands if the middle operands are all 0s Currently we can only get a uniform base from a simple GEP with 2 operands. This causes us to miss address folding opportunities for simple global array accesses as the test case shows. This patch adds support for larger GEPs if the other indices are 0 since those don't require any additional computations to be inserted. We may also want to handle constant splats of zero here, but I'm leaving that for future work when I have a real world example. Differential Revision: https://reviews.llvm.org/D39911 llvm-svn: 317947 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp') diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index e22fe19f9f8..285f7eba099 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -3871,7 +3871,7 @@ static bool getUniformBase(const Value* &Ptr, SDValue& Base, SDValue& Index, assert(Ptr->getType()->isVectorTy() && "Uexpected pointer type"); const GetElementPtrInst *GEP = dyn_cast(Ptr); - if (!GEP || GEP->getNumOperands() > 2) + if (!GEP) return false; const Value *GEPPtr = GEP->getPointerOperand(); @@ -3880,7 +3880,14 @@ static bool getUniformBase(const Value* &Ptr, SDValue& Base, SDValue& Index, else if (!(Ptr = getSplatValue(GEPPtr))) return false; - Value *IndexVal = GEP->getOperand(1); + unsigned FinalIndex = GEP->getNumOperands() - 1; + Value *IndexVal = GEP->getOperand(FinalIndex); + + // Ensure all the other indices are 0. + for (unsigned i = 1; i < FinalIndex; ++i) + if (auto *C = dyn_cast(GEP->getOperand(i))) + if (!C->isZero()) + return false; // The operands of the GEP may be defined in another basic block. // In this case we'll not find nodes for the operands. -- cgit v1.2.3