From zwarich at apple.com Mon Jan 17 00:59:40 2011 From: zwarich at apple.com (Cameron Zwarich) Date: Sun, 16 Jan 2011 22:59:40 -0800 Subject: [llvm-commits] [llvm] r123609 - in /llvm/trunk: include/llvm/Transforms/Utils/PromoteMemToReg.h lib/Transforms/Scalar/ScalarReplAggregates.cpp lib/Transforms/Utils/Mem2Reg.cpp lib/Transforms/Utils/PromoteMemoryToRegister.cpp In-Reply-To: <20110117010859.9C7E72A6C130@llvm.org> References: <20110117010859.9C7E72A6C130@llvm.org> Message-ID: <958A7D60-670C-486A-AE47-0490627FAB20@apple.com> This caused some failures on the llvm-x86_64-linux-checks bot. I'll probably roll it out now and investigate tomorrow, unless something really obvious shows up on those test cases. Cameron From zwarich at apple.com Mon Jan 17 01:27:56 2011 From: zwarich at apple.com (Cameron Zwarich) Date: Sun, 16 Jan 2011 23:27:56 -0800 Subject: [llvm-commits] [llvm] r123609 - in /llvm/trunk: include/llvm/Transforms/Utils/PromoteMemToReg.h lib/Transforms/Scalar/ScalarReplAggregates.cpp lib/Transforms/Utils/Mem2Reg.cpp lib/Transforms/Utils/PromoteMemoryToRegister.cpp In-Reply-To: <958A7D60-670C-486A-AE47-0490627FAB20@apple.com> References: <20110117010859.9C7E72A6C130@llvm.org> <958A7D60-670C-486A-AE47-0490627FAB20@apple.com> Message-ID: On Jan 16, 2011, at 10:59 PM, Cameron Zwarich wrote: > This caused some failures on the llvm-x86_64-linux-checks bot. I'll probably roll it out now and investigate tomorrow, unless something really obvious shows up on those test cases. All of the failing tests pass locally for me with a Release+Asserts+Checks build. I don't see how the heap invariants can be violated, since my Compare parameter simply compares two integers and I only use the priority_queue operations. This is definitely interesting... I'll roll it out now because I probably don't have time to deal with this during the work day tomorrow. Cameron From zwarich at apple.com Mon Jan 17 01:26:51 2011 From: zwarich at apple.com (Cameron Zwarich) Date: Mon, 17 Jan 2011 07:26:51 -0000 Subject: [llvm-commits] [llvm] r123618 - in /llvm/trunk: include/llvm/Transforms/Utils/PromoteMemToReg.h lib/Transforms/Scalar/ScalarReplAggregates.cpp lib/Transforms/Utils/Mem2Reg.cpp lib/Transforms/Utils/PromoteMemoryToRegister.cpp Message-ID: <20110117072651.CE3C62A6C12C@llvm.org> Author: zwarich Date: Mon Jan 17 01:26:51 2011 New Revision: 123618 URL: http://llvm.org/viewvc/llvm-project?rev=123618&view=rev Log: Roll out r123609 due to failures on the llvm-x86_64-linux-checks bot. Modified: llvm/trunk/include/llvm/Transforms/Utils/PromoteMemToReg.h llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp llvm/trunk/lib/Transforms/Utils/Mem2Reg.cpp llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp Modified: llvm/trunk/include/llvm/Transforms/Utils/PromoteMemToReg.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/PromoteMemToReg.h?rev=123618&r1=123617&r2=123618&view=diff ============================================================================== --- llvm/trunk/include/llvm/Transforms/Utils/PromoteMemToReg.h (original) +++ llvm/trunk/include/llvm/Transforms/Utils/PromoteMemToReg.h Mon Jan 17 01:26:51 2011 @@ -38,7 +38,8 @@ /// made to the IR. /// void PromoteMemToReg(const std::vector &Allocas, - DominatorTree &DT, AliasSetTracker *AST = 0); + DominatorTree &DT, DominanceFrontier &DF, + AliasSetTracker *AST = 0); } // End llvm namespace Modified: llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp?rev=123618&r1=123617&r2=123618&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp Mon Jan 17 01:26:51 2011 @@ -152,6 +152,7 @@ // will not alter the CFG, so say so. virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequired(); + AU.addRequired(); AU.setPreservesCFG(); } }; @@ -179,6 +180,7 @@ INITIALIZE_PASS_BEGIN(SROA_DF, "scalarrepl", "Scalar Replacement of Aggregates (DF)", false, false) INITIALIZE_PASS_DEPENDENCY(DominatorTree) +INITIALIZE_PASS_DEPENDENCY(DominanceFrontier) INITIALIZE_PASS_END(SROA_DF, "scalarrepl", "Scalar Replacement of Aggregates (DF)", false, false) @@ -875,8 +877,11 @@ bool SROA::performPromotion(Function &F) { std::vector Allocas; DominatorTree *DT = 0; - if (HasDomFrontiers) + DominanceFrontier *DF = 0; + if (HasDomFrontiers) { DT = &getAnalysis(); + DF = &getAnalysis(); + } BasicBlock &BB = F.getEntryBlock(); // Get the entry node for the function @@ -895,7 +900,7 @@ if (Allocas.empty()) break; if (HasDomFrontiers) - PromoteMemToReg(Allocas, *DT); + PromoteMemToReg(Allocas, *DT, *DF); else { SSAUpdater SSA; for (unsigned i = 0, e = Allocas.size(); i != e; ++i) { Modified: llvm/trunk/lib/Transforms/Utils/Mem2Reg.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/Mem2Reg.cpp?rev=123618&r1=123617&r2=123618&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/Mem2Reg.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/Mem2Reg.cpp Mon Jan 17 01:26:51 2011 @@ -40,6 +40,7 @@ // virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequired(); + AU.addRequired(); AU.setPreservesCFG(); // This is a cluster of orthogonal Transforms AU.addPreserved(); @@ -53,6 +54,7 @@ INITIALIZE_PASS_BEGIN(PromotePass, "mem2reg", "Promote Memory to Register", false, false) INITIALIZE_PASS_DEPENDENCY(DominatorTree) +INITIALIZE_PASS_DEPENDENCY(DominanceFrontier) INITIALIZE_PASS_END(PromotePass, "mem2reg", "Promote Memory to Register", false, false) @@ -64,6 +66,7 @@ bool Changed = false; DominatorTree &DT = getAnalysis(); + DominanceFrontier &DF = getAnalysis(); while (1) { Allocas.clear(); @@ -77,7 +80,7 @@ if (Allocas.empty()) break; - PromoteMemToReg(Allocas, DT); + PromoteMemToReg(Allocas, DT, DF); NumPromoted += Allocas.size(); Changed = true; } Modified: llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp?rev=123618&r1=123617&r2=123618&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp Mon Jan 17 01:26:51 2011 @@ -9,19 +9,10 @@ // // This file promotes memory references to be register references. It promotes // alloca instructions which only have loads and stores as uses. An alloca is -// transformed by using iterated dominator frontiers to place PHI nodes, then -// traversing the function in depth-first order to rewrite loads and stores as -// appropriate. -// -// The algorithm used here is based on: -// -// Sreedhar and Gao. A linear time algorithm for placing phi-nodes. -// In Proceedings of the 22nd ACM SIGPLAN-SIGACT Symposium on Principles of -// Programming Languages -// POPL '95. ACM, New York, NY, 62-73. -// -// It has been modified to not explicitly use the DJ graph data structure and to -// directly compute pruned SSA using per-variable liveness information. +// transformed by using dominator frontiers to place PHI nodes, then traversing +// the function in depth-first order to rewrite loads and stores as appropriate. +// This is just the standard SSA construction algorithm to construct "pruned" +// SSA form. // //===----------------------------------------------------------------------===// @@ -44,7 +35,6 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/Support/CFG.h" #include -#include using namespace llvm; STATISTIC(NumLocalPromoted, "Number of alloca's promoted within one block"); @@ -189,6 +179,7 @@ /// std::vector Allocas; DominatorTree &DT; + DominanceFrontier &DF; DIFactory *DIF; /// AST - An AliasSetTracker object to update. If null, don't update it. @@ -226,15 +217,12 @@ /// non-determinstic behavior. DenseMap BBNumbers; - /// DomLevels - Maps DomTreeNodes to their level in the dominator tree. - DenseMap DomLevels; - /// BBNumPreds - Lazily compute the number of predecessors a block has. DenseMap BBNumPreds; public: PromoteMem2Reg(const std::vector &A, DominatorTree &dt, - AliasSetTracker *ast) - : Allocas(A), DT(dt), DIF(0), AST(ast) {} + DominanceFrontier &df, AliasSetTracker *ast) + : Allocas(A), DT(dt), DF(df), DIF(0), AST(ast) {} ~PromoteMem2Reg() { delete DIF; } @@ -341,7 +329,7 @@ void PromoteMem2Reg::run() { - Function &F = *DT.getRoot()->getParent(); + Function &F = *DF.getRoot()->getParent(); if (AST) PointerAllocaValues.resize(Allocas.size()); AllocaDbgDeclares.resize(Allocas.size()); @@ -434,26 +422,7 @@ continue; } } - - // If we haven't computed dominator tree levels, do so now. - if (DomLevels.empty()) { - SmallVector Worklist; - - DomTreeNode *Root = DT.getRootNode(); - DomLevels[Root] = 0; - Worklist.push_back(Root); - - while (!Worklist.empty()) { - DomTreeNode *Node = Worklist.pop_back_val(); - unsigned ChildLevel = DomLevels[Node] + 1; - for (DomTreeNode::iterator CI = Node->begin(), CE = Node->end(); - CI != CE; ++CI) { - DomLevels[*CI] = ChildLevel; - Worklist.push_back(*CI); - } - } - } - + // If we haven't computed a numbering for the BB's in the function, do so // now. if (BBNumbers.empty()) { @@ -688,14 +657,6 @@ } } -typedef std::pair DomTreeNodePair; - -struct DomTreeNodeCompare { - bool operator()(const DomTreeNodePair &LHS, const DomTreeNodePair &RHS) { - return LHS.second <= RHS.second; - } -}; - /// DetermineInsertionPoint - At this point, we're committed to promoting the /// alloca using IDF's, and the standard SSA construction algorithm. Determine /// which blocks need phi nodes and see if we can optimize out some work by @@ -712,77 +673,46 @@ SmallPtrSet LiveInBlocks; ComputeLiveInBlocks(AI, Info, DefBlocks, LiveInBlocks); - // Use a priority queue keyed on dominator tree level so that inserted nodes - // are handled from the bottom of the dominator tree upwards. - typedef std::priority_queue, - DomTreeNodeCompare> IDFPriorityQueue; - IDFPriorityQueue PQ; - - for (unsigned i = 0, e = Info.DefiningBlocks.size(); i != e; ++i) { - if (DomTreeNode *Node = DT.getNode(Info.DefiningBlocks[i])) - PQ.push(std::make_pair(Node, DomLevels[Node])); - } - + // Compute the locations where PhiNodes need to be inserted. Look at the + // dominance frontier of EACH basic-block we have a write in. + unsigned CurrentVersion = 0; std::vector > DFBlocks; - SmallPtrSet Visited; - SmallVector Worklist; - while (!PQ.empty()) { - DomTreeNodePair RootPair = PQ.top(); - PQ.pop(); - DomTreeNode *Root = RootPair.first; - unsigned RootLevel = RootPair.second; - - // Walk all dominator tree children of Root, inspecting their CFG edges with - // targets elsewhere on the dominator tree. Only targets whose level is at - // most Root's level are added to the iterated dominance frontier of the - // definition set. - - Worklist.clear(); - Worklist.push_back(Root); - - while (!Worklist.empty()) { - DomTreeNode *Node = Worklist.pop_back_val(); - BasicBlock *BB = Node->getBlock(); - - for (succ_iterator SI = succ_begin(BB), SE = succ_end(BB); SI != SE; - ++SI) { - DomTreeNode *SuccNode = DT.getNode(*SI); - - // Quickly skip all CFG edges that are also dominator tree edges instead - // of catching them below. - if (SuccNode->getIDom() == Node) - continue; - - unsigned SuccLevel = DomLevels[SuccNode]; - if (SuccLevel > RootLevel) - continue; - - if (!Visited.insert(SuccNode)) - continue; - - BasicBlock *SuccBB = SuccNode->getBlock(); - if (!LiveInBlocks.count(SuccBB)) - continue; - - DFBlocks.push_back(std::make_pair(BBNumbers[SuccBB], SuccBB)); - if (!DefBlocks.count(SuccBB)) - PQ.push(std::make_pair(SuccNode, SuccLevel)); - } - - for (DomTreeNode::iterator CI = Node->begin(), CE = Node->end(); CI != CE; - ++CI) { - if (!Visited.count(*CI)) - Worklist.push_back(*CI); - } + while (!Info.DefiningBlocks.empty()) { + BasicBlock *BB = Info.DefiningBlocks.back(); + Info.DefiningBlocks.pop_back(); + + // Look up the DF for this write, add it to defining blocks. + DominanceFrontier::const_iterator it = DF.find(BB); + if (it == DF.end()) continue; + + const DominanceFrontier::DomSetType &S = it->second; + + // In theory we don't need the indirection through the DFBlocks vector. + // In practice, the order of calling QueuePhiNode would depend on the + // (unspecified) ordering of basic blocks in the dominance frontier, + // which would give PHI nodes non-determinstic subscripts. Fix this by + // processing blocks in order of the occurance in the function. + for (DominanceFrontier::DomSetType::const_iterator P = S.begin(), + PE = S.end(); P != PE; ++P) { + // If the frontier block is not in the live-in set for the alloca, don't + // bother processing it. + if (!LiveInBlocks.count(*P)) + continue; + + DFBlocks.push_back(std::make_pair(BBNumbers[*P], *P)); } + + // Sort by which the block ordering in the function. + if (DFBlocks.size() > 1) + std::sort(DFBlocks.begin(), DFBlocks.end()); + + for (unsigned i = 0, e = DFBlocks.size(); i != e; ++i) { + BasicBlock *BB = DFBlocks[i].second; + if (QueuePhiNode(BB, AllocaNum, CurrentVersion)) + Info.DefiningBlocks.push_back(BB); + } + DFBlocks.clear(); } - - if (DFBlocks.size() > 1) - std::sort(DFBlocks.begin(), DFBlocks.end()); - - unsigned CurrentVersion = 0; - for (unsigned i = 0, e = DFBlocks.size(); i != e; ++i) - QueuePhiNode(DFBlocks[i].second, AllocaNum, CurrentVersion); } /// RewriteSingleStoreAlloca - If there is only a single store to this value, @@ -1110,9 +1040,10 @@ /// made to the IR. /// void llvm::PromoteMemToReg(const std::vector &Allocas, - DominatorTree &DT, AliasSetTracker *AST) { + DominatorTree &DT, DominanceFrontier &DF, + AliasSetTracker *AST) { // If there is nothing to do, bail out... if (Allocas.empty()) return; - PromoteMem2Reg(Allocas, DT, AST).run(); + PromoteMem2Reg(Allocas, DT, DF, AST).run(); } From evan.cheng at apple.com Mon Jan 17 02:03:19 2011 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 17 Jan 2011 08:03:19 -0000 Subject: [llvm-commits] [llvm] r123619 - in /llvm/trunk: lib/Target/ARM/ test/CodeGen/ARM/ Message-ID: <20110117080319.6F8382A6C12C@llvm.org> Author: evancheng Date: Mon Jan 17 02:03:18 2011 New Revision: 123619 URL: http://llvm.org/viewvc/llvm-project?rev=123619&view=rev Log: Materialize GA addresses with movw + movt pairs for Darwin in PIC mode. e.g. movw r0, :lower16:(L_foo$non_lazy_ptr-(LPC0_0+4)) movt r0, :upper16:(L_foo$non_lazy_ptr-(LPC0_0+4)) LPC0_0: add r0, pc, r0 It's not yet enabled by default as some tests are failing. I suspect bugs in down stream tools. Modified: llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp llvm/trunk/lib/Target/ARM/ARMAsmPrinter.h llvm/trunk/lib/Target/ARM/ARMBaseInfo.h llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp llvm/trunk/lib/Target/ARM/ARMExpandPseudoInsts.cpp llvm/trunk/lib/Target/ARM/ARMFastISel.cpp llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp llvm/trunk/lib/Target/ARM/ARMISelLowering.h llvm/trunk/lib/Target/ARM/ARMInstrInfo.td llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td llvm/trunk/lib/Target/ARM/ARMJITInfo.h llvm/trunk/lib/Target/ARM/ARMMachineFunctionInfo.h llvm/trunk/lib/Target/ARM/ARMSubtarget.cpp llvm/trunk/test/CodeGen/ARM/2010-11-30-reloc-movt.ll llvm/trunk/test/CodeGen/ARM/2010-12-13-reloc-pic.ll llvm/trunk/test/CodeGen/ARM/2010-12-15-elf-lcomm.ll Modified: llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp?rev=123619&r1=123618&r2=123619&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp Mon Jan 17 02:03:18 2011 @@ -20,6 +20,7 @@ #include "ARMBaseRegisterInfo.h" #include "ARMConstantPoolValue.h" #include "ARMMachineFunctionInfo.h" +#include "ARMMCExpr.h" #include "ARMTargetMachine.h" #include "ARMTargetObjectFile.h" #include "InstPrinter/ARMInstPrinter.h" @@ -537,6 +538,25 @@ return MCSymbolRefExpr::VK_None; } +MCSymbol *ARMAsmPrinter::GetARMGVSymbol(const GlobalValue *GV) { + bool isIndirect = Subtarget->isTargetDarwin() && + Subtarget->GVIsIndirectSymbol(GV, TM.getRelocationModel()); + if (!isIndirect) + return Mang->getSymbol(GV); + + // FIXME: Remove this when Darwin transition to @GOT like syntax. + MCSymbol *MCSym = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr"); + MachineModuleInfoMachO &MMIMachO = + MMI->getObjFileInfo(); + MachineModuleInfoImpl::StubValueTy &StubSym = + GV->hasHiddenVisibility() ? MMIMachO.getHiddenGVStubEntry(MCSym) : + MMIMachO.getGVStubEntry(MCSym); + if (StubSym.getPointer() == 0) + StubSym = MachineModuleInfoImpl:: + StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage()); + return MCSym; +} + void ARMAsmPrinter:: EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) { int Size = TM.getTargetData()->getTypeAllocSize(MCPV->getType()); @@ -553,23 +573,7 @@ MCSym = GetBlockAddressSymbol(ACPV->getBlockAddress()); } else if (ACPV->isGlobalValue()) { const GlobalValue *GV = ACPV->getGV(); - bool isIndirect = Subtarget->isTargetDarwin() && - Subtarget->GVIsIndirectSymbol(GV, TM.getRelocationModel()); - if (!isIndirect) - MCSym = Mang->getSymbol(GV); - else { - // FIXME: Remove this when Darwin transition to @GOT like syntax. - MCSym = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr"); - - MachineModuleInfoMachO &MMIMachO = - MMI->getObjFileInfo(); - MachineModuleInfoImpl::StubValueTy &StubSym = - GV->hasHiddenVisibility() ? MMIMachO.getHiddenGVStubEntry(MCSym) : - MMIMachO.getGVStubEntry(MCSym); - if (StubSym.getPointer() == 0) - StubSym = MachineModuleInfoImpl:: - StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage()); - } + MCSym = GetARMGVSymbol(GV); } else { assert(ACPV->isExtSymbol() && "unrecognized constant pool value"); MCSym = GetExternalSymbolSymbol(ACPV->getSymbol()); @@ -737,7 +741,8 @@ } void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) { - switch (MI->getOpcode()) { + unsigned Opc = MI->getOpcode(); + switch (Opc) { default: break; case ARM::t2ADDrSPi: case ARM::t2ADDrSPi12: @@ -858,6 +863,61 @@ } return; } + case ARM::MOVi16_pic_ga: + case ARM::t2MOVi16_pic_ga: { + MCInst TmpInst; + TmpInst.setOpcode(Opc == ARM::MOVi16_pic_ga ? ARM::MOVi16 : ARM::t2MOVi16); + TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); + + const GlobalValue *GV = MI->getOperand(1).getGlobal(); + MCSymbol *GVSym = GetARMGVSymbol(GV); + const MCExpr *GVSymExpr = MCSymbolRefExpr::Create(GVSym, OutContext); + MCSymbol *LabelSym = getPICLabel(MAI->getPrivateGlobalPrefix(), + getFunctionNumber(), MI->getOperand(2).getImm(), + OutContext); + const MCExpr *LabelSymExpr = MCSymbolRefExpr::Create(LabelSym, OutContext); + const MCExpr *PCRelExpr = + ARMMCExpr::CreateLower16(MCBinaryExpr::CreateSub(GVSymExpr, + MCBinaryExpr::CreateAdd(LabelSymExpr, + MCConstantExpr::Create(4, OutContext), + OutContext), OutContext), OutContext); + TmpInst.addOperand(MCOperand::CreateExpr(PCRelExpr)); + // Add predicate operands. + TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); + TmpInst.addOperand(MCOperand::CreateReg(0)); + // Add 's' bit operand (always reg0 for this) + TmpInst.addOperand(MCOperand::CreateReg(0)); + OutStreamer.EmitInstruction(TmpInst); + return; + } + case ARM::MOVTi16_pic_ga: + case ARM::t2MOVTi16_pic_ga: { + MCInst TmpInst; + TmpInst.setOpcode(Opc==ARM::MOVTi16_pic_ga ? ARM::MOVTi16 : ARM::t2MOVTi16); + TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); + TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg())); + + const GlobalValue *GV = MI->getOperand(2).getGlobal(); + MCSymbol *GVSym = GetARMGVSymbol(GV); + const MCExpr *GVSymExpr = MCSymbolRefExpr::Create(GVSym, OutContext); + MCSymbol *LabelSym = getPICLabel(MAI->getPrivateGlobalPrefix(), + getFunctionNumber(), MI->getOperand(3).getImm(), + OutContext); + const MCExpr *LabelSymExpr = MCSymbolRefExpr::Create(LabelSym, OutContext); + const MCExpr *PCRelExpr = + ARMMCExpr::CreateUpper16(MCBinaryExpr::CreateSub(GVSymExpr, + MCBinaryExpr::CreateAdd(LabelSymExpr, + MCConstantExpr::Create(4, OutContext), + OutContext), OutContext), OutContext); + TmpInst.addOperand(MCOperand::CreateExpr(PCRelExpr)); + // Add predicate operands. + TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); + TmpInst.addOperand(MCOperand::CreateReg(0)); + // Add 's' bit operand (always reg0 for this) + TmpInst.addOperand(MCOperand::CreateReg(0)); + OutStreamer.EmitInstruction(TmpInst); + return; + } case ARM::tPICADD: { // This is a pseudo op for a label + instruction sequence, which looks like: // LPC0: Modified: llvm/trunk/lib/Target/ARM/ARMAsmPrinter.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMAsmPrinter.h?rev=123619&r1=123618&r2=123619&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMAsmPrinter.h (original) +++ llvm/trunk/lib/Target/ARM/ARMAsmPrinter.h Mon Jan 17 02:03:18 2011 @@ -101,6 +101,8 @@ MCSymbol *GetARMSJLJEHLabel(void) const; + MCSymbol *GetARMGVSymbol(const GlobalValue *GV); + /// EmitMachineConstantPoolValue - Print a machine constantpool value to /// the .s file. virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV); Modified: llvm/trunk/lib/Target/ARM/ARMBaseInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBaseInfo.h?rev=123619&r1=123618&r2=123619&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMBaseInfo.h (original) +++ llvm/trunk/lib/Target/ARM/ARMBaseInfo.h Mon Jan 17 02:03:18 2011 @@ -185,6 +185,18 @@ /// higher 16 bit of the address. Used only via movt instruction. MO_HI16, + /// MO_LO16_NONLAZY_PIC - On a symbol operand "FOO", this represents a + /// relocation containing lower 16 bit of the PC relative address of the + /// non-lazy-ptr indirect symbol, i.e. "FOO$non_lazy_ptr - LABEL". + /// Used only via movw instruction. + MO_LO16_NONLAZY_PIC, + + /// MO_HI16_NONLAZY_PIC - On a symbol operand "FOO", this represents a + /// relocation containing lower 16 bit of the PC relative address of the + /// non-lazy-ptr indirect symbol, i.e. "FOO$non_lazy_ptr - LABEL". + /// Used only via movt instruction. + MO_HI16_NONLAZY_PIC, + /// MO_PLT - On a symbol operand, this represents an ELF PLT reference on a /// call operand. MO_PLT Modified: llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp?rev=123619&r1=123618&r2=123619&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp Mon Jan 17 02:03:18 2011 @@ -561,8 +561,14 @@ case ARMII::Size2Bytes: return 2; // Thumb1 instruction. case ARMII::SizeSpecial: { switch (Opc) { + case ARM::MOVi16_pic_ga: + case ARM::MOVTi16_pic_ga: + case ARM::t2MOVi16_pic_ga: + case ARM::t2MOVTi16_pic_ga: + return 4; case ARM::MOVi32imm: case ARM::t2MOVi32imm: + case ARM::MOV_pic_ga: return 8; case ARM::CONSTPOOL_ENTRY: // If this machine instr is a constant pool entry, its size is recorded as @@ -977,7 +983,7 @@ ARMConstantPoolValue *ACPV = static_cast(MCPE.Val.MachineCPVal); - unsigned PCLabelId = AFI->createConstPoolEntryUId(); + unsigned PCLabelId = AFI->createPICLabelUId(); ARMConstantPoolValue *NewCPV = 0; // FIXME: The below assumes PIC relocation model and that the function // is Thumb mode (t1 or t2). PCAdjustment would be 8 for ARM mode PIC, and Modified: llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp?rev=123619&r1=123618&r2=123619&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp Mon Jan 17 02:03:18 2011 @@ -316,7 +316,7 @@ } /// The next UID to take is the first unused one. - AFI->initConstPoolEntryUId(CPEMIs.size()); + AFI->initPICLabelUId(CPEMIs.size()); // Do the initial scan of the function, building up information about the // sizes of each block, the location of all the water, and finding all of the @@ -1245,7 +1245,7 @@ // No existing clone of this CPE is within range. // We will be generating a new clone. Get a UID for it. - unsigned ID = AFI->createConstPoolEntryUId(); + unsigned ID = AFI->createPICLabelUId(); // Look for water where we can place this CPE. MachineBasicBlock *NewIsland = MF.CreateMachineBasicBlock(); Modified: llvm/trunk/lib/Target/ARM/ARMExpandPseudoInsts.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMExpandPseudoInsts.cpp?rev=123619&r1=123618&r2=123619&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMExpandPseudoInsts.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMExpandPseudoInsts.cpp Mon Jan 17 02:03:18 2011 @@ -765,13 +765,16 @@ case ARM::MOVi32imm: case ARM::MOVCCi32imm: + case ARM::MOV_pic_ga: case ARM::t2MOVi32imm: - case ARM::t2MOVCCi32imm: { + case ARM::t2MOVCCi32imm: + case ARM::t2MOV_pic_ga: { unsigned PredReg = 0; ARMCC::CondCodes Pred = llvm::getInstrPredicate(&MI, PredReg); unsigned DstReg = MI.getOperand(0).getReg(); bool DstIsDead = MI.getOperand(0).isDead(); bool isCC = Opcode == ARM::MOVCCi32imm || Opcode == ARM::t2MOVCCi32imm; + bool isPIC_GA = (Opcode == ARM::t2MOV_pic_ga || Opcode == ARM::MOV_pic_ga); const MachineOperand &MO = MI.getOperand(isCC ? 2 : 1); MachineInstrBuilder LO16, HI16; @@ -798,14 +801,24 @@ break; } - bool isThumb = - (Opcode == ARM::t2MOVi32imm || Opcode == ARM::t2MOVCCi32imm); + unsigned LO16Opc = 0; + unsigned HI16Opc = 0; + if (Opcode == ARM::t2MOVi32imm || Opcode == ARM::t2MOVCCi32imm) { + LO16Opc = ARM::t2MOVi16; + HI16Opc = ARM::t2MOVTi16; + } else if (Opcode == ARM::MOV_pic_ga) { + LO16Opc = ARM::MOVi16_pic_ga; + HI16Opc = ARM::MOVTi16_pic_ga; + } else if (Opcode == ARM::t2MOV_pic_ga) { + LO16Opc = ARM::t2MOVi16_pic_ga; + HI16Opc = ARM::t2MOVTi16_pic_ga; + } else { + LO16Opc = ARM::MOVi16; + HI16Opc = ARM::MOVTi16; + } - LO16 = BuildMI(MBB, MBBI, MI.getDebugLoc(), - TII->get(isThumb ? ARM::t2MOVi16 : ARM::MOVi16), - DstReg); - HI16 = BuildMI(MBB, MBBI, MI.getDebugLoc(), - TII->get(isThumb ? ARM::t2MOVTi16 : ARM::MOVTi16)) + LO16 = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(LO16Opc), DstReg); + HI16 = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(HI16Opc)) .addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead)) .addReg(DstReg); @@ -815,16 +828,30 @@ unsigned Hi16 = (Imm >> 16) & 0xffff; LO16 = LO16.addImm(Lo16); HI16 = HI16.addImm(Hi16); + } else if (isPIC_GA) { + unsigned LabelId = MI.getOperand(2).getImm(); + const GlobalValue *GV = MO.getGlobal(); + unsigned TF = MO.getTargetFlags(); + LO16 = LO16.addGlobalAddress(GV, MO.getOffset(), + TF | ARMII::MO_LO16_NONLAZY_PIC) + .addImm(LabelId); + HI16 = HI16.addGlobalAddress(GV, MO.getOffset(), + TF | ARMII::MO_HI16_NONLAZY_PIC) + .addImm(LabelId); } else { const GlobalValue *GV = MO.getGlobal(); unsigned TF = MO.getTargetFlags(); LO16 = LO16.addGlobalAddress(GV, MO.getOffset(), TF | ARMII::MO_LO16); HI16 = HI16.addGlobalAddress(GV, MO.getOffset(), TF | ARMII::MO_HI16); } + (*LO16).setMemRefs(MI.memoperands_begin(), MI.memoperands_end()); (*HI16).setMemRefs(MI.memoperands_begin(), MI.memoperands_end()); - LO16.addImm(Pred).addReg(PredReg); - HI16.addImm(Pred).addReg(PredReg); + + if (!isPIC_GA) { + LO16.addImm(Pred).addReg(PredReg); + HI16.addImm(Pred).addReg(PredReg); + } TransferImpOps(MI, LO16, HI16); MI.eraseFromParent(); break; Modified: llvm/trunk/lib/Target/ARM/ARMFastISel.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMFastISel.cpp?rev=123619&r1=123618&r2=123619&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMFastISel.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMFastISel.cpp Mon Jan 17 02:03:18 2011 @@ -517,7 +517,7 @@ // Grab index. unsigned PCAdj = (RelocM != Reloc::PIC_) ? 0 : (Subtarget->isThumb() ? 4 : 8); - unsigned Id = AFI->createConstPoolEntryUId(); + unsigned Id = AFI->createPICLabelUId(); ARMConstantPoolValue *CPV = new ARMConstantPoolValue(GV, Id, ARMCP::CPValue, PCAdj); unsigned Idx = MCP.getConstantPoolIndex(CPV, Align); Modified: llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp?rev=123619&r1=123618&r2=123619&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp Mon Jan 17 02:03:18 2011 @@ -127,8 +127,7 @@ SDValue &Offset); bool SelectAddrMode6(SDNode *Parent, SDValue N, SDValue &Addr,SDValue &Align); - bool SelectAddrModePC(SDValue N, SDValue &Offset, - SDValue &Label); + bool SelectAddrModePC(SDValue N, SDValue &Offset, SDValue &Label); // Thumb Addressing Modes: bool SelectThumbAddrModeRR(SDValue N, SDValue &Base, SDValue &Offset); Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=123619&r1=123618&r2=123619&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Mon Jan 17 02:03:18 2011 @@ -734,6 +734,7 @@ switch (Opcode) { default: return 0; case ARMISD::Wrapper: return "ARMISD::Wrapper"; + case ARMISD::WrapperPIC: return "ARMISD::WrapperPIC"; case ARMISD::WrapperJT: return "ARMISD::WrapperJT"; case ARMISD::CALL: return "ARMISD::CALL"; case ARMISD::CALL_PRED: return "ARMISD::CALL_PRED"; @@ -1315,7 +1316,7 @@ if (GlobalAddressSDNode *G = dyn_cast(Callee)) { const GlobalValue *GV = G->getGlobal(); // Create a constant pool entry for the callee address - unsigned ARMPCLabelIndex = AFI->createConstPoolEntryUId(); + unsigned ARMPCLabelIndex = AFI->createPICLabelUId(); ARMConstantPoolValue *CPV = new ARMConstantPoolValue(GV, ARMPCLabelIndex, ARMCP::CPValue, 0); @@ -1330,7 +1331,7 @@ const char *Sym = S->getSymbol(); // Create a constant pool entry for the callee address - unsigned ARMPCLabelIndex = AFI->createConstPoolEntryUId(); + unsigned ARMPCLabelIndex = AFI->createPICLabelUId(); ARMConstantPoolValue *CPV = new ARMConstantPoolValue(*DAG.getContext(), Sym, ARMPCLabelIndex, 0); // Get the address of the callee into a register @@ -1352,7 +1353,7 @@ isLocalARMFunc = !Subtarget->isThumb() && (!isExt || !ARMInterworking); // tBX takes a register source operand. if (isARMFunc && Subtarget->isThumb1Only() && !Subtarget->hasV5TOps()) { - unsigned ARMPCLabelIndex = AFI->createConstPoolEntryUId(); + unsigned ARMPCLabelIndex = AFI->createPICLabelUId(); ARMConstantPoolValue *CPV = new ARMConstantPoolValue(GV, ARMPCLabelIndex, ARMCP::CPValue, 4); @@ -1381,7 +1382,7 @@ // tBX takes a register source operand. const char *Sym = S->getSymbol(); if (isARMFunc && Subtarget->isThumb1Only() && !Subtarget->hasV5TOps()) { - unsigned ARMPCLabelIndex = AFI->createConstPoolEntryUId(); + unsigned ARMPCLabelIndex = AFI->createPICLabelUId(); ARMConstantPoolValue *CPV = new ARMConstantPoolValue(*DAG.getContext(), Sym, ARMPCLabelIndex, 4); SDValue CPAddr = DAG.getTargetConstantPool(CPV, getPointerTy(), 4); @@ -1808,7 +1809,7 @@ CPAddr = DAG.getTargetConstantPool(BA, PtrVT, 4); } else { unsigned PCAdj = Subtarget->isThumb() ? 4 : 8; - ARMPCLabelIndex = AFI->createConstPoolEntryUId(); + ARMPCLabelIndex = AFI->createPICLabelUId(); ARMConstantPoolValue *CPV = new ARMConstantPoolValue(BA, ARMPCLabelIndex, ARMCP::CPBlockAddress, PCAdj); @@ -1833,7 +1834,7 @@ unsigned char PCAdj = Subtarget->isThumb() ? 4 : 8; MachineFunction &MF = DAG.getMachineFunction(); ARMFunctionInfo *AFI = MF.getInfo(); - unsigned ARMPCLabelIndex = AFI->createConstPoolEntryUId(); + unsigned ARMPCLabelIndex = AFI->createPICLabelUId(); ARMConstantPoolValue *CPV = new ARMConstantPoolValue(GA->getGlobal(), ARMPCLabelIndex, ARMCP::CPValue, PCAdj, ARMCP::TLSGD, true); @@ -1878,7 +1879,7 @@ if (GV->isDeclaration()) { MachineFunction &MF = DAG.getMachineFunction(); ARMFunctionInfo *AFI = MF.getInfo(); - unsigned ARMPCLabelIndex = AFI->createConstPoolEntryUId(); + unsigned ARMPCLabelIndex = AFI->createPICLabelUId(); // Initial exec model. unsigned char PCAdj = Subtarget->isThumb() ? 4 : 8; ARMConstantPoolValue *CPV = @@ -1949,36 +1950,55 @@ Result = DAG.getLoad(PtrVT, dl, Chain, Result, MachinePointerInfo::getGOT(), false, false, 0); return Result; + } + + // If we have T2 ops, we can materialize the address directly via movt/movw + // pair. This is always cheaper. + if (Subtarget->useMovt()) { + // FIXME: Once remat is capable of dealing with instructions with register + // operands, expand this into two nodes. + return DAG.getNode(ARMISD::Wrapper, dl, PtrVT, + DAG.getTargetGlobalAddress(GV, dl, PtrVT)); } else { - // If we have T2 ops, we can materialize the address directly via movt/movw - // pair. This is always cheaper. - if (Subtarget->useMovt()) { - return DAG.getNode(ARMISD::Wrapper, dl, PtrVT, - DAG.getTargetGlobalAddress(GV, dl, PtrVT)); - } else { - SDValue CPAddr = DAG.getTargetConstantPool(GV, PtrVT, 4); - CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr); - return DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), CPAddr, - MachinePointerInfo::getConstantPool(), - false, false, 0); - } + SDValue CPAddr = DAG.getTargetConstantPool(GV, PtrVT, 4); + CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr); + return DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), CPAddr, + MachinePointerInfo::getConstantPool(), + false, false, 0); } } SDValue ARMTargetLowering::LowerGlobalAddressDarwin(SDValue Op, SelectionDAG &DAG) const { - MachineFunction &MF = DAG.getMachineFunction(); - ARMFunctionInfo *AFI = MF.getInfo(); - unsigned ARMPCLabelIndex = 0; EVT PtrVT = getPointerTy(); DebugLoc dl = Op.getDebugLoc(); const GlobalValue *GV = cast(Op)->getGlobal(); Reloc::Model RelocM = getTargetMachine().getRelocationModel(); + MachineFunction &MF = DAG.getMachineFunction(); + ARMFunctionInfo *AFI = MF.getInfo(); + + if (Subtarget->useMovt()) { + // FIXME: Once remat is capable of dealing with instructions with register + // operands, expand this into two nodes. + if (RelocM != Reloc::PIC_) + return DAG.getNode(ARMISD::Wrapper, dl, PtrVT, + DAG.getTargetGlobalAddress(GV, dl, PtrVT)); + + // FIXME: Not a constant pool! + unsigned PICLabelIndex = AFI->createPICLabelUId(); + SDValue PICLabel = DAG.getConstant(PICLabelIndex, MVT::i32); + SDValue Result = DAG.getNode(ARMISD::WrapperPIC, dl, PtrVT, + DAG.getTargetGlobalAddress(GV, dl, PtrVT), + PICLabel); + return DAG.getNode(ARMISD::PIC_ADD, dl, PtrVT, Result, PICLabel); + } + + unsigned ARMPCLabelIndex = 0; SDValue CPAddr; - if (RelocM == Reloc::Static) + if (RelocM == Reloc::Static) { CPAddr = DAG.getTargetConstantPool(GV, PtrVT, 4); - else { - ARMPCLabelIndex = AFI->createConstPoolEntryUId(); + } else { + ARMPCLabelIndex = AFI->createPICLabelUId(); unsigned PCAdj = (RelocM != Reloc::PIC_) ? 0 : (Subtarget->isThumb()?4:8); ARMConstantPoolValue *CPV = new ARMConstantPoolValue(GV, ARMPCLabelIndex, ARMCP::CPValue, PCAdj); @@ -2009,7 +2029,7 @@ "GLOBAL OFFSET TABLE not implemented for non-ELF targets"); MachineFunction &MF = DAG.getMachineFunction(); ARMFunctionInfo *AFI = MF.getInfo(); - unsigned ARMPCLabelIndex = AFI->createConstPoolEntryUId(); + unsigned ARMPCLabelIndex = AFI->createPICLabelUId(); EVT PtrVT = getPointerTy(); DebugLoc dl = Op.getDebugLoc(); unsigned PCAdj = Subtarget->isThumb() ? 4 : 8; @@ -2062,7 +2082,7 @@ case Intrinsic::eh_sjlj_lsda: { MachineFunction &MF = DAG.getMachineFunction(); ARMFunctionInfo *AFI = MF.getInfo(); - unsigned ARMPCLabelIndex = AFI->createConstPoolEntryUId(); + unsigned ARMPCLabelIndex = AFI->createPICLabelUId(); EVT PtrVT = getPointerTy(); DebugLoc dl = Op.getDebugLoc(); Reloc::Model RelocM = getTargetMachine().getRelocationModel(); Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.h?rev=123619&r1=123618&r2=123619&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.h (original) +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.h Mon Jan 17 02:03:18 2011 @@ -34,6 +34,8 @@ Wrapper, // Wrapper - A wrapper node for TargetConstantPool, // TargetExternalSymbol, and TargetGlobalAddress. + WrapperPIC, // WrapperPIC - A wrapper node for TargetGlobalAddress in + // PIC mode. WrapperJT, // WrapperJT - A wrapper node for TargetJumpTable CALL, // Function call. Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=123619&r1=123618&r2=123619&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Mon Jan 17 02:03:18 2011 @@ -70,6 +70,7 @@ // Node definitions. def ARMWrapper : SDNode<"ARMISD::Wrapper", SDTIntUnaryOp>; def ARMWrapperJT : SDNode<"ARMISD::WrapperJT", SDTIntBinOp>; +def ARMWrapperPIC : SDNode<"ARMISD::WrapperPIC", SDTIntBinOp>; def ARMcallseq_start : SDNode<"ISD::CALLSEQ_START", SDT_ARMCallSeqStart, [SDNPHasChain, SDNPOutGlue]>; @@ -1930,7 +1931,10 @@ let Inst{25} = 1; } -let Constraints = "$src = $Rd" in +def MOVi16_pic_ga : PseudoInst<(outs GPR:$Rd), + (ins i32imm:$addr, pclabel:$id), IIC_iMOVi, []>; + +let Constraints = "$src = $Rd" in { def MOVTi16 : AI1<0b1010, (outs GPR:$Rd), (ins GPR:$src, i32imm_hilo16:$imm), DPFrm, IIC_iMOVi, "movt", "\t$Rd, $imm", @@ -1947,6 +1951,11 @@ let Inst{25} = 1; } +def MOVTi16_pic_ga : PseudoInst<(outs GPR:$Rd), + (ins GPR:$src, i32imm:$addr, pclabel:$id), IIC_iMOVi, []>; + +} // Constraints + def : ARMPat<(or GPR:$src, 0xffff0000), (MOVTi16 GPR:$src, 0xffff)>, Requires<[IsARM, HasV6T2]>; @@ -3363,11 +3372,17 @@ // This is a single pseudo instruction, the benefit is that it can be remat'd // as a single unit instead of having to handle reg inputs. // FIXME: Remove this when we can do generalized remat. -let isReMaterializable = 1, isMoveImm = 1 in +let isReMaterializable = 1, isMoveImm = 1 in { def MOVi32imm : PseudoInst<(outs GPR:$dst), (ins i32imm:$src), IIC_iMOVix2, [(set GPR:$dst, (arm_i32imm:$src))]>, Requires<[IsARM]>; +def MOV_pic_ga : PseudoInst<(outs GPR:$dst), + (ins i32imm:$addr, pclabel:$id), IIC_iMOVix2, + [(set GPR:$dst, (ARMWrapperPIC tglobaladdr:$addr, imm:$id))]>, + Requires<[IsARM, UseMovt]>; +} // isReMaterializable = 1, isMoveImm = 1 in + // ConstantPool, GlobalAddress, and JumpTable def : ARMPat<(ARMWrapper tglobaladdr :$dst), (LEApcrel tglobaladdr :$dst)>, Requires<[IsARM, DontUseMovt]>; Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td?rev=123619&r1=123618&r2=123619&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td Mon Jan 17 02:03:18 2011 @@ -1696,7 +1696,10 @@ let Inst{7-0} = imm{7-0}; } -let Constraints = "$src = $Rd" in +def t2MOVi16_pic_ga : PseudoInst<(outs rGPR:$Rd), + (ins i32imm:$addr, pclabel:$id), IIC_iMOVi, []>; + +let Constraints = "$src = $Rd" in { def t2MOVTi16 : T2I<(outs rGPR:$Rd), (ins rGPR:$src, i32imm_hilo16:$imm), IIC_iMOVi, "movt", "\t$Rd, $imm", @@ -1718,6 +1721,10 @@ let Inst{7-0} = imm{7-0}; } +def t2MOVTi16_pic_ga : PseudoInst<(outs rGPR:$Rd), + (ins rGPR:$src, i32imm:$addr, pclabel:$id), IIC_iMOVi, []>; +} // Constraints + def : T2Pat<(or rGPR:$src, 0xffff0000), (t2MOVTi16 rGPR:$src, 0xffff)>; //===----------------------------------------------------------------------===// @@ -3209,11 +3216,17 @@ // 32-bit immediate using movw + movt. // This is a single pseudo instruction to make it re-materializable. // FIXME: Remove this when we can do generalized remat. -let isReMaterializable = 1, isMoveImm = 1 in +let isReMaterializable = 1, isMoveImm = 1 in { def t2MOVi32imm : PseudoInst<(outs rGPR:$dst), (ins i32imm:$src), IIC_iMOVix2, [(set rGPR:$dst, (i32 imm:$src))]>, Requires<[IsThumb, HasV6T2]>; +def t2MOV_pic_ga : PseudoInst<(outs rGPR:$dst), + (ins i32imm:$addr, pclabel:$id), IIC_iMOVix2, + [(set rGPR:$dst, (ARMWrapperPIC tglobaladdr:$addr, imm:$id))]>, + Requires<[IsThumb2, UseMovt]>; +} // isReMaterializable = 1, isMoveImm = 1 in + // ConstantPool, GlobalAddress, and JumpTable def : T2Pat<(ARMWrapper tglobaladdr :$dst), (t2LEApcrel tglobaladdr :$dst)>, Requires<[IsThumb2, DontUseMovt]>; Modified: llvm/trunk/lib/Target/ARM/ARMJITInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMJITInfo.h?rev=123619&r1=123618&r2=123619&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMJITInfo.h (original) +++ llvm/trunk/lib/Target/ARM/ARMJITInfo.h Mon Jan 17 02:03:18 2011 @@ -105,7 +105,7 @@ /// model is PIC. void Initialize(const MachineFunction &MF, bool isPIC) { const ARMFunctionInfo *AFI = MF.getInfo(); - ConstPoolId2AddrMap.resize(AFI->getNumConstPoolEntries()); + ConstPoolId2AddrMap.resize(AFI->getNumPICLabels()); JumpTableId2AddrMap.resize(AFI->getNumJumpTables()); IsPIC = isPIC; } Modified: llvm/trunk/lib/Target/ARM/ARMMachineFunctionInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMMachineFunctionInfo.h?rev=123619&r1=123618&r2=123619&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMMachineFunctionInfo.h (original) +++ llvm/trunk/lib/Target/ARM/ARMMachineFunctionInfo.h Mon Jan 17 02:03:18 2011 @@ -87,7 +87,7 @@ /// unsigned JumpTableUId; - unsigned ConstPoolEntryUId; + unsigned PICLabelUId; /// VarArgsFrameIndex - FrameIndex for start of varargs area. int VarArgsFrameIndex; @@ -104,8 +104,8 @@ FramePtrSpillOffset(0), GPRCS1Offset(0), GPRCS2Offset(0), DPRCSOffset(0), GPRCS1Size(0), GPRCS2Size(0), DPRCSSize(0), GPRCS1Frames(0), GPRCS2Frames(0), DPRCSFrames(0), - JumpTableUId(0), ConstPoolEntryUId(0), VarArgsFrameIndex(0), - HasITBlocks(false) {} + JumpTableUId(0), PICLabelUId(0), + VarArgsFrameIndex(0), HasITBlocks(false) {} explicit ARMFunctionInfo(MachineFunction &MF) : isThumb(MF.getTarget().getSubtarget().isThumb()), @@ -116,8 +116,8 @@ GPRCS1Size(0), GPRCS2Size(0), DPRCSSize(0), GPRCS1Frames(32), GPRCS2Frames(32), DPRCSFrames(32), SpilledCSRegs(MF.getTarget().getRegisterInfo()->getNumRegs()), - JumpTableUId(0), ConstPoolEntryUId(0), VarArgsFrameIndex(0), - HasITBlocks(false) {} + JumpTableUId(0), PICLabelUId(0), + VarArgsFrameIndex(0), HasITBlocks(false) {} bool isThumbFunction() const { return isThumb; } bool isThumb1OnlyFunction() const { return isThumb && !hasThumb2; } @@ -227,16 +227,16 @@ return JumpTableUId; } - void initConstPoolEntryUId(unsigned UId) { - ConstPoolEntryUId = UId; + void initPICLabelUId(unsigned UId) { + PICLabelUId = UId; } - unsigned getNumConstPoolEntries() const { - return ConstPoolEntryUId; + unsigned getNumPICLabels() const { + return PICLabelUId; } - unsigned createConstPoolEntryUId() { - return ConstPoolEntryUId++; + unsigned createPICLabelUId() { + return PICLabelUId++; } int getVarArgsFrameIndex() const { return VarArgsFrameIndex; } Modified: llvm/trunk/lib/Target/ARM/ARMSubtarget.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMSubtarget.cpp?rev=123619&r1=123618&r2=123619&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMSubtarget.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMSubtarget.cpp Mon Jan 17 02:03:18 2011 @@ -25,8 +25,7 @@ cl::desc("Reserve R9, making it unavailable as GPR")); static cl::opt -UseMOVT("arm-use-movt", - cl::init(true), cl::Hidden); +UseMOVT("arm-darwin-use-movt", cl::init(false), cl::Hidden); static cl::opt StrictAlign("arm-strict-align", cl::Hidden, @@ -45,7 +44,7 @@ , NoARM(false) , PostRAScheduler(false) , IsR9Reserved(ReserveR9) - , UseMovt(UseMOVT) + , UseMovt(false) , HasFP16(false) , HasD16(false) , HasHardwareDivide(false) @@ -147,8 +146,16 @@ if (isAAPCS_ABI()) stackAlignment = 8; - if (isTargetDarwin()) + if (!isTargetDarwin()) + UseMovt = hasV6T2Ops(); + else { IsR9Reserved = ReserveR9 | (ARMArchVersion < V6); + if (UseMOVT && hasV6T2Ops()) { + unsigned Maj, Min, Rev; + TargetTriple.getDarwinNumber(Maj, Min, Rev); + UseMovt = (Maj > 4 || Min > 2); + } + } if (!isThumb() || hasThumb2()) PostRAScheduler = true; Modified: llvm/trunk/test/CodeGen/ARM/2010-11-30-reloc-movt.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/2010-11-30-reloc-movt.ll?rev=123619&r1=123618&r2=123619&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/2010-11-30-reloc-movt.ll (original) +++ llvm/trunk/test/CodeGen/ARM/2010-11-30-reloc-movt.ll Mon Jan 17 02:03:18 2011 @@ -1,4 +1,4 @@ -; RUN: llc %s -mtriple=armv7-linux-gnueabi -arm-use-movt -filetype=obj -o - | \ +; RUN: llc %s -mtriple=armv7-linux-gnueabi -filetype=obj -o - | \ ; RUN: elf-dump --dump-section-data | FileCheck -check-prefix=OBJ %s target triple = "armv7-none-linux-gnueabi" Modified: llvm/trunk/test/CodeGen/ARM/2010-12-13-reloc-pic.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/2010-12-13-reloc-pic.ll?rev=123619&r1=123618&r2=123619&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/2010-12-13-reloc-pic.ll (original) +++ llvm/trunk/test/CodeGen/ARM/2010-12-13-reloc-pic.ll Mon Jan 17 02:03:18 2011 @@ -1,4 +1,4 @@ -; RUN: llc %s -mtriple=armv7-linux-gnueabi -arm-use-movt -relocation-model=pic -filetype=obj -o - | \ +; RUN: llc %s -mtriple=armv7-linux-gnueabi -relocation-model=pic -filetype=obj -o - | \ ; RUN: elf-dump --dump-section-data | FileCheck -check-prefix=PIC01 %s ;; FIXME: Reduce this test further, or even better, Modified: llvm/trunk/test/CodeGen/ARM/2010-12-15-elf-lcomm.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/2010-12-15-elf-lcomm.ll?rev=123619&r1=123618&r2=123619&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/2010-12-15-elf-lcomm.ll (original) +++ llvm/trunk/test/CodeGen/ARM/2010-12-15-elf-lcomm.ll Mon Jan 17 02:03:18 2011 @@ -1,6 +1,6 @@ -; RUN: llc %s -mtriple=armv7-linux-gnueabi -arm-use-movt -filetype=obj -o - | \ +; RUN: llc %s -mtriple=armv7-linux-gnueabi -filetype=obj -o - | \ ; RUN: elf-dump --dump-section-data | FileCheck -check-prefix=OBJ %s -; RUN: llc %s -mtriple=armv7-linux-gnueabi -arm-use-movt -o - | \ +; RUN: llc %s -mtriple=armv7-linux-gnueabi -o - | \ ; RUN: FileCheck -check-prefix=ASM %s From geek4civic at gmail.com Mon Jan 17 04:35:27 2011 From: geek4civic at gmail.com (NAKAMURA Takumi) Date: Mon, 17 Jan 2011 19:35:27 +0900 Subject: [llvm-commits] [PATCH] Some tweaks (PathV2, Archive, &c) Message-ID: Michael and guys, Four patches are here. Checked on Windows XP, Windows 7 and CentOS5. They are trivial, and feel free to commit them by yourself with appropriate approval, or improve them, please ;) [Win/posix] * 0002-lib-Archive-ArchiveWriter.cpp-Don-t-concatenate-.patch.txt On Posix, we would see weird directories in the temporary directory. eg.) /tmp/f8-d3-97-7c/home/chapuni/BUILD/llvm-static/test/Linker/Output On Win32, make_unique() tried to make invalid directory and path. eg.) 59-7f-5e-53C:/cygwin/home/.... For now, I got rid of adding prefix or suffix to the model to unique(). [Win32] * 0001-lib-Support-Windows-Signals.inc-Showstopper-dial.patch.txt On mingw and msvc, I think it would be enough. :) * 0003-Windows-PathV2.inc-MoveFileEx-can-behave-like-Po.patch.txt On win32, we can use MoveFileEx(). * 0004-Windows-PathV2.inc-For-CryptAcquireContext-CRYPT.patch.txt On some circumstances (afaik some Windows XP), CryptAcquireContext to default would fail. (On windows7, it succeeds) CRYPT_VERIFYCONTEXT can provide a trivial context, I understand. Anyway, I think Crypto API would be overkill for random number generation. ...Takumi -------------- next part -------------- From f1da4feb13fc845fc2f909457725f563907ee0db Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Mon, 17 Jan 2011 14:39:59 +0900 Subject: [PATCH 1/4] lib/Support/Windows/Signals.inc: "Showstopper" dialogs may be suppressed with SetErrorMode() on Windows 7. --- lib/Support/Windows/Signals.inc | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diff --git a/lib/Support/Windows/Signals.inc b/lib/Support/Windows/Signals.inc index c0e3eca..14f3f21 100644 --- a/lib/Support/Windows/Signals.inc +++ b/lib/Support/Windows/Signals.inc @@ -112,6 +112,9 @@ static void RegisterHandler() { #ifdef _MSC_VER _CrtSetReportHook(CRTReportHook); #endif + SetErrorMode(SEM_FAILCRITICALERRORS | + SEM_NOGPFAULTERRORBOX | + SEM_NOOPENFILEERRORBOX); ExitOnUnhandledExceptions = true; } -- 1.7.1.GIT -------------- next part -------------- From 51c1d4cf0f6f276169941e7307f101a7a56328a9 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Mon, 17 Jan 2011 18:00:25 +0900 Subject: [PATCH 2/4] lib/Archive/ArchiveWriter.cpp: Don't concatenate the model string before archPath, when archPath is absolute! --- lib/Archive/ArchiveWriter.cpp | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Archive/ArchiveWriter.cpp b/lib/Archive/ArchiveWriter.cpp index 59fb7bd..063000c 100644 --- a/lib/Archive/ArchiveWriter.cpp +++ b/lib/Archive/ArchiveWriter.cpp @@ -364,7 +364,7 @@ Archive::writeToDisk(bool CreateSymbolTable, bool TruncateNames, bool Compress, // Create a temporary file to store the archive in SmallString<128> TempArchivePath; int ArchFD; - if (error_code ec = sys::fs::unique_file("%%-%%-%%-%%" + archPath.str(), + if (error_code ec = sys::fs::unique_file("%%-%%-%%-%%", ArchFD, TempArchivePath)) { if (ErrMsg) *ErrMsg = ec.message(); return true; @@ -421,7 +421,7 @@ Archive::writeToDisk(bool CreateSymbolTable, bool TruncateNames, bool Compress, // Open another temporary file in order to avoid invalidating the // mmapped data - if (error_code ec = sys::fs::unique_file("%%-%%-%%-%%" + archPath.str(), + if (error_code ec = sys::fs::unique_file("%%-%%-%%-%%", ArchFD, TempArchiveWithSymbolTablePath)) { if (ErrMsg) *ErrMsg = ec.message(); return true; -- 1.7.1.GIT -------------- next part -------------- From 251774b2389de9cc83581da9e5c28857e59f7ec3 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Mon, 17 Jan 2011 18:03:23 +0900 Subject: [PATCH 3/4] Windows/PathV2.inc: MoveFileEx() can behave like Posix's mv(1) to specify MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING. --- lib/Support/Windows/PathV2.inc | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/lib/Support/Windows/PathV2.inc b/lib/Support/Windows/PathV2.inc index f4629a1..a631bc6 100644 --- a/lib/Support/Windows/PathV2.inc +++ b/lib/Support/Windows/PathV2.inc @@ -310,7 +310,8 @@ error_code rename(const Twine &from, const Twine &to) { if (error_code ec = UTF8ToUTF16(f, wide_from)) return ec; if (error_code ec = UTF8ToUTF16(t, wide_to)) return ec; - if (!::MoveFileW(wide_from.begin(), wide_to.begin())) + if (!::MoveFileExW(wide_from.begin(), wide_to.begin(), + MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING)) return windows_error(::GetLastError()); return success; -- 1.7.1.GIT -------------- next part -------------- From d65e8aff05e5afb9249cdcae4c863c68ec77c0c1 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Mon, 17 Jan 2011 18:15:14 +0900 Subject: [PATCH 4/4] Windows/PathV2.inc: For CryptAcquireContext(), CRYPT_VERIFYCONTEXT may be specified for easy use. --- lib/Support/Windows/PathV2.inc | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/lib/Support/Windows/PathV2.inc b/lib/Support/Windows/PathV2.inc index a631bc6..b36b291 100644 --- a/lib/Support/Windows/PathV2.inc +++ b/lib/Support/Windows/PathV2.inc @@ -525,7 +525,7 @@ error_code unique_file(const Twine &model, int &result_fd, NULL, NULL, PROV_RSA_FULL, - 0)) + CRYPT_VERIFYCONTEXT)) return windows_error(::GetLastError()); ScopedCryptContext CryptoProvider(HCPC); -- 1.7.1.GIT From 6yearold at gmail.com Mon Jan 17 05:13:36 2011 From: 6yearold at gmail.com (arrowdodger) Date: Mon, 17 Jan 2011 14:13:36 +0300 Subject: [llvm-commits] [patch][cmake] More config.h.cmake fixes. Message-ID: Some more easy stuff in config-ix.cmake and cmake.config.h. Bonus: two typos in Makefiles. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110117/1523b0ce/attachment.html -------------- next part -------------- A non-text attachment was scrubbed... Name: cmake1.patch Type: application/octet-stream Size: 5594 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20110117/1523b0ce/attachment.obj From kalle.raiskila at nokia.com Mon Jan 17 05:59:20 2011 From: kalle.raiskila at nokia.com (Kalle Raiskila) Date: Mon, 17 Jan 2011 11:59:20 -0000 Subject: [llvm-commits] [llvm] r123620 - in /llvm/trunk: lib/Target/CellSPU/SPUISelLowering.cpp test/CodeGen/CellSPU/stores.ll Message-ID: <20110117115920.77A3A2A6C12C@llvm.org> Author: kraiskil Date: Mon Jan 17 05:59:20 2011 New Revision: 123620 URL: http://llvm.org/viewvc/llvm-project?rev=123620&view=rev Log: Don't crash SPU BE with memory accesses with big alignmnet. Modified: llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp llvm/trunk/test/CodeGen/CellSPU/stores.ll Modified: llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp?rev=123620&r1=123619&r2=123620&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp (original) +++ llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp Mon Jan 17 05:59:20 2011 @@ -560,7 +560,7 @@ assert( LN->getAddressingMode() == ISD::UNINDEXED && "we should get only UNINDEXED adresses"); // clean aligned loads can be selected as-is - if (InVT.getSizeInBits() == 128 && alignment == 16) + if (InVT.getSizeInBits() == 128 && (alignment%16) == 0) return SDValue(); // Get pointerinfos to the memory chunk(s) that contain the data to load @@ -573,7 +573,7 @@ SDValue basePtr = LN->getBasePtr(); SDValue rotate; - if (alignment == 16) { + if ((alignment%16) == 0) { ConstantSDNode *CN; // Special cases for a known aligned load to simplify the base pointer @@ -777,7 +777,7 @@ assert( SN->getAddressingMode() == ISD::UNINDEXED && "we should get only UNINDEXED adresses"); // clean aligned loads can be selected as-is - if (StVT.getSizeInBits() == 128 && alignment == 16) + if (StVT.getSizeInBits() == 128 && (alignment%16) == 0) return SDValue(); SDValue alignLoadVec; @@ -785,7 +785,7 @@ SDValue the_chain = SN->getChain(); SDValue insertEltOffs; - if (alignment == 16) { + if ((alignment%16) == 0) { ConstantSDNode *CN; // Special cases for a known aligned load to simplify the base pointer // and insertion byte: Modified: llvm/trunk/test/CodeGen/CellSPU/stores.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CellSPU/stores.ll?rev=123620&r1=123619&r2=123620&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/CellSPU/stores.ll (original) +++ llvm/trunk/test/CodeGen/CellSPU/stores.ll Mon Jan 17 05:59:20 2011 @@ -162,3 +162,12 @@ store i32 %val, i32*%ptr, align 2 ret void } + +define void @store_v8( <8 x float> %val, <8 x float>* %ptr ) +{ +;CHECK: stq +;CHECK: stq +;CHECK: bi $lr + store <8 x float> %val, <8 x float>* %ptr + ret void +} From benny.kra at googlemail.com Mon Jan 17 06:04:57 2011 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Mon, 17 Jan 2011 12:04:57 -0000 Subject: [llvm-commits] [llvm] r123621 - in /llvm/trunk: lib/CodeGen/SelectionDAG/TargetLowering.cpp test/CodeGen/X86/ctpop-combine.ll Message-ID: <20110117120457.9B2992A6C12C@llvm.org> Author: d0k Date: Mon Jan 17 06:04:57 2011 New Revision: 123621 URL: http://llvm.org/viewvc/llvm-project?rev=123621&view=rev Log: Add a DAGCombine to turn (ctpop x) u< 2 into (x & x-1) == 0. This shaves off 4 popcounts from the hacked 186.crafty source. This is enabled even when a native popcount instruction is available. The combined code is one operation longer but it should be faster nevertheless. Added: llvm/trunk/test/CodeGen/X86/ctpop-combine.ll Modified: llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp?rev=123621&r1=123620&r2=123621&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp Mon Jan 17 06:04:57 2011 @@ -1870,6 +1870,30 @@ } } + SDValue CTPOP = N0; + // Look through truncs that don't change the value of a ctpop. + if (N0.hasOneUse() && N0.getOpcode() == ISD::TRUNCATE) + CTPOP = N0.getOperand(0); + + if (CTPOP.hasOneUse() && CTPOP.getOpcode() == ISD::CTPOP && + (N0 == CTPOP || N0.getValueType().getSizeInBits() >= + Log2_32_Ceil(CTPOP.getValueType().getSizeInBits()))) { + EVT CTVT = CTPOP.getValueType(); + SDValue CTOp = CTPOP.getOperand(0); + + // (ctpop x) u< 2 -> (x & x-1) == 0 + // (ctpop x) u> 1 -> (x & x-1) != 0 + if ((Cond == ISD::SETULT && C1 == 2) || (Cond == ISD::SETUGT && C1 == 1)){ + SDValue Sub = DAG.getNode(ISD::SUB, dl, CTVT, CTOp, + DAG.getConstant(1, CTVT)); + SDValue And = DAG.getNode(ISD::AND, dl, CTVT, CTOp, Sub); + ISD::CondCode CC = Cond == ISD::SETULT ? ISD::SETEQ : ISD::SETNE; + return DAG.getSetCC(dl, VT, And, DAG.getConstant(0, CTVT), CC); + } + + // TODO: (ctpop x) == 1 -> x && (x & x-1) == 0 iff ctpop is illegal. + } + // If the LHS is '(and load, const)', the RHS is 0, // the test is for equality or unsigned, and all 1 bits of the const are // in the same partial word, see if we can shorten the load. Added: llvm/trunk/test/CodeGen/X86/ctpop-combine.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/ctpop-combine.ll?rev=123621&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/ctpop-combine.ll (added) +++ llvm/trunk/test/CodeGen/X86/ctpop-combine.ll Mon Jan 17 06:04:57 2011 @@ -0,0 +1,31 @@ +; RUN: llc -march=x86-64 < %s | FileCheck %s + +declare i64 @llvm.ctpop.i64(i64) nounwind readnone + +define i32 @test1(i64 %x) nounwind readnone { + %count = tail call i64 @llvm.ctpop.i64(i64 %x) + %cast = trunc i64 %count to i32 + %cmp = icmp ugt i32 %cast, 1 + %conv = zext i1 %cmp to i32 + ret i32 %conv +; CHECK: test1: +; CHECK: leaq -1(%rdi) +; CHECK-NEXT: testq +; CHECK-NEXT: setne +; CHECK: ret +} + + +define i32 @test2(i64 %x) nounwind readnone { + %count = tail call i64 @llvm.ctpop.i64(i64 %x) + %cast = trunc i64 %count to i32 + %cmp = icmp ult i32 %cast, 2 + %conv = zext i1 %cmp to i32 + ret i32 %conv +; CHECK: test2: +; CHECK: leaq -1(%rdi) +; CHECK-NEXT: testq +; CHECK-NEXT: sete +; CHECK: ret +} + From benny.kra at googlemail.com Mon Jan 17 06:24:34 2011 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Mon, 17 Jan 2011 13:24:34 +0100 Subject: [llvm-commits] [llvm] r123547 - /llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp In-Reply-To: References: <20110115203031.19E282A6C12C@llvm.org> Message-ID: On 16.01.2011, at 02:02, Chris Lattner wrote: > One interesting thing that I see is that the calls are often of the form: > > icmp_ugt(ctpop(a), ctpop(b)) > > I wonder if there is some clever optimization for that case. > > Another case I see in a few places is: > > %331 = tail call i64 @llvm.ctpop.i64(i64 %330) nounwind > %cast.i137 = trunc i64 %331 to i32 > %332 = icmp ugt i32 %cast.i137, 1 > > Where both the trunc and the ctpop have one use. I added a DAGCombine to turn this pattern into (x & x-1) != 0 in r123621. > There are a few other interesting patterns that seem simplifiable: > > ;