diff options
| author | Reid Kleckner <rnk@google.com> | 2016-01-22 01:09:29 +0000 |
|---|---|---|
| committer | Reid Kleckner <rnk@google.com> | 2016-01-22 01:09:29 +0000 |
| commit | b7ecfa5b090aa4ca1607b6803f6a5db8a4873a65 (patch) | |
| tree | eaca292da57ddb54f76f7125a2de355f3a8f78c5 | |
| parent | b5e984992ac5fa0a0fad76886607711d884cec8f (diff) | |
| download | bcm5719-llvm-b7ecfa5b090aa4ca1607b6803f6a5db8a4873a65.tar.gz bcm5719-llvm-b7ecfa5b090aa4ca1607b6803f6a5db8a4873a65.zip | |
Revert "[SelectionDAG] Fold more offsets into GlobalAddresses"
This reverts r258296 and the follow up r258366. With this change, we
miscompiled the following program on Windows:
#include <string>
#include <iostream>
static const char kData[] = "asdf jkl;";
int main() {
std::string s(kData + 3, sizeof(kData) - 3);
std::cout << s << '\n';
}
llvm-svn: 258465
| -rw-r--r-- | llvm/include/llvm/CodeGen/SelectionDAG.h | 7 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 150 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 43 | ||||
| -rw-r--r-- | llvm/test/CodeGen/WebAssembly/address-offsets.ll | 672 | ||||
| -rw-r--r-- | llvm/test/CodeGen/X86/lea-opt.ll | 18 | ||||
| -rw-r--r-- | llvm/test/CodeGen/X86/negative-offset.ll | 18 | ||||
| -rw-r--r-- | llvm/test/CodeGen/XCore/threads.ll | 4 |
7 files changed, 84 insertions, 828 deletions
diff --git a/llvm/include/llvm/CodeGen/SelectionDAG.h b/llvm/include/llvm/CodeGen/SelectionDAG.h index 39fcc4b0498..a21e9ae881a 100644 --- a/llvm/include/llvm/CodeGen/SelectionDAG.h +++ b/llvm/include/llvm/CodeGen/SelectionDAG.h @@ -1156,10 +1156,6 @@ public: /// either of the specified value types. SDValue CreateStackTemporary(EVT VT1, EVT VT2); - SDValue FoldSymbolOffset(unsigned Opcode, EVT VT, - const GlobalAddressSDNode *GA, - const SDNode *N2); - SDValue FoldConstantArithmetic(unsigned Opcode, SDLoc DL, EVT VT, SDNode *Cst1, SDNode *Cst2); @@ -1271,9 +1267,6 @@ public: unsigned getEVTAlignment(EVT MemoryVT) const; - /// Test whether the given value is a constant int or similar node. - SDNode *isConstantIntBuildVectorOrConstantInt(SDValue N); - private: void InsertNode(SDNode *N); bool RemoveNodeFromCSEMaps(SDNode *N); diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 98caf5b2c43..c741982bc08 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -390,9 +390,6 @@ namespace { /// consecutive chains. bool findBetterNeighborChains(StoreSDNode *St); - /// Match "(X shl/srl V1) & V2" where V2 may not be present. - bool MatchRotateHalf(SDValue Op, SDValue &Shift, SDValue &Mask); - /// Holds a pointer to an LSBaseSDNode as well as information on where it /// is located in a sequence of memory operations connected by a chain. struct MemOpLink { @@ -766,6 +763,16 @@ static bool isConstantSplatVector(SDNode *N, APInt& SplatValue) { EltVT.getSizeInBits() >= SplatBitSize); } +// \brief Returns the SDNode if it is a constant integer BuildVector +// or constant integer. +static SDNode *isConstantIntBuildVectorOrConstantInt(SDValue N) { + if (isa<ConstantSDNode>(N)) + return N.getNode(); + if (ISD::isBuildVectorOfConstantSDNodes(N.getNode())) + return N.getNode(); + return nullptr; +} + // \brief Returns the SDNode if it is a constant float BuildVector // or constant float. static SDNode *isConstantFPBuildVectorOrConstantFP(SDValue N) { @@ -818,8 +825,8 @@ SDValue DAGCombiner::ReassociateOps(unsigned Opc, SDLoc DL, SDValue N0, SDValue N1) { EVT VT = N0.getValueType(); if (N0.getOpcode() == Opc) { - if (SDNode *L = DAG.isConstantIntBuildVectorOrConstantInt(N0.getOperand(1))) { - if (SDNode *R = DAG.isConstantIntBuildVectorOrConstantInt(N1)) { + if (SDNode *L = isConstantIntBuildVectorOrConstantInt(N0.getOperand(1))) { + if (SDNode *R = isConstantIntBuildVectorOrConstantInt(N1)) { // reassoc. (op (op x, c1), c2) -> (op x, (op c1, c2)) if (SDValue OpNode = DAG.FoldConstantArithmetic(Opc, DL, VT, L, R)) return DAG.getNode(Opc, DL, VT, N0.getOperand(0), OpNode); @@ -838,8 +845,8 @@ SDValue DAGCombiner::ReassociateOps(unsigned Opc, SDLoc DL, } if (N1.getOpcode() == Opc) { - if (SDNode *R = DAG.isConstantIntBuildVectorOrConstantInt(N1.getOperand(1))) { - if (SDNode *L = DAG.isConstantIntBuildVectorOrConstantInt(N0)) { + if (SDNode *R = isConstantIntBuildVectorOrConstantInt(N1.getOperand(1))) { + if (SDNode *L = isConstantIntBuildVectorOrConstantInt(N0)) { // reassoc. (op c2, (op x, c1)) -> (op x, (op c1, c2)) if (SDValue OpNode = DAG.FoldConstantArithmetic(Opc, DL, VT, R, L)) return DAG.getNode(Opc, DL, VT, N1.getOperand(0), OpNode); @@ -1650,28 +1657,34 @@ SDValue DAGCombiner::visitADD(SDNode *N) { return N0; if (N1.getOpcode() == ISD::UNDEF) return N1; - if (DAG.isConstantIntBuildVectorOrConstantInt(N0)) { - // canonicalize constant to RHS - if (!DAG.isConstantIntBuildVectorOrConstantInt(N1)) - return DAG.getNode(ISD::ADD, SDLoc(N), VT, N1, N0); - // fold (add c1, c2) -> c1+c2 - return DAG.FoldConstantArithmetic(ISD::ADD, SDLoc(N), VT, - N0.getNode(), N1.getNode()); - } + // fold (add c1, c2) -> c1+c2 + ConstantSDNode *N0C = getAsNonOpaqueConstant(N0); + ConstantSDNode *N1C = getAsNonOpaqueConstant(N1); + if (N0C && N1C) + return DAG.FoldConstantArithmetic(ISD::ADD, SDLoc(N), VT, N0C, N1C); + // canonicalize constant to RHS + if (isConstantIntBuildVectorOrConstantInt(N0) && + !isConstantIntBuildVectorOrConstantInt(N1)) + return DAG.getNode(ISD::ADD, SDLoc(N), VT, N1, N0); // fold (add x, 0) -> x if (isNullConstant(N1)) return N0; + // fold (add Sym, c) -> Sym+c + if (GlobalAddressSDNode *GA = dyn_cast<GlobalAddressSDNode>(N0)) + if (!LegalOperations && TLI.isOffsetFoldingLegal(GA) && N1C && + GA->getOpcode() == ISD::GlobalAddress) + return DAG.getGlobalAddress(GA->getGlobal(), SDLoc(N1C), VT, + GA->getOffset() + + (uint64_t)N1C->getSExtValue()); // fold ((c1-A)+c2) -> (c1+c2)-A - if (ConstantSDNode *N1C = getAsNonOpaqueConstant(N1)) { - if (N0.getOpcode() == ISD::SUB) - if (ConstantSDNode *N0C = getAsNonOpaqueConstant(N0.getOperand(0))) { - SDLoc DL(N); - return DAG.getNode(ISD::SUB, DL, VT, - DAG.getConstant(N1C->getAPIntValue()+ - N0C->getAPIntValue(), DL, VT), - N0.getOperand(1)); - } - } + if (N1C && N0.getOpcode() == ISD::SUB) + if (ConstantSDNode *N0C = getAsNonOpaqueConstant(N0.getOperand(0))) { + SDLoc DL(N); + return DAG.getNode(ISD::SUB, DL, VT, + DAG.getConstant(N1C->getAPIntValue()+ + N0C->getAPIntValue(), DL, VT), + N0.getOperand(1)); + } // reassociate add if (SDValue RADD = ReassociateOps(ISD::ADD, SDLoc(N), N0, N1)) return RADD; @@ -1866,14 +1879,11 @@ SDValue DAGCombiner::visitSUB(SDNode *N) { // FIXME: Refactor this and xor and other similar operations together. if (N0 == N1) return tryFoldToZero(SDLoc(N), TLI, VT, DAG, LegalOperations, LegalTypes); - if (DAG.isConstantIntBuildVectorOrConstantInt(N0) && - DAG.isConstantIntBuildVectorOrConstantInt(N1)) { - // fold (sub c1, c2) -> c1-c2 - return DAG.FoldConstantArithmetic(ISD::SUB, SDLoc(N), VT, - N0.getNode(), N1.getNode()); - } + // fold (sub c1, c2) -> c1-c2 ConstantSDNode *N0C = getAsNonOpaqueConstant(N0); ConstantSDNode *N1C = getAsNonOpaqueConstant(N1); + if (N0C && N1C) + return DAG.FoldConstantArithmetic(ISD::SUB, SDLoc(N), VT, N0C, N1C); // fold (sub x, c) -> (add x, -c) if (N1C) { SDLoc DL(N); @@ -2037,8 +2047,8 @@ SDValue DAGCombiner::visitMUL(SDNode *N) { N0.getNode(), N1.getNode()); // canonicalize constant to RHS (vector doesn't have to splat) - if (DAG.isConstantIntBuildVectorOrConstantInt(N0) && - !DAG.isConstantIntBuildVectorOrConstantInt(N1)) + if (isConstantIntBuildVectorOrConstantInt(N0) && + !isConstantIntBuildVectorOrConstantInt(N1)) return DAG.getNode(ISD::MUL, SDLoc(N), VT, N1, N0); // fold (mul x, 0) -> 0 if (N1IsConst && ConstValue1 == 0) @@ -2115,9 +2125,9 @@ SDValue DAGCombiner::visitMUL(SDNode *N) { } // fold (mul (add x, c1), c2) -> (add (mul x, c2), c1*c2) - if (DAG.isConstantIntBuildVectorOrConstantInt(N1) && + if (isConstantIntBuildVectorOrConstantInt(N1) && N0.getOpcode() == ISD::ADD && - DAG.isConstantIntBuildVectorOrConstantInt(N0.getOperand(1)) && + isConstantIntBuildVectorOrConstantInt(N0.getOperand(1)) && isMulAddWithConstProfitable(N, N0, N1)) return DAG.getNode(ISD::ADD, SDLoc(N), VT, DAG.getNode(ISD::MUL, SDLoc(N0), VT, @@ -2688,8 +2698,8 @@ SDValue DAGCombiner::visitIMINMAX(SDNode *N) { return DAG.FoldConstantArithmetic(N->getOpcode(), SDLoc(N), VT, N0C, N1C); // canonicalize constant to RHS - if (DAG.isConstantIntBuildVectorOrConstantInt(N0) && - !DAG.isConstantIntBuildVectorOrConstantInt(N1)) + if (isConstantIntBuildVectorOrConstantInt(N0) && + !isConstantIntBuildVectorOrConstantInt(N1)) return DAG.getNode(N->getOpcode(), SDLoc(N), VT, N1, N0); return SDValue(); @@ -3035,8 +3045,8 @@ SDValue DAGCombiner::visitAND(SDNode *N) { if (N0C && N1C && !N1C->isOpaque()) return DAG.FoldConstantArithmetic(ISD::AND, SDLoc(N), VT, N0C, N1C); // canonicalize constant to RHS - if (DAG.isConstantIntBuildVectorOrConstantInt(N0) && - !DAG.isConstantIntBuildVectorOrConstantInt(N1)) + if (isConstantIntBuildVectorOrConstantInt(N0) && + !isConstantIntBuildVectorOrConstantInt(N1)) return DAG.getNode(ISD::AND, SDLoc(N), VT, N1, N0); // fold (and x, -1) -> x if (isAllOnesConstant(N1)) @@ -3750,8 +3760,8 @@ SDValue DAGCombiner::visitOR(SDNode *N) { if (N0C && N1C && !N1C->isOpaque()) return DAG.FoldConstantArithmetic(ISD::OR, SDLoc(N), VT, N0C, N1C); // canonicalize constant to RHS - if (DAG.isConstantIntBuildVectorOrConstantInt(N0) && - !DAG.isConstantIntBuildVectorOrConstantInt(N1)) + if (isConstantIntBuildVectorOrConstantInt(N0) && + !isConstantIntBuildVectorOrConstantInt(N1)) return DAG.getNode(ISD::OR, SDLoc(N), VT, N1, N0); // fold (or x, 0) -> x if (isNullConstant(N1)) @@ -3807,9 +3817,9 @@ SDValue DAGCombiner::visitOR(SDNode *N) { } /// Match "(X shl/srl V1) & V2" where V2 may not be present. -bool DAGCombiner::MatchRotateHalf(SDValue Op, SDValue &Shift, SDValue &Mask) { +static bool MatchRotateHalf(SDValue Op, SDValue &Shift, SDValue &Mask) { if (Op.getOpcode() == ISD::AND) { - if (DAG.isConstantIntBuildVectorOrConstantInt(Op.getOperand(1))) { + if (isConstantIntBuildVectorOrConstantInt(Op.getOperand(1))) { Mask = Op.getOperand(1); Op = Op.getOperand(0); } else { @@ -4096,8 +4106,8 @@ SDValue DAGCombiner::visitXOR(SDNode *N) { if (N0C && N1C) return DAG.FoldConstantArithmetic(ISD::XOR, SDLoc(N), VT, N0C, N1C); // canonicalize constant to RHS - if (DAG.isConstantIntBuildVectorOrConstantInt(N0) && - !DAG.isConstantIntBuildVectorOrConstantInt(N1)) + if (isConstantIntBuildVectorOrConstantInt(N0) && + !isConstantIntBuildVectorOrConstantInt(N1)) return DAG.getNode(ISD::XOR, SDLoc(N), VT, N1, N0); // fold (xor x, 0) -> x if (isNullConstant(N1)) @@ -4906,7 +4916,7 @@ SDValue DAGCombiner::visitBSWAP(SDNode *N) { EVT VT = N->getValueType(0); // fold (bswap c1) -> c2 - if (DAG.isConstantIntBuildVectorOrConstantInt(N0)) + if (isConstantIntBuildVectorOrConstantInt(N0)) return DAG.getNode(ISD::BSWAP, SDLoc(N), VT, N0); // fold (bswap (bswap x)) -> x if (N0.getOpcode() == ISD::BSWAP) @@ -4919,7 +4929,7 @@ SDValue DAGCombiner::visitCTLZ(SDNode *N) { EVT VT = N->getValueType(0); // fold (ctlz c1) -> c2 - if (DAG.isConstantIntBuildVectorOrConstantInt(N0)) + if (isConstantIntBuildVectorOrConstantInt(N0)) return DAG.getNode(ISD::CTLZ, SDLoc(N), VT, N0); return SDValue(); } @@ -4929,7 +4939,7 @@ SDValue DAGCombiner::visitCTLZ_ZERO_UNDEF(SDNode *N) { EVT VT = N->getValueType(0); // fold (ctlz_zero_undef c1) -> c2 - if (DAG.isConstantIntBuildVectorOrConstantInt(N0)) + if (isConstantIntBuildVectorOrConstantInt(N0)) return DAG.getNode(ISD::CTLZ_ZERO_UNDEF, SDLoc(N), VT, N0); return SDValue(); } @@ -4939,7 +4949,7 @@ SDValue DAGCombiner::visitCTTZ(SDNode *N) { EVT VT = N->getValueType(0); // fold (cttz c1) -> c2 - if (DAG.isConstantIntBuildVectorOrConstantInt(N0)) + if (isConstantIntBuildVectorOrConstantInt(N0)) return DAG.getNode(ISD::CTTZ, SDLoc(N), VT, N0); return SDValue(); } @@ -4949,7 +4959,7 @@ SDValue DAGCombiner::visitCTTZ_ZERO_UNDEF(SDNode *N) { EVT VT = N->getValueType(0); // fold (cttz_zero_undef c1) -> c2 - if (DAG.isConstantIntBuildVectorOrConstantInt(N0)) + if (isConstantIntBuildVectorOrConstantInt(N0)) return DAG.getNode(ISD::CTTZ_ZERO_UNDEF, SDLoc(N), VT, N0); return SDValue(); } @@ -4959,7 +4969,7 @@ SDValue DAGCombiner::visitCTPOP(SDNode *N) { EVT VT = N->getValueType(0); // fold (ctpop c1) -> c2 - if (DAG.isConstantIntBuildVectorOrConstantInt(N0)) + if (isConstantIntBuildVectorOrConstantInt(N0)) return DAG.getNode(ISD::CTPOP, SDLoc(N), VT, N0); return SDValue(); } @@ -6892,7 +6902,7 @@ SDValue DAGCombiner::visitSIGN_EXTEND_INREG(SDNode *N) { return DAG.getUNDEF(VT); // fold (sext_in_reg c1) -> c1 - if (DAG.isConstantIntBuildVectorOrConstantInt(N0)) + if (isConstantIntBuildVectorOrConstantInt(N0)) return DAG.getNode(ISD::SIGN_EXTEND_INREG, SDLoc(N), VT, N0, N1); // If the input is already sign extended, just drop the extension. @@ -7011,7 +7021,7 @@ SDValue DAGCombiner::visitTRUNCATE(SDNode *N) { if (N0.getValueType() == N->getValueType(0)) return N0; // fold (truncate c1) -> c1 - if (DAG.isConstantIntBuildVectorOrConstantInt(N0)) + if (isConstantIntBuildVectorOrConstantInt(N0)) return DAG.getNode(ISD::TRUNCATE, SDLoc(N), VT, N0); // fold (truncate (truncate x)) -> (truncate x) if (N0.getOpcode() == ISD::TRUNCATE) @@ -8858,7 +8868,7 @@ SDValue DAGCombiner::visitSINT_TO_FP(SDNode *N) { EVT OpVT = N0.getValueType(); // fold (sint_to_fp c1) -> c1fp - if (DAG.isConstantIntBuildVectorOrConstantInt(N0) && + if (isConstantIntBuildVectorOrConstantInt(N0) && // ...but only if the target supports immediate floating-point values (!LegalOperations || TLI.isOperationLegalOrCustom(llvm::ISD::ConstantFP, VT))) @@ -8912,7 +8922,7 @@ SDValue DAGCombiner::visitUINT_TO_FP(SDNode *N) { EVT OpVT = N0.getValueType(); // fold (uint_to_fp c1) -> c1fp - if (DAG.isConstantIntBuildVectorOrConstantInt(N0) && + if (isConstantIntBuildVectorOrConstantInt(N0) && // ...but only if the target supports immediate floating-point values (!LegalOperations || TLI.isOperationLegalOrCustom(llvm::ISD::ConstantFP, VT))) @@ -10930,23 +10940,9 @@ struct BaseIndexOffset { } /// Parses tree in Ptr for base, index, offset addresses. - static BaseIndexOffset match(SDValue Ptr, SelectionDAG &DAG) { + static BaseIndexOffset match(SDValue Ptr) { bool IsIndexSignExt = false; - // Split up a folded GlobalAddress+Offset into its component parts. - if (GlobalAddressSDNode *GA = dyn_cast<GlobalAddressSDNode>(Ptr)) - if (GA->getOpcode() == ISD::GlobalAddress && GA->getOffset() != 0) { - return BaseIndexOffset(DAG.getGlobalAddress(GA->getGlobal(), - SDLoc(GA), - GA->getValueType(0), - /*Offset=*/0, - /*isTargetGA=*/false, - GA->getTargetFlags()), - SDValue(), - GA->getOffset(), - IsIndexSignExt); - } - // We only can pattern match BASE + INDEX + OFFSET. If Ptr is not an ADD // instruction, then it could be just the BASE or everything else we don't // know how to handle. Just use Ptr as BASE and give up. @@ -11067,7 +11063,7 @@ bool DAGCombiner::isMulAddWithConstProfitable(SDNode *MulNode, // multiply (CONST * A) after we also do the same transformation // to the "t2" instruction. if (OtherOp->getOpcode() == ISD::ADD && - DAG.isConstantIntBuildVectorOrConstantInt(OtherOp->getOperand(1)) && + isConstantIntBuildVectorOrConstantInt(OtherOp->getOperand(1)) && OtherOp->getOperand(0).getNode() == MulVar) return true; } @@ -11219,7 +11215,7 @@ void DAGCombiner::getStoreMergeAndAliasCandidates( SmallVectorImpl<LSBaseSDNode*> &AliasLoadNodes) { // This holds the base pointer, index, and the offset in bytes from the base // pointer. - BaseIndexOffset BasePtr = BaseIndexOffset::match(St->getBasePtr(), DAG); + BaseIndexOffset BasePtr = BaseIndexOffset::match(St->getBasePtr()); // We must have a base and an offset. if (!BasePtr.Base.getNode()) @@ -11257,7 +11253,7 @@ void DAGCombiner::getStoreMergeAndAliasCandidates( if (OtherST->getMemoryVT() != MemVT) continue; - BaseIndexOffset Ptr = BaseIndexOffset::match(OtherST->getBasePtr(), DAG); + BaseIndexOffset Ptr = BaseIndexOffset::match(OtherST->getBasePtr()); if (Ptr.equalBaseIndex(BasePtr)) StoreNodes.push_back(MemOpLink(OtherST, Ptr.Offset, Seq++)); @@ -11273,7 +11269,7 @@ void DAGCombiner::getStoreMergeAndAliasCandidates( break; // Find the base pointer and offset for this memory node. - BaseIndexOffset Ptr = BaseIndexOffset::match(Index->getBasePtr(), DAG); + BaseIndexOffset Ptr = BaseIndexOffset::match(Index->getBasePtr()); // Check that the base pointer is the same as the original one. if (!Ptr.equalBaseIndex(BasePtr)) @@ -11561,7 +11557,7 @@ bool DAGCombiner::MergeConsecutiveStores(StoreSDNode* St) { if (Ld->getMemoryVT() != MemVT) break; - BaseIndexOffset LdPtr = BaseIndexOffset::match(Ld->getBasePtr(), DAG); + BaseIndexOffset LdPtr = BaseIndexOffset::match(Ld->getBasePtr()); // If this is not the first ptr that we check. if (LdBasePtr.Base.getNode()) { // The base ptr must be the same. @@ -14720,7 +14716,7 @@ SDValue DAGCombiner::FindBetterChain(SDNode *N, SDValue OldChain) { bool DAGCombiner::findBetterNeighborChains(StoreSDNode* St) { // This holds the base pointer, index, and the offset in bytes from the base // pointer. - BaseIndexOffset BasePtr = BaseIndexOffset::match(St->getBasePtr(), DAG); + BaseIndexOffset BasePtr = BaseIndexOffset::match(St->getBasePtr()); // We must have a base and an offset. if (!BasePtr.Base.getNode()) @@ -14746,7 +14742,7 @@ bool DAGCombiner::findBetterNeighborChains(StoreSDNode* St) { break; // Find the base pointer and offset for this memory node. - BaseIndexOffset Ptr = BaseIndexOffset::match(Index->getBasePtr(), DAG); + BaseIndexOffset Ptr = BaseIndexOffset::match(Index->getBasePtr()); // Check that the base pointer is the same as the original one. if (!Ptr.equalBaseIndex(BasePtr)) diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 1cd5cd8ac23..893871f9448 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -3263,26 +3263,6 @@ SDValue SelectionDAG::FoldConstantArithmetic(unsigned Opcode, SDLoc DL, EVT VT, return getConstant(Folded.first, DL, VT); } -SDValue SelectionDAG::FoldSymbolOffset(unsigned Opcode, EVT VT, - const GlobalAddressSDNode *GA, - const SDNode *N2) { - if (GA->getOpcode() != ISD::GlobalAddress) - return SDValue(); - if (!TLI->isOffsetFoldingLegal(GA)) - return SDValue(); - const ConstantSDNode *Cst2 = dyn_cast<ConstantSDNode>(N2); - if (!Cst2) - return SDValue(); - int64_t Offset = Cst2->getSExtValue(); - switch (Opcode) { - case ISD::ADD: break; - case ISD::SUB: Offset = -uint64_t(Offset); break; - default: return SDValue(); - } - return getGlobalAddress(GA->getGlobal(), SDLoc(Cst2), VT, - GA->getOffset() + uint64_t(Offset)); -} - SDValue SelectionDAG::FoldConstantArithmetic(unsigned Opcode, SDLoc DL, EVT VT, SDNode *Cst1, SDNode *Cst2) { // If the opcode is a target-specific ISD node, there's nothing we can @@ -3309,13 +3289,6 @@ SDValue SelectionDAG::FoldConstantArithmetic(unsigned Opcode, SDLoc DL, EVT VT, } } - // fold (add Sym, c) -> Sym+c - if (GlobalAddressSDNode *GA = dyn_cast<GlobalAddressSDNode>(Cst1)) - return FoldSymbolOffset(Opcode, VT, GA, Cst2); - if (isCommutativeBinOp(Opcode)) - if (GlobalAddressSDNode *GA = dyn_cast<GlobalAddressSDNode>(Cst2)) - return FoldSymbolOffset(Opcode, VT, GA, Cst1); - // For vectors extract each constant element into Inputs so we can constant // fold them individually. BuildVectorSDNode *BV1 = dyn_cast<BuildVectorSDNode>(Cst1); @@ -7349,22 +7322,6 @@ bool ShuffleVectorSDNode::isSplatMask(const int *Mask, EVT VT) { return true; } -// \brief Returns the SDNode if it is a constant integer BuildVector -// or constant integer. -SDNode *SelectionDAG::isConstantIntBuildVectorOrConstantInt(SDValue N) { - if (isa<ConstantSDNode>(N)) - return N.getNode(); - if (ISD::isBuildVectorOfConstantSDNodes(N.getNode())) - return N.getNode(); - // Treat a GlobalAddress supporting constant offset folding as a - // constant integer. - if (GlobalAddressSDNode *GA = dyn_cast<GlobalAddressSDNode>(N)) - if (GA->getOpcode() == ISD::GlobalAddress && - TLI->isOffsetFoldingLegal(GA)) - return GA; - return nullptr; -} - #ifndef NDEBUG static void checkForCyclesHelper(const SDNode *N, SmallPtrSetImpl<const SDNode*> &Visited, diff --git a/llvm/test/CodeGen/WebAssembly/address-offsets.ll b/llvm/test/CodeGen/WebAssembly/address-offsets.ll deleted file mode 100644 index 46d16d2b926..00000000000 --- a/llvm/test/CodeGen/WebAssembly/address-offsets.ll +++ /dev/null @@ -1,672 +0,0 @@ -; RUN: llc < %s -asm-verbose=false | FileCheck %s - -; Test folding constant offsets and symbols into load and store addresses under -; a variety of circumstances. - -target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" -target triple = "wasm32-unknown-unknown" - -@g = external global [0 x i32], align 4 - -; CHECK-LABEL: load_test0: -; CHECK-NEXT: result i32{{$}} -; CHECK-NEXT: i32.const $push0=, 0{{$}} -; CHECK-NEXT: i32.load $push1=, g+40($pop0){{$}} -; CHECK-NEXT: return $pop1{{$}} -define i32 @load_test0() { - %t = load i32, i32* getelementptr inbounds ([0 x i32], [0 x i32]* @g, i32 0, i32 10), align 4 - ret i32 %t -} - -; CHECK-LABEL: load_test0_noinbounds: -; CHECK-NEXT: result i32{{$}} -; CHECK-NEXT: i32.const $push0=, 0{{$}} -; CHECK-NEXT: i32.load $push1=, g+40($pop0){{$}} -; CHECK-NEXT: return $pop1{{$}} -define i32 @load_test0_noinbounds() { - %t = load i32, i32* getelementptr ([0 x i32], [0 x i32]* @g, i32 0, i32 10), align 4 - ret i32 %t -} - -; CHECK-LABEL: load_test1: -; CHECK-NEXT: param i32{{$}} -; CHECK-NEXT: result i32{{$}} -; CHECK-NEXT: i32.const $push0=, 2{{$}} -; CHECK-NEXT: i32.shl $push1=, $0, $pop0{{$}} -; CHECK-NEXT: i32.load $push2=, g+40($pop1){{$}} -; CHECK-NEXT: return $pop2{{$}} -define i32 @load_test1(i32 %n) { - %add = add nsw i32 %n, 10 - %arrayidx = getelementptr inbounds [0 x i32], [0 x i32]* @g, i32 0, i32 %add - %t = load i32, i32* %arrayidx, align 4 - ret i32 %t -} - -; CHECK-LABEL: load_test2: -; CHECK-NEXT: param i32{{$}} -; CHECK-NEXT: result i32{{$}} -; CHECK-NEXT: i32.const $push0=, 2{{$}} -; CHECK-NEXT: i32.shl $push1=, $0, $pop0{{$}} -; CHECK-NEXT: i32.load $push2=, g+40($pop1){{$}} -; CHECK-NEXT: return $pop2{{$}} -define i32 @load_test2(i32 %n) { - %add = add nsw i32 10, %n - %arrayidx = getelementptr inbounds [0 x i32], [0 x i32]* @g, i32 0, i32 %add - %t = load i32, i32* %arrayidx, align 4 - ret i32 %t -} - -; CHECK-LABEL: load_test3: -; CHECK-NEXT: param i32{{$}} -; CHECK-NEXT: result i32{{$}} -; CHECK-NEXT: i32.const $push0=, 2{{$}} -; CHECK-NEXT: i32.shl $push1=, $0, $pop0{{$}} -; CHECK-NEXT: i32.load $push2=, g+40($pop1){{$}} -; CHECK-NEXT: return $pop2{{$}} -define i32 @load_test3(i32 %n) { - %add.ptr = getelementptr inbounds [0 x i32], [0 x i32]* @g, i32 0, i32 %n - %add.ptr1 = getelementptr inbounds i32, i32* %add.ptr, i32 10 - %t = load i32, i32* %add.ptr1, align 4 - ret i32 %t -} - -; CHECK-LABEL: load_test4: -; CHECK-NEXT: param i32{{$}} -; CHECK-NEXT: result i32{{$}} -; CHECK-NEXT: i32.const $push0=, 2{{$}} -; CHECK-NEXT: i32.shl $push1=, $0, $pop0{{$}} -; CHECK-NEXT: i32.load $push2=, g+40($pop1){{$}} -; CHECK-NEXT: return $pop2{{$}} -define i32 @load_test4(i32 %n) { - %add.ptr = getelementptr inbounds i32, i32* getelementptr inbounds ([0 x i32], [0 x i32]* @g, i32 0, i32 10), i32 %n - %t = load i32, i32* %add.ptr, align 4 - ret i32 %t -} - -; CHECK-LABEL: load_test5: -; CHECK-NEXT: param i32{{$}} -; CHECK-NEXT: result i32{{$}} -; CHECK-NEXT: i32.const $push0=, 2{{$}} -; CHECK-NEXT: i32.shl $push1=, $0, $pop0{{$}} -; CHECK-NEXT: i32.load $push2=, g+40($pop1){{$}} -; CHECK-NEXT: return $pop2{{$}} -define i32 @load_test5(i32 %n) { - %add.ptr = getelementptr inbounds i32, i32* getelementptr inbounds ([0 x i32], [0 x i32]* @g, i32 0, i32 10), i32 %n - %t = load i32, i32* %add.ptr, align 4 - ret i32 %t -} - -; CHECK-LABEL: load_test6: -; CHECK-NEXT: param i32{{$}} -; CHECK-NEXT: result i32{{$}} -; CHECK-NEXT: i32.const $push0=, 2{{$}} -; CHECK-NEXT: i32.shl $push1=, $0, $pop0{{$}} -; CHECK-NEXT: i32.load $push2=, g+40($pop1){{$}} -; CHECK-NEXT: return $pop2{{$}} -define i32 @load_test6(i32 %n) { - %add = add nsw i32 %n, 10 - %add.ptr = getelementptr inbounds [0 x i32], [0 x i32]* @g, i32 0, i32 %add - %t = load i32, i32* %add.ptr, align 4 - ret i32 %t -} - -; CHECK-LABEL: load_test7: -; CHECK-NEXT: param i32{{$}} -; CHECK-NEXT: result i32{{$}} -; CHECK-NEXT: i32.const $push0=, 2{{$}} -; CHECK-NEXT: i32.shl $push1=, $0, $pop0{{$}} -; CHECK-NEXT: i32.load $push2=, g+40($pop1){{$}} -; CHECK-NEXT: return $pop2{{$}} -define i32 @load_test7(i32 %n) { - %add.ptr = getelementptr inbounds [0 x i32], [0 x i32]* @g, i32 0, i32 %n - %add.ptr1 = getelementptr inbounds i32, i32* %add.ptr, i32 10 - %t = load i32, i32* %add.ptr1, align 4 - ret i32 %t -} - -; CHECK-LABEL: load_test8: -; CHECK-NEXT: param i32{{$}} -; CHECK-NEXT: result i32{{$}} -; CHECK-NEXT: i32.const $push0=, 2{{$}} -; CHECK-NEXT: i32.shl $push1=, $0, $pop0{{$}} -; CHECK-NEXT: i32.load $push2=, g+40($pop1){{$}} -; CHECK-NEXT: return $pop2{{$}} -define i32 @load_test8(i32 %n) { - %add = add nsw i32 10, %n - %add.ptr = getelementptr inbounds [0 x i32], [0 x i32]* @g, i32 0, i32 %add - %t = load i32, i32* %add.ptr, align 4 - ret i32 %t -} - -; CHECK-LABEL: load_test9: -; CHECK-NEXT: result i32{{$}} -; CHECK-NEXT: i32.const $push0=, 0{{$}} -; CHECK-NEXT: i32.load $push1=, g-40($pop0){{$}} -; CHECK-NEXT: return $pop1{{$}} -define i32 @load_test9() { - %t = load i32, i32* getelementptr inbounds ([0 x i32], [0 x i32]* @g, i32 0, i32 1073741814), align 4 - ret i32 %t -} - -; CHECK-LABEL: load_test10: -; CHECK-NEXT: param i32{{$}} -; CHECK-NEXT: result i32{{$}} -; CHECK-NEXT: i32.const $push0=, 2{{$}} -; CHECK-NEXT: i32.shl $push1=, $0, $pop0{{$}} -; CHECK-NEXT: i32.const $push2=, g-40{{$}} -; CHECK-NEXT: i32.add $push3=, $pop1, $pop2{{$}} -; CHECK-NEXT: i32.load $push4=, 0($pop3){{$}} -; CHECK-NEXT: return $pop4{{$}} -define i32 @load_test10(i32 %n) { - %add = add nsw i32 %n, -10 - %arrayidx = getelementptr inbounds [0 x i32], [0 x i32]* @g, i32 0, i32 %add - %t = load i32, i32* %arrayidx, align 4 - ret i32 %t -} - -; CHECK-LABEL: load_test11: -; CHECK-NEXT: param i32{{$}} -; CHECK-NEXT: result i32{{$}} -; CHECK-NEXT: i32.load $push0=, 40($0){{$}} -; CHECK-NEXT: return $pop0{{$}} -define i32 @load_test11(i32* %p) { - %arrayidx = getelementptr inbounds i32, i32* %p, i32 10 - %t = load i32, i32* %arrayidx, align 4 - ret i32 %t -} - -; CHECK-LABEL: load_test11_noinbounds: -; CHECK-NEXT: param i32{{$}} -; CHECK-NEXT: result i32{{$}} -; CHECK-NEXT: i32.const $push0=, 40{{$}} -; CHECK-NEXT: i32.add $push1=, $0, $pop0{{$}} -; CHECK-NEXT: i32.load $push2=, 0($pop1){{$}} -; CHECK-NEXT: return $pop2{{$}} -define i32 @load_test11_noinbounds(i32* %p) { - %arrayidx = getelementptr i32, i32* %p, i32 10 - %t = load i32, i32* %arrayidx, align 4 - ret i32 %t -} - -; CHECK-LABEL: load_test12: -; CHECK-NEXT: param i32, i32{{$}} -; CHECK-NEXT: result i32{{$}} -; CHECK-NEXT: i32.const $push0=, 2{{$}} -; CHECK-NEXT: i32.shl $push1=, $1, $pop0{{$}} -; CHECK-NEXT: i32.add $push2=, $pop1, $0{{$}} -; CHECK-NEXT: i32.const $push3=, 40{{$}} -; CHECK-NEXT: i32.add $push4=, $pop2, $pop3{{$}} -; CHECK-NEXT: i32.load $push5=, 0($pop4){{$}} -; CHECK-NEXT: return $pop5{{$}} -define i32 @load_test12(i32* %p, i32 %n) { - %add = add nsw i32 %n, 10 - %arrayidx = getelementptr inbounds i32, i32* %p, i32 %add - %t = load i32, i32* %arrayidx, align 4 - ret i32 %t -} - -; CHECK-LABEL: load_test13: -; CHECK-NEXT: param i32, i32{{$}} -; CHECK-NEXT: result i32{{$}} -; CHECK-NEXT: i32.const $push0=, 2{{$}} -; CHECK-NEXT: i32.shl $push1=, $1, $pop0{{$}} -; CHECK-NEXT: i32.add $push2=, $pop1, $0{{$}} -; CHECK-NEXT: i32.const $push3=, 40{{$}} -; CHECK-NEXT: i32.add $push4=, $pop2, $pop3{{$}} -; CHECK-NEXT: i32.load $push5=, 0($pop4){{$}} -; CHECK-NEXT: return $pop5{{$}} -define i32 @load_test13(i32* %p, i32 %n) { - %add = add nsw i32 10, %n - %arrayidx = getelementptr inbounds i32, i32* %p, i32 %add - %t = load i32, i32* %arrayidx, align 4 - ret i32 %t -} - -; CHECK-LABEL: load_test14: -; CHECK-NEXT: param i32, i32{{$}} -; CHECK-NEXT: result i32{{$}} -; CHECK-NEXT: i32.const $push0=, 2{{$}} -; CHECK-NEXT: i32.shl $push1=, $1, $pop0{{$}} -; CHECK-NEXT: i32.add $push2=, $0, $pop1{{$}} -; CHECK-NEXT: i32.load $push3=, 40($pop2){{$}} -; CHECK-NEXT: return $pop3{{$}} -define i32 @load_test14(i32* %p, i32 %n) { - %add.ptr = getelementptr inbounds i32, i32* %p, i32 %n - %add.ptr1 = getelementptr inbounds i32, i32* %add.ptr, i32 10 - %t = load i32, i32* %add.ptr1, align 4 - ret i32 %t -} - -; CHECK-LABEL: load_test15: -; CHECK-NEXT: param i32, i32{{$}} -; CHECK-NEXT: result i32{{$}} -; CHECK-NEXT: i32.const $push0=, 2{{$}} -; CHECK-NEXT: i32.shl $push1=, $1, $pop0{{$}} -; CHECK-NEXT: i32.add $push2=, $0, $pop1{{$}} -; CHECK-NEXT: i32.const $push3=, 40{{$}} -; CHECK-NEXT: i32.add $push4=, $pop2, $pop3{{$}} -; CHECK-NEXT: i32.load $push5=, 0($pop4){{$}} -; CHECK-NEXT: return $pop5{{$}} -define i32 @load_test15(i32* %p, i32 %n) { - %add.ptr = getelementptr inbounds i32, i32* %p, i32 10 - %add.ptr1 = getelementptr inbounds i32, i32* %add.ptr, i32 %n - %t = load i32, i32* %add.ptr1, align 4 - ret i32 %t -} - -; CHECK-LABEL: load_test16: -; CHECK-NEXT: param i32, i32{{$}} -; CHECK-NEXT: result i32{{$}} -; CHECK-NEXT: i32.const $push0=, 2{{$}} -; CHECK-NEXT: i32.shl $push1=, $1, $pop0{{$}} -; CHECK-NEXT: i32.add $push2=, $0, $pop1{{$}} -; CHECK-NEXT: i32.const $push3=, 40{{$}} -; CHECK-NEXT: i32.add $push4=, $pop2, $pop3{{$}} -; CHECK-NEXT: i32.load $push5=, 0($pop4){{$}} -; CHECK-NEXT: return $pop5{{$}} -define i32 @load_test16(i32* %p, i32 %n) { - %add.ptr = getelementptr inbounds i32, i32* %p, i32 10 - %add.ptr1 = getelementptr inbounds i32, i32* %add.ptr, i32 %n - %t = load i32, i32* %add.ptr1, align 4 - ret i32 %t -} - -; CHECK-LABEL: load_test17: -; CHECK-NEXT: param i32, i32{{$}} -; CHECK-NEXT: result i32{{$}} -; CHECK-NEXT: i32.const $push0=, 2{{$}} -; CHECK-NEXT: i32.shl $push1=, $1, $pop0{{$}} -; CHECK-NEXT: i32.add $push2=, $pop1, $0{{$}} -; CHECK-NEXT: i32.const $push3=, 40{{$}} -; CHECK-NEXT: i32.add $push4=, $pop2, $pop3{{$}} -; CHECK-NEXT: i32.load $push5=, 0($pop4){{$}} -; CHECK-NEXT: return $pop5{{$}} -define i32 @load_test17(i32* %p, i32 %n) { - %add = add nsw i32 %n, 10 - %add.ptr = getelementptr inbounds i32, i32* %p, i32 %add - %t = load i32, i32* %add.ptr, align 4 - ret i32 %t -} - -; CHECK-LABEL: load_test18: -; CHECK-NEXT: param i32, i32{{$}} -; CHECK-NEXT: result i32{{$}} -; CHECK-NEXT: i32.const $push0=, 2{{$}} -; CHECK-NEXT: i32.shl $push1=, $1, $pop0{{$}} -; CHECK-NEXT: i32.add $push2=, $0, $pop1{{$}} -; CHECK-NEXT: i32.load $push3=, 40($pop2){{$}} -; CHECK-NEXT: return $pop3{{$}} -define i32 @load_test18(i32* %p, i32 %n) { - %add.ptr = getelementptr inbounds i32, i32* %p, i32 %n - %add.ptr1 = getelementptr inbounds i32, i32* %add.ptr, i32 10 - %t = load i32, i32* %add.ptr1, align 4 - ret i32 %t -} - -; CHECK-LABEL: load_test19: -; CHECK-NEXT: param i32, i32{{$}} -; CHECK-NEXT: result i32{{$}} -; CHECK-NEXT: i32.const $push0=, 2{{$}} -; CHECK-NEXT: i32.shl $push1=, $1, $pop0{{$}} -; CHECK-NEXT: i32.add $push2=, $pop1, $0{{$}} -; CHECK-NEXT: i32.const $push3=, 40{{$}} -; CHECK-NEXT: i32.add $push4=, $pop2, $pop3{{$}} -; CHECK-NEXT: i32.load $push5=, 0($pop4){{$}} -; CHECK-NEXT: return $pop5{{$}} -define i32 @load_test19(i32* %p, i32 %n) { - %add = add nsw i32 10, %n - %add.ptr = getelementptr inbounds i32, i32* %p, i32 %add - %t = load i32, i32* %add.ptr, align 4 - ret i32 %t -} - -; CHECK-LABEL: load_test20: -; CHECK-NEXT: param i32{{$}} -; CHECK-NEXT: result i32{{$}} -; CHECK-NEXT: i32.const $push0=, -40{{$}} -; CHECK-NEXT: i32.add $push1=, $0, $pop0{{$}} -; CHECK-NEXT: i32.load $push2=, 0($pop1){{$}} -; CHECK-NEXT: return $pop2{{$}} -define i32 @load_test20(i32* %p) { - %arrayidx = getelementptr inbounds i32, i32* %p, i32 -10 - %t = load i32, i32* %arrayidx, align 4 - ret i32 %t -} - -; CHECK-LABEL: load_test21: -; CHECK-NEXT: param i32, i32{{$}} -; CHECK-NEXT: result i32{{$}} -; CHECK-NEXT: i32.const $push0=, 2{{$}} -; CHECK-NEXT: i32.shl $push1=, $1, $pop0{{$}} -; CHECK-NEXT: i32.add $push2=, $pop1, $0{{$}} -; CHECK-NEXT: i32.const $push3=, -40{{$}} -; CHECK-NEXT: i32.add $push4=, $pop2, $pop3{{$}} -; CHECK-NEXT: i32.load $push5=, 0($pop4){{$}} -; CHECK-NEXT: return $pop5{{$}} -define i32 @load_test21(i32* %p, i32 %n) { - %add = add nsw i32 %n, -10 - %arrayidx = getelementptr inbounds i32, i32* %p, i32 %add - %t = load i32, i32* %arrayidx, align 4 - ret i32 %t -} - -; CHECK-LABEL: store_test0: -; CHECK-NEXT: param i32{{$}} -; CHECK-NEXT: i32.const $push0=, 0{{$}} -; CHECK-NEXT: i32.store $discard=, g+40($pop0), $0{{$}} -; CHECK-NEXT: return{{$}} -define void @store_test0(i32 %i) { - store i32 %i, i32* getelementptr inbounds ([0 x i32], [0 x i32]* @g, i32 0, i32 10), align 4 - ret void -} - -; CHECK-LABEL: store_test0_noinbounds: -; CHECK-NEXT: param i32{{$}} -; CHECK-NEXT: i32.const $push0=, 0{{$}} -; CHECK-NEXT: i32.store $discard=, g+40($pop0), $0{{$}} -; CHECK-NEXT: return{{$}} -define void @store_test0_noinbounds(i32 %i) { - store i32 %i, i32* getelementptr ([0 x i32], [0 x i32]* @g, i32 0, i32 10), align 4 - ret void -} - -; CHECK-LABEL: store_test1: -; CHECK-NEXT: param i32, i32{{$}} -; CHECK-NEXT: i32.const $push0=, 2{{$}} -; CHECK-NEXT: i32.shl $push1=, $0, $pop0{{$}} -; CHECK-NEXT: i32.store $discard=, g+40($pop1), $1{{$}} -; CHECK-NEXT: return{{$}} -define void @store_test1(i32 %n, i32 %i) { - %add = add nsw i32 %n, 10 - %arrayidx = getelementptr inbounds [0 x i32], [0 x i32]* @g, i32 0, i32 %add - store i32 %i, i32* %arrayidx, align 4 - ret void -} - -; CHECK-LABEL: store_test2: -; CHECK-NEXT: param i32, i32{{$}} -; CHECK-NEXT: i32.const $push0=, 2{{$}} -; CHECK-NEXT: i32.shl $push1=, $0, $pop0{{$}} -; CHECK-NEXT: i32.store $discard=, g+40($pop1), $1{{$}} -; CHECK-NEXT: return{{$}} -define void @store_test2(i32 %n, i32 %i) { - %add = add nsw i32 10, %n - %arrayidx = getelementptr inbounds [0 x i32], [0 x i32]* @g, i32 0, i32 %add - store i32 %i, i32* %arrayidx, align 4 - ret void -} - -; CHECK-LABEL: store_test3: -; CHECK-NEXT: param i32, i32{{$}} -; CHECK-NEXT: i32.const $push0=, 2{{$}} -; CHECK-NEXT: i32.shl $push1=, $0, $pop0{{$}} -; CHECK-NEXT: i32.store $discard=, g+40($pop1), $1{{$}} -; CHECK-NEXT: return{{$}} -define void @store_test3(i32 %n, i32 %i) { - %add.ptr = getelementptr inbounds [0 x i32], [0 x i32]* @g, i32 0, i32 %n - %add.ptr1 = getelementptr inbounds i32, i32* %add.ptr, i32 10 - store i32 %i, i32* %add.ptr1, align 4 - ret void -} - -; CHECK-LABEL: store_test4: -; CHECK-NEXT: param i32, i32{{$}} -; CHECK-NEXT: i32.const $push0=, 2{{$}} -; CHECK-NEXT: i32.shl $push1=, $0, $pop0{{$}} -; CHECK-NEXT: i32.store $discard=, g+40($pop1), $1{{$}} -; CHECK-NEXT: return{{$}} -define void @store_test4(i32 %n, i32 %i) { - %add.ptr = getelementptr inbounds i32, i32* getelementptr inbounds ([0 x i32], [0 x i32]* @g, i32 0, i32 10), i32 %n - store i32 %i, i32* %add.ptr, align 4 - ret void -} - -; CHECK-LABEL: store_test5: -; CHECK-NEXT: param i32, i32{{$}} -; CHECK-NEXT: i32.const $push0=, 2{{$}} -; CHECK-NEXT: i32.shl $push1=, $0, $pop0{{$}} -; CHECK-NEXT: i32.store $discard=, g+40($pop1), $1{{$}} -; CHECK-NEXT: return{{$}} -define void @store_test5(i32 %n, i32 %i) { - %add.ptr = getelementptr inbounds i32, i32* getelementptr inbounds ([0 x i32], [0 x i32]* @g, i32 0, i32 10), i32 %n - store i32 %i, i32* %add.ptr, align 4 - ret void -} - -; CHECK-LABEL: store_test6: -; CHECK-NEXT: param i32, i32{{$}} -; CHECK-NEXT: i32.const $push0=, 2{{$}} -; CHECK-NEXT: i32.shl $push1=, $0, $pop0{{$}} -; CHECK-NEXT: i32.store $discard=, g+40($pop1), $1{{$}} -; CHECK-NEXT: return{{$}} -define void @store_test6(i32 %n, i32 %i) { - %add = add nsw i32 %n, 10 - %add.ptr = getelementptr inbounds [0 x i32], [0 x i32]* @g, i32 0, i32 %add - store i32 %i, i32* %add.ptr, align 4 - ret void -} - -; CHECK-LABEL: store_test7: -; CHECK-NEXT: param i32, i32{{$}} -; CHECK-NEXT: i32.const $push0=, 2{{$}} -; CHECK-NEXT: i32.shl $push1=, $0, $pop0{{$}} -; CHECK-NEXT: i32.store $discard=, g+40($pop1), $1{{$}} -; CHECK-NEXT: return{{$}} -define void @store_test7(i32 %n, i32 %i) { - %add.ptr = getelementptr inbounds [0 x i32], [0 x i32]* @g, i32 0, i32 %n - %add.ptr1 = getelementptr inbounds i32, i32* %add.ptr, i32 10 - store i32 %i, i32* %add.ptr1, align 4 - ret void -} - -; CHECK-LABEL: store_test8: -; CHECK-NEXT: param i32, i32{{$}} -; CHECK-NEXT: i32.const $push0=, 2{{$}} -; CHECK-NEXT: i32.shl $push1=, $0, $pop0{{$}} -; CHECK-NEXT: i32.store $discard=, g+40($pop1), $1{{$}} -; CHECK-NEXT: return{{$}} -define void @store_test8(i32 %n, i32 %i) { - %add = add nsw i32 10, %n - %add.ptr = getelementptr inbounds [0 x i32], [0 x i32]* @g, i32 0, i32 %add - store i32 %i, i32* %add.ptr, align 4 - ret void -} - -; CHECK-LABEL: store_test9: -; CHECK-NEXT: param i32{{$}} -; CHECK-NEXT: i32.const $push0=, 0{{$}} -; CHECK-NEXT: i32.store $discard=, g-40($pop0), $0{{$}} -; CHECK-NEXT: return{{$}} -define void @store_test9(i32 %i) { - store i32 %i, i32* getelementptr inbounds ([0 x i32], [0 x i32]* @g, i32 0, i32 1073741814), align 4 - ret void -} - -; CHECK-LABEL: store_test10: -; CHECK-NEXT: param i32, i32{{$}} -; CHECK-NEXT: i32.const $push0=, 2{{$}} -; CHECK-NEXT: i32.shl $push1=, $0, $pop0{{$}} -; CHECK-NEXT: i32.const $push2=, g-40{{$}} -; CHECK-NEXT: i32.add $push3=, $pop1, $pop2{{$}} -; CHECK-NEXT: i32.store $discard=, 0($pop3), $1{{$}} -; CHECK-NEXT: return{{$}} -define void @store_test10(i32 %n, i32 %i) { - %add = add nsw i32 %n, -10 - %arrayidx = getelementptr inbounds [0 x i32], [0 x i32]* @g, i32 0, i32 %add - store i32 %i, i32* %arrayidx, align 4 - ret void -} - -; CHECK-LABEL: store_test11: -; CHECK-NEXT: param i32, i32{{$}} -; CHECK-NEXT: i32.store $discard=, 40($0), $1{{$}} -; CHECK-NEXT: return{{$}} -define void @store_test11(i32* %p, i32 %i) { - %arrayidx = getelementptr inbounds i32, i32* %p, i32 10 - store i32 %i, i32* %arrayidx, align 4 - ret void -} - -; CHECK-LABEL: store_test11_noinbounds: -; CHECK-NEXT: param i32, i32{{$}} -; CHECK-NEXT: i32.const $push0=, 40{{$}} -; CHECK-NEXT: i32.add $push1=, $0, $pop0{{$}} -; CHECK-NEXT: i32.store $discard=, 0($pop1), $1{{$}} -; CHECK-NEXT: return{{$}} -define void @store_test11_noinbounds(i32* %p, i32 %i) { - %arrayidx = getelementptr i32, i32* %p, i32 10 - store i32 %i, i32* %arrayidx, align 4 - ret void -} - -; CHECK-LABEL: store_test12: -; CHECK-NEXT: param i32, i32, i32{{$}} -; CHECK-NEXT: i32.const $push0=, 2{{$}} -; CHECK-NEXT: i32.shl $push1=, $1, $pop0{{$}} -; CHECK-NEXT: i32.add $push2=, $pop1, $0{{$}} -; CHECK-NEXT: i32.const $push3=, 40{{$}} -; CHECK-NEXT: i32.add $push4=, $pop2, $pop3{{$}} -; CHECK-NEXT: i32.store $discard=, 0($pop4), $2{{$}} -; CHECK-NEXT: return{{$}} -define void @store_test12(i32* %p, i32 %n, i32 %i) { - %add = add nsw i32 %n, 10 - %arrayidx = getelementptr inbounds i32, i32* %p, i32 %add - store i32 %i, i32* %arrayidx, align 4 - ret void -} - -; CHECK-LABEL: store_test13: -; CHECK-NEXT: param i32, i32, i32{{$}} -; CHECK-NEXT: i32.const $push0=, 2{{$}} -; CHECK-NEXT: i32.shl $push1=, $1, $pop0{{$}} -; CHECK-NEXT: i32.add $push2=, $pop1, $0{{$}} -; CHECK-NEXT: i32.const $push3=, 40{{$}} -; CHECK-NEXT: i32.add $push4=, $pop2, $pop3{{$}} -; CHECK-NEXT: i32.store $discard=, 0($pop4), $2{{$}} -; CHECK-NEXT: return{{$}} -define void @store_test13(i32* %p, i32 %n, i32 %i) { - %add = add nsw i32 10, %n - %arrayidx = getelementptr inbounds i32, i32* %p, i32 %add - store i32 %i, i32* %arrayidx, align 4 - ret void -} - -; CHECK-LABEL: store_test14: -; CHECK-NEXT: param i32, i32, i32{{$}} -; CHECK-NEXT: i32.const $push0=, 2{{$}} -; CHECK-NEXT: i32.shl $push1=, $1, $pop0{{$}} -; CHECK-NEXT: i32.add $push2=, $0, $pop1{{$}} -; CHECK-NEXT: i32.store $discard=, 40($pop2), $2{{$}} -; CHECK-NEXT: return{{$}} -define void @store_test14(i32* %p, i32 %n, i32 %i) { - %add.ptr = getelementptr inbounds i32, i32* %p, i32 %n - %add.ptr1 = getelementptr inbounds i32, i32* %add.ptr, i32 10 - store i32 %i, i32* %add.ptr1, align 4 - ret void -} - -; CHECK-LABEL: store_test15: -; CHECK-NEXT: param i32, i32, i32{{$}} -; CHECK-NEXT: i32.const $push0=, 2{{$}} -; CHECK-NEXT: i32.shl $push1=, $1, $pop0{{$}} -; CHECK-NEXT: i32.add $push2=, $0, $pop1{{$}} -; CHECK-NEXT: i32.const $push3=, 40{{$}} -; CHECK-NEXT: i32.add $push4=, $pop2, $pop3{{$}} -; CHECK-NEXT: i32.store $discard=, 0($pop4), $2{{$}} -; CHECK-NEXT: return{{$}} -define void @store_test15(i32* %p, i32 %n, i32 %i) { - %add.ptr = getelementptr inbounds i32, i32* %p, i32 10 - %add.ptr1 = getelementptr inbounds i32, i32* %add.ptr, i32 %n - store i32 %i, i32* %add.ptr1, align 4 - ret void -} - -; CHECK-LABEL: store_test16: -; CHECK-NEXT: param i32, i32, i32{{$}} -; CHECK-NEXT: i32.const $push0=, 2{{$}} -; CHECK-NEXT: i32.shl $push1=, $1, $pop0{{$}} -; CHECK-NEXT: i32.add $push2=, $0, $pop1{{$}} -; CHECK-NEXT: i32.const $push3=, 40{{$}} -; CHECK-NEXT: i32.add $push4=, $pop2, $pop3{{$}} -; CHECK-NEXT: i32.store $discard=, 0($pop4), $2{{$}} -; CHECK-NEXT: return{{$}} -define void @store_test16(i32* %p, i32 %n, i32 %i) { - %add.ptr = getelementptr inbounds i32, i32* %p, i32 10 - %add.ptr1 = getelementptr inbounds i32, i32* %add.ptr, i32 %n - store i32 %i, i32* %add.ptr1, align 4 - ret void -} - -; CHECK-LABEL: store_test17: -; CHECK-NEXT: param i32, i32, i32{{$}} -; CHECK-NEXT: i32.const $push0=, 2{{$}} -; CHECK-NEXT: i32.shl $push1=, $1, $pop0{{$}} -; CHECK-NEXT: i32.add $push2=, $pop1, $0{{$}} -; CHECK-NEXT: i32.const $push3=, 40{{$}} -; CHECK-NEXT: i32.add $push4=, $pop2, $pop3{{$}} -; CHECK-NEXT: i32.store $discard=, 0($pop4), $2{{$}} -; CHECK-NEXT: return{{$}} -define void @store_test17(i32* %p, i32 %n, i32 %i) { - %add = add nsw i32 %n, 10 - %add.ptr = getelementptr inbounds i32, i32* %p, i32 %add - store i32 %i, i32* %add.ptr, align 4 - ret void -} - -; CHECK-LABEL: store_test18: -; CHECK-NEXT: param i32, i32, i32{{$}} -; CHECK-NEXT: i32.const $push0=, 2{{$}} -; CHECK-NEXT: i32.shl $push1=, $1, $pop0{{$}} -; CHECK-NEXT: i32.add $push2=, $0, $pop1{{$}} -; CHECK-NEXT: i32.store $discard=, 40($pop2), $2{{$}} -; CHECK-NEXT: return{{$}} -define void @store_test18(i32* %p, i32 %n, i32 %i) { - %add.ptr = getelementptr inbounds i32, i32* %p, i32 %n - %add.ptr1 = getelementptr inbounds i32, i32* %add.ptr, i32 10 - store i32 %i, i32* %add.ptr1, align 4 - ret void -} - -; CHECK-LABEL: store_test19: -; CHECK-NEXT: param i32, i32, i32{{$}} -; CHECK-NEXT: i32.const $push0=, 2{{$}} -; CHECK-NEXT: i32.shl $push1=, $1, $pop0{{$}} -; CHECK-NEXT: i32.add $push2=, $pop1, $0{{$}} -; CHECK-NEXT: i32.const $push3=, 40{{$}} -; CHECK-NEXT: i32.add $push4=, $pop2, $pop3{{$}} -; CHECK-NEXT: i32.store $discard=, 0($pop4), $2{{$}} -; CHECK-NEXT: return{{$}} -define void @store_test19(i32* %p, i32 %n, i32 %i) { - %add = add nsw i32 10, %n - %add.ptr = getelementptr inbounds i32, i32* %p, i32 %add - store i32 %i, i32* %add.ptr, align 4 - ret void -} - -; CHECK-LABEL: store_test20: -; CHECK-NEXT: param i32, i32{{$}} -; CHECK-NEXT: i32.const $push0=, -40{{$}} -; CHECK-NEXT: i32.add $push1=, $0, $pop0{{$}} -; CHECK-NEXT: i32.store $discard=, 0($pop1), $1{{$}} -; CHECK-NEXT: return{{$}} -define void @store_test20(i32* %p, i32 %i) { - %arrayidx = getelementptr inbounds i32, i32* %p, i32 -10 - store i32 %i, i32* %arrayidx, align 4 - ret void -} - -; CHECK-LABEL: store_test21: -; CHECK-NEXT: param i32, i32, i32{{$}} -; CHECK-NEXT: i32.const $push0=, 2{{$}} -; CHECK-NEXT: i32.shl $push1=, $1, $pop0{{$}} -; CHECK-NEXT: i32.add $push2=, $pop1, $0{{$}} -; CHECK-NEXT: i32.const $push3=, -40{{$}} -; CHECK-NEXT: i32.add $push4=, $pop2, $pop3{{$}} -; CHECK-NEXT: i32.store $discard=, 0($pop4), $2{{$}} -; CHECK-NEXT: return{{$}} -define void @store_test21(i32* %p, i32 %n, i32 %i) { - %add = add nsw i32 %n, -10 - %arrayidx = getelementptr inbounds i32, i32* %p, i32 %add - store i32 %i, i32* %arrayidx, align 4 - ret void -} diff --git a/llvm/test/CodeGen/X86/lea-opt.ll b/llvm/test/CodeGen/X86/lea-opt.ll index 20e27773195..8096bfabd6c 100644 --- a/llvm/test/CodeGen/X86/lea-opt.ll +++ b/llvm/test/CodeGen/X86/lea-opt.ll @@ -34,12 +34,12 @@ sw.bb.2: ; preds = %entry sw.epilog: ; preds = %sw.bb.2, %sw.bb.1, %entry ret void ; CHECK-LABEL: test1: -; CHECK: shlq $2, [[REG1:%[a-z]+]] -; CHECK: movl arr1([[REG1]],[[REG1]],2), {{.*}} -; CHECK: leaq arr1+4([[REG1]],[[REG1]],2), [[REG2:%[a-z]+]] -; CHECK: subl arr1+4([[REG1]],[[REG1]],2), {{.*}} -; CHECK: leaq arr1+8([[REG1]],[[REG1]],2), [[REG3:%[a-z]+]] -; CHECK: addl arr1+8([[REG1]],[[REG1]],2), {{.*}} +; CHECK: leaq (%rdi,%rdi,2), [[REG1:%[a-z]+]] +; CHECK: movl arr1(,[[REG1]],4), {{.*}} +; CHECK: leaq arr1+4(,[[REG1]],4), [[REG2:%[a-z]+]] +; CHECK: subl arr1+4(,[[REG1]],4), {{.*}} +; CHECK: leaq arr1+8(,[[REG1]],4), [[REG3:%[a-z]+]] +; CHECK: addl arr1+8(,[[REG1]],4), {{.*}} ; CHECK: movl ${{[1-4]+}}, ([[REG2]]) ; CHECK: movl ${{[1-4]+}}, ([[REG3]]) ; CHECK: movl ${{[1-4]+}}, ([[REG2]]) @@ -74,11 +74,11 @@ sw.bb.2: ; preds = %entry sw.epilog: ; preds = %sw.bb.2, %sw.bb.1, %entry ret void ; CHECK-LABEL: test2: -; CHECK: shlq $2, [[REG1:%[a-z]+]] -; CHECK: leaq arr1+4([[REG1]],[[REG1]],2), [[REG2:%[a-z]+]] +; CHECK: leaq (%rdi,%rdi,2), [[REG1:%[a-z]+]] +; CHECK: leaq arr1+4(,[[REG1]],4), [[REG2:%[a-z]+]] ; CHECK: movl -4([[REG2]]), {{.*}} ; CHECK: subl ([[REG2]]), {{.*}} -; CHECK: leaq arr1+8([[REG1]],[[REG1]],2), [[REG3:%[a-z]+]] +; CHECK: leaq arr1+8(,[[REG1]],4), [[REG3:%[a-z]+]] ; CHECK: addl ([[REG3]]), {{.*}} ; CHECK: movl ${{[1-4]+}}, ([[REG2]]) ; CHECK: movl ${{[1-4]+}}, ([[REG3]]) diff --git a/llvm/test/CodeGen/X86/negative-offset.ll b/llvm/test/CodeGen/X86/negative-offset.ll deleted file mode 100644 index dc1b255d020..00000000000 --- a/llvm/test/CodeGen/X86/negative-offset.ll +++ /dev/null @@ -1,18 +0,0 @@ -; RUN: llc < %s -asm-verbose=false | FileCheck %s - -target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" -target triple = "x86_64-unknown-linux-gnu" - -; Test that a constant consisting of a global symbol with a negative offset -; is properly folded and isel'd. - -; CHECK-LABEL: negative_offset: -; CHECK: movl $G, %eax -; CHECK: notq %rax -; CHECK: addq %rdi, %rax -; CHECK: retq -@G = external global [8 x i32] -define i8* @negative_offset(i8* %a) { - %t = getelementptr i8, i8* %a, i64 sub (i64 -1, i64 ptrtoint ([8 x i32]* @G to i64)) - ret i8* %t -} diff --git a/llvm/test/CodeGen/XCore/threads.ll b/llvm/test/CodeGen/XCore/threads.ll index 30dda143e08..0c25314295d 100644 --- a/llvm/test/CodeGen/XCore/threads.ll +++ b/llvm/test/CodeGen/XCore/threads.ll @@ -87,7 +87,7 @@ define i32* @f_tle() { ; CHECK: shl [[R0:r[0-9]]], r11, 3 ; CHECK: ldaw [[R1:r[0-9]]], dp[tle] ; r0 = &tl + id*8 -; CHECK: add r0, [[R0]], [[R1]] +; CHECK: add r0, [[R1]], [[R0]] ret i32* getelementptr inbounds ([2 x i32], [2 x i32]* @tle, i32 0, i32 0) } @@ -96,7 +96,7 @@ define i32 @f_tlExpr () { ; CHECK: get r11, id ; CHECK: shl [[R0:r[0-9]]], r11, 3 ; CHECK: ldaw [[R1:r[0-9]]], dp[tle] -; CHECK: add [[R2:r[0-9]]], [[R0]], [[R1]] +; CHECK: add [[R2:r[0-9]]], [[R1]], [[R0]] ; CHECK: add r0, [[R2]], [[R2]] ret i32 add( i32 ptrtoint( i32* getelementptr inbounds ([2 x i32], [2 x i32]* @tle, i32 0, i32 0) to i32), |

