From sabre at nondot.org Mon Dec 13 00:25:44 2010 From: sabre at nondot.org (Chris Lattner) Date: Mon, 13 Dec 2010 06:25:44 -0000 Subject: [llvm-commits] [llvm] r121688 - /llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp Message-ID: <20101213062544.CD6372A6C12C@llvm.org> Author: lattner Date: Mon Dec 13 00:25:44 2010 New Revision: 121688 URL: http://llvm.org/viewvc/llvm-project?rev=121688&view=rev Log: split all the guts of SimplifyCFGOpt::run out into one function per terminator kind. Modified: llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp Modified: llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp?rev=121688&r1=121687&r2=121688&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp Mon Dec 13 00:25:44 2010 @@ -48,6 +48,14 @@ BasicBlock *Pred); bool FoldValueComparisonIntoPredecessors(TerminatorInst *TI); + bool SimplifyReturn(ReturnInst *RI); + bool SimplifyUnwind(UnwindInst *UI); + bool SimplifyUnreachable(UnreachableInst *UI); + bool SimplifySwitch(SwitchInst *SI); + bool SimplifyIndirectBr(IndirectBrInst *IBI); + bool SimplifyUncondBranch(BranchInst *BI); + bool SimplifyCondBranch(BranchInst *BI); + public: explicit SimplifyCFGOpt(const TargetData *td) : TD(td) {} bool run(BasicBlock *BB); @@ -1918,8 +1926,7 @@ } // Create the new switch instruction now. - SwitchInst *New = - SwitchInst::Create(CompVal, DefaultBB, Values.size(), BI); + SwitchInst *New = SwitchInst::Create(CompVal, DefaultBB, Values.size(), BI); // Add all of the 'cases' to the switch instruction. for (unsigned i = 0, e = Values.size(); i != e; ++i) @@ -1941,415 +1948,475 @@ return true; } -bool SimplifyCFGOpt::run(BasicBlock *BB) { - bool Changed = false; - Function *Fn = BB->getParent(); - - assert(BB && Fn && "Block not embedded in function!"); - assert(BB->getTerminator() && "Degenerate basic block encountered!"); - - // Remove basic blocks that have no predecessors (except the entry block)... - // or that just have themself as a predecessor. These are unreachable. - if ((pred_begin(BB) == pred_end(BB) && BB != &Fn->getEntryBlock()) || - BB->getSinglePredecessor() == BB) { - DEBUG(dbgs() << "Removing BB: \n" << *BB); - DeleteDeadBlock(BB); +bool SimplifyCFGOpt::SimplifyReturn(ReturnInst *RI) { + BasicBlock *BB = RI->getParent(); + if (!BB->getFirstNonPHIOrDbg()->isTerminator()) return false; + + // Find predecessors that end with branches. + SmallVector UncondBranchPreds; + SmallVector CondBranchPreds; + for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI) { + BasicBlock *P = *PI; + TerminatorInst *PTI = P->getTerminator(); + if (BranchInst *BI = dyn_cast(PTI)) { + if (BI->isUnconditional()) + UncondBranchPreds.push_back(P); + else + CondBranchPreds.push_back(BI); + } + } + + // If we found some, do the transformation! + if (!UncondBranchPreds.empty()) { + while (!UncondBranchPreds.empty()) { + BasicBlock *Pred = UncondBranchPreds.pop_back_val(); + DEBUG(dbgs() << "FOLDING: " << *BB + << "INTO UNCOND BRANCH PRED: " << *Pred); + Instruction *UncondBranch = Pred->getTerminator(); + // Clone the return and add it to the end of the predecessor. + Instruction *NewRet = RI->clone(); + Pred->getInstList().push_back(NewRet); + + // If the return instruction returns a value, and if the value was a + // PHI node in "BB", propagate the right value into the return. + for (User::op_iterator i = NewRet->op_begin(), e = NewRet->op_end(); + i != e; ++i) + if (PHINode *PN = dyn_cast(*i)) + if (PN->getParent() == BB) + *i = PN->getIncomingValueForBlock(Pred); + + // Update any PHI nodes in the returning block to realize that we no + // longer branch to them. + BB->removePredecessor(Pred); + Pred->getInstList().erase(UncondBranch); + } + + // If we eliminated all predecessors of the block, delete the block now. + if (pred_begin(BB) == pred_end(BB)) + // We know there are no successors, so just nuke the block. + BB->eraseFromParent(); + return true; } + + // Check out all of the conditional branches going to this return + // instruction. If any of them just select between returns, change the + // branch itself into a select/return pair. + while (!CondBranchPreds.empty()) { + BranchInst *BI = CondBranchPreds.pop_back_val(); + + // Check to see if the non-BB successor is also a return block. + if (isa(BI->getSuccessor(0)->getTerminator()) && + isa(BI->getSuccessor(1)->getTerminator()) && + SimplifyCondBranchToTwoReturns(BI)) + return true; + } + return false; +} - // Check to see if we can constant propagate this terminator instruction - // away... - Changed |= ConstantFoldTerminator(BB); - - // Check for and eliminate duplicate PHI nodes in this block. - Changed |= EliminateDuplicatePHINodes(BB); +bool SimplifyCFGOpt::SimplifyUnwind(UnwindInst *UI) { + // Check to see if the first instruction in this block is just an unwind. + // If so, replace any invoke instructions which use this as an exception + // destination with call instructions. + BasicBlock *BB = UI->getParent(); + if (!BB->getFirstNonPHIOrDbg()->isTerminator()) return false; - // Merge basic blocks into their predecessor if there is only one distinct - // pred, and if there is only one distinct successor of the predecessor, and - // if there are no PHI nodes. - // - if (MergeBlockIntoPredecessor(BB)) + bool Changed = false; + SmallVector Preds(pred_begin(BB), pred_end(BB)); + while (!Preds.empty()) { + BasicBlock *Pred = Preds.back(); + InvokeInst *II = dyn_cast(Pred->getTerminator()); + if (II && II->getUnwindDest() == BB) { + // Insert a new branch instruction before the invoke, because this + // is now a fall through. + BranchInst *BI = BranchInst::Create(II->getNormalDest(), II); + Pred->getInstList().remove(II); // Take out of symbol table + + // Insert the call now. + SmallVector Args(II->op_begin(), II->op_end()-3); + CallInst *CI = CallInst::Create(II->getCalledValue(), + Args.begin(), Args.end(), + II->getName(), BI); + CI->setCallingConv(II->getCallingConv()); + CI->setAttributes(II->getAttributes()); + // If the invoke produced a value, the Call now does instead. + II->replaceAllUsesWith(CI); + delete II; + Changed = true; + } + + Preds.pop_back(); + } + + // If this block is now dead (and isn't the entry block), remove it. + if (pred_begin(BB) == pred_end(BB) && + BB != &BB->getParent()->getEntryBlock()) { + // We know there are no successors, so just nuke the block. + BB->eraseFromParent(); return true; + } - // If there is a trivial two-entry PHI node in this basic block, and we can - // eliminate it, do so now. - if (PHINode *PN = dyn_cast(BB->begin())) - if (PN->getNumIncomingValues() == 2) - Changed |= FoldTwoEntryPHINode(PN); + return Changed; +} - // If this is a returning block with only PHI nodes in it, fold the return - // instruction into any unconditional branch predecessors. - // - // If any predecessor is a conditional branch that just selects among - // different return values, fold the replace the branch/return with a select - // and return. - if (ReturnInst *RI = dyn_cast(BB->getTerminator())) { - if (BB->getFirstNonPHIOrDbg()->isTerminator()) { - // Find predecessors that end with branches. - SmallVector UncondBranchPreds; - SmallVector CondBranchPreds; - for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI) { - BasicBlock *P = *PI; - TerminatorInst *PTI = P->getTerminator(); - if (BranchInst *BI = dyn_cast(PTI)) { - if (BI->isUnconditional()) - UncondBranchPreds.push_back(P); - else - CondBranchPreds.push_back(BI); +bool SimplifyCFGOpt::SimplifyUnreachable(UnreachableInst *UI) { + BasicBlock *BB = UI->getParent(); + + bool Changed = false; + + // If there are any instructions immediately before the unreachable that can + // be removed, do so. + while (UI != BB->begin()) { + BasicBlock::iterator BBI = UI; + --BBI; + // Do not delete instructions that can have side effects, like calls + // (which may never return) and volatile loads and stores. + if (isa(BBI) && !isa(BBI)) break; + + if (StoreInst *SI = dyn_cast(BBI)) + if (SI->isVolatile()) + break; + + if (LoadInst *LI = dyn_cast(BBI)) + if (LI->isVolatile()) + break; + + // Delete this instruction + BB->getInstList().erase(BBI); + Changed = true; + } + + // If the unreachable instruction is the first in the block, take a gander + // at all of the predecessors of this instruction, and simplify them. + if (&BB->front() != UI) return Changed; + + SmallVector Preds(pred_begin(BB), pred_end(BB)); + for (unsigned i = 0, e = Preds.size(); i != e; ++i) { + TerminatorInst *TI = Preds[i]->getTerminator(); + + if (BranchInst *BI = dyn_cast(TI)) { + if (BI->isUnconditional()) { + if (BI->getSuccessor(0) == BB) { + new UnreachableInst(TI->getContext(), TI); + TI->eraseFromParent(); + Changed = true; + } + } else { + if (BI->getSuccessor(0) == BB) { + BranchInst::Create(BI->getSuccessor(1), BI); + EraseTerminatorInstAndDCECond(BI); + } else if (BI->getSuccessor(1) == BB) { + BranchInst::Create(BI->getSuccessor(0), BI); + EraseTerminatorInstAndDCECond(BI); + Changed = true; } } - - // If we found some, do the transformation! - if (!UncondBranchPreds.empty()) { - while (!UncondBranchPreds.empty()) { - BasicBlock *Pred = UncondBranchPreds.pop_back_val(); - DEBUG(dbgs() << "FOLDING: " << *BB - << "INTO UNCOND BRANCH PRED: " << *Pred); - Instruction *UncondBranch = Pred->getTerminator(); - // Clone the return and add it to the end of the predecessor. - Instruction *NewRet = RI->clone(); - Pred->getInstList().push_back(NewRet); - - // If the return instruction returns a value, and if the value was a - // PHI node in "BB", propagate the right value into the return. - for (User::op_iterator i = NewRet->op_begin(), e = NewRet->op_end(); - i != e; ++i) - if (PHINode *PN = dyn_cast(*i)) - if (PN->getParent() == BB) - *i = PN->getIncomingValueForBlock(Pred); + } else if (SwitchInst *SI = dyn_cast(TI)) { + for (unsigned i = 1, e = SI->getNumCases(); i != e; ++i) + if (SI->getSuccessor(i) == BB) { + BB->removePredecessor(SI->getParent()); + SI->removeCase(i); + --i; --e; + Changed = true; + } + // If the default value is unreachable, figure out the most popular + // destination and make it the default. + if (SI->getSuccessor(0) == BB) { + std::map Popularity; + for (unsigned i = 1, e = SI->getNumCases(); i != e; ++i) + Popularity[SI->getSuccessor(i)]++; + + // Find the most popular block. + unsigned MaxPop = 0; + BasicBlock *MaxBlock = 0; + for (std::map::iterator + I = Popularity.begin(), E = Popularity.end(); I != E; ++I) { + if (I->second > MaxPop) { + MaxPop = I->second; + MaxBlock = I->first; + } + } + if (MaxBlock) { + // Make this the new default, allowing us to delete any explicit + // edges to it. + SI->setSuccessor(0, MaxBlock); + Changed = true; - // Update any PHI nodes in the returning block to realize that we no - // longer branch to them. - BB->removePredecessor(Pred); - Pred->getInstList().erase(UncondBranch); + // If MaxBlock has phinodes in it, remove MaxPop-1 entries from + // it. + if (isa(MaxBlock->begin())) + for (unsigned i = 0; i != MaxPop-1; ++i) + MaxBlock->removePredecessor(SI->getParent()); + + for (unsigned i = 1, e = SI->getNumCases(); i != e; ++i) + if (SI->getSuccessor(i) == MaxBlock) { + SI->removeCase(i); + --i; --e; + } } - - // If we eliminated all predecessors of the block, delete the block now. - if (pred_begin(BB) == pred_end(BB)) - // We know there are no successors, so just nuke the block. - Fn->getBasicBlockList().erase(BB); - - return true; } - - // Check out all of the conditional branches going to this return - // instruction. If any of them just select between returns, change the - // branch itself into a select/return pair. - while (!CondBranchPreds.empty()) { - BranchInst *BI = CondBranchPreds.pop_back_val(); - - // Check to see if the non-BB successor is also a return block. - if (isa(BI->getSuccessor(0)->getTerminator()) && - isa(BI->getSuccessor(1)->getTerminator()) && - SimplifyCondBranchToTwoReturns(BI)) - return true; - } - } - } else if (isa(BB->begin())) { - // Check to see if the first instruction in this block is just an unwind. - // If so, replace any invoke instructions which use this as an exception - // destination with call instructions. - // - SmallVector Preds(pred_begin(BB), pred_end(BB)); - while (!Preds.empty()) { - BasicBlock *Pred = Preds.back(); - InvokeInst *II = dyn_cast(Pred->getTerminator()); - if (II && II->getUnwindDest() == BB) { - // Insert a new branch instruction before the invoke, because this - // is now a fall through. + } else if (InvokeInst *II = dyn_cast(TI)) { + if (II->getUnwindDest() == BB) { + // Convert the invoke to a call instruction. This would be a good + // place to note that the call does not throw though. BranchInst *BI = BranchInst::Create(II->getNormalDest(), II); - Pred->getInstList().remove(II); // Take out of symbol table - - // Insert the call now. - SmallVector Args(II->op_begin(), II->op_end()-3); + II->removeFromParent(); // Take out of symbol table + + // Insert the call now... + SmallVector Args(II->op_begin(), II->op_end()-3); CallInst *CI = CallInst::Create(II->getCalledValue(), Args.begin(), Args.end(), II->getName(), BI); CI->setCallingConv(II->getCallingConv()); CI->setAttributes(II->getAttributes()); - // If the invoke produced a value, the Call now does instead. + // If the invoke produced a value, the call does now instead. II->replaceAllUsesWith(CI); delete II; Changed = true; } - - Preds.pop_back(); } + } + + // If this block is now dead, remove it. + if (pred_begin(BB) == pred_end(BB) && + BB != &BB->getParent()->getEntryBlock()) { + // We know there are no successors, so just nuke the block. + BB->eraseFromParent(); + return true; + } - // If this block is now dead (and isn't the entry block), remove it. - if (pred_begin(BB) == pred_end(BB) && BB != &Fn->getEntryBlock()) { - // We know there are no successors, so just nuke the block. - Fn->getBasicBlockList().erase(BB); - return true; - } + return Changed; +} - } else if (SwitchInst *SI = dyn_cast(BB->getTerminator())) { - if (isValueEqualityComparison(SI)) { - // If we only have one predecessor, and if it is a branch on this value, - // see if that predecessor totally determines the outcome of this switch. - if (BasicBlock *OnlyPred = BB->getSinglePredecessor()) - if (SimplifyEqualityComparisonWithOnlyPredecessor(SI, OnlyPred)) - return SimplifyCFG(BB) || 1; - - // If the block only contains the switch, see if we can fold the block - // away into any preds. - BasicBlock::iterator BBI = BB->begin(); - // Ignore dbg intrinsics. - while (isa(BBI)) - ++BBI; - if (SI == &*BBI) - if (FoldValueComparisonIntoPredecessors(SI)) - return SimplifyCFG(BB) || 1; - } - } else if (BranchInst *BI = dyn_cast(BB->getTerminator())) { - if (BI->isUnconditional()) { - // If the Terminator is the only non-phi instruction, simplify the block. - BasicBlock::iterator I = BB->getFirstNonPHIOrDbg(); - if (I->isTerminator() && BB != &Fn->getEntryBlock() && - TryToSimplifyUncondBranchFromEmptyBlock(BB)) - return true; - - // If the only instruction in the block is a seteq/setne comparison - // against a constant, try to simplify the block. - if (ICmpInst *ICI = dyn_cast(I)) - if (ICI->isEquality() && isa(ICI->getOperand(1))) { - for (++I; isa(I); ++I) - ; - if (I->isTerminator() && - TryToSimplifyUncondBranchWithICmpInIt(ICI)) - return true; - } - - } else { // Conditional branch - if (isValueEqualityComparison(BI)) { - // If we only have one predecessor, and if it is a branch on this value, - // see if that predecessor totally determines the outcome of this - // switch. - if (BasicBlock *OnlyPred = BB->getSinglePredecessor()) - if (SimplifyEqualityComparisonWithOnlyPredecessor(BI, OnlyPred)) - return SimplifyCFG(BB) | true; - - // This block must be empty, except for the setcond inst, if it exists. - // Ignore dbg intrinsics. - BasicBlock::iterator I = BB->begin(); - // Ignore dbg intrinsics. - while (isa(I)) - ++I; - if (&*I == BI) { - if (FoldValueComparisonIntoPredecessors(BI)) - return SimplifyCFG(BB) | true; - } else if (&*I == cast(BI->getCondition())){ - ++I; - // Ignore dbg intrinsics. - while (isa(I)) - ++I; - if (&*I == BI && FoldValueComparisonIntoPredecessors(BI)) - return SimplifyCFG(BB) | true; - } - } - // Try to turn "br (X == 0 | X == 1), T, F" into a switch instruction. - if (SimplifyBranchOnICmpChain(BI, TD)) - return true; - - - // We have a conditional branch to two blocks that are only reachable - // from BI. We know that the condbr dominates the two blocks, so see if - // there is any identical code in the "then" and "else" blocks. If so, we - // can hoist it up to the branching block. - if (BI->getSuccessor(0)->getSinglePredecessor() != 0) { - if (BI->getSuccessor(1)->getSinglePredecessor() != 0) { - if (HoistThenElseCodeToIf(BI)) - return SimplifyCFG(BB) | true; - } else { - // If Successor #1 has multiple preds, we may be able to conditionally - // execute Successor #0 if it branches to successor #1. - TerminatorInst *Succ0TI = BI->getSuccessor(0)->getTerminator(); - if (Succ0TI->getNumSuccessors() == 1 && - Succ0TI->getSuccessor(0) == BI->getSuccessor(1)) - if (SpeculativelyExecuteBB(BI, BI->getSuccessor(0))) - return SimplifyCFG(BB) | true; - } - } else if (BI->getSuccessor(1)->getSinglePredecessor() != 0) { - // If Successor #0 has multiple preds, we may be able to conditionally - // execute Successor #1 if it branches to successor #0. - TerminatorInst *Succ1TI = BI->getSuccessor(1)->getTerminator(); - if (Succ1TI->getNumSuccessors() == 1 && - Succ1TI->getSuccessor(0) == BI->getSuccessor(0)) - if (SpeculativelyExecuteBB(BI, BI->getSuccessor(1))) - return SimplifyCFG(BB) | true; - } - - // If this is a branch on a phi node in the current block, thread control - // through this block if any PHI node entries are constants. - if (PHINode *PN = dyn_cast(BI->getCondition())) - if (PN->getParent() == BI->getParent()) - if (FoldCondBranchOnPHI(BI)) - return SimplifyCFG(BB) | true; - - // If this basic block is ONLY a setcc and a branch, and if a predecessor - // branches to us and one of our successors, fold the setcc into the - // predecessor and use logical operations to pick the right destination. - if (FoldBranchToCommonDest(BI)) - return SimplifyCFG(BB) | true; +bool SimplifyCFGOpt::SimplifySwitch(SwitchInst *SI) { + // If this switch is too complex to want to look at, ignore it. + if (!isValueEqualityComparison(SI)) + return false; + + BasicBlock *BB = SI->getParent(); - // Scan predecessor blocks for conditional branches. - for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI) - if (BranchInst *PBI = dyn_cast((*PI)->getTerminator())) - if (PBI != BI && PBI->isConditional()) - if (SimplifyCondBranchToCondBranch(PBI, BI)) - return SimplifyCFG(BB) | true; - } - } else if (isa(BB->getTerminator())) { - // If there are any instructions immediately before the unreachable that can - // be removed, do so. - Instruction *Unreachable = BB->getTerminator(); - while (Unreachable != BB->begin()) { - BasicBlock::iterator BBI = Unreachable; - --BBI; - // Do not delete instructions that can have side effects, like calls - // (which may never return) and volatile loads and stores. - if (isa(BBI) && !isa(BBI)) break; - - if (StoreInst *SI = dyn_cast(BBI)) - if (SI->isVolatile()) - break; - - if (LoadInst *LI = dyn_cast(BBI)) - if (LI->isVolatile()) - break; + // If we only have one predecessor, and if it is a branch on this value, + // see if that predecessor totally determines the outcome of this switch. + if (BasicBlock *OnlyPred = BB->getSinglePredecessor()) + if (SimplifyEqualityComparisonWithOnlyPredecessor(SI, OnlyPred)) + return SimplifyCFG(BB) || 1; + + // If the block only contains the switch, see if we can fold the block + // away into any preds. + BasicBlock::iterator BBI = BB->begin(); + // Ignore dbg intrinsics. + while (isa(BBI)) + ++BBI; + if (SI == &*BBI) + if (FoldValueComparisonIntoPredecessors(SI)) + return SimplifyCFG(BB) || 1; + + return false; +} - // Delete this instruction - BB->getInstList().erase(BBI); +bool SimplifyCFGOpt::SimplifyIndirectBr(IndirectBrInst *IBI) { + BasicBlock *BB = IBI->getParent(); + bool Changed = false; + + // Eliminate redundant destinations. + SmallPtrSet Succs; + for (unsigned i = 0, e = IBI->getNumDestinations(); i != e; ++i) { + BasicBlock *Dest = IBI->getDestination(i); + if (!Dest->hasAddressTaken() || !Succs.insert(Dest)) { + Dest->removePredecessor(BB); + IBI->removeDestination(i); + --i; --e; Changed = true; } + } - // If the unreachable instruction is the first in the block, take a gander - // at all of the predecessors of this instruction, and simplify them. - if (&BB->front() == Unreachable) { - SmallVector Preds(pred_begin(BB), pred_end(BB)); - for (unsigned i = 0, e = Preds.size(); i != e; ++i) { - TerminatorInst *TI = Preds[i]->getTerminator(); - - if (BranchInst *BI = dyn_cast(TI)) { - if (BI->isUnconditional()) { - if (BI->getSuccessor(0) == BB) { - new UnreachableInst(TI->getContext(), TI); - TI->eraseFromParent(); - Changed = true; - } - } else { - if (BI->getSuccessor(0) == BB) { - BranchInst::Create(BI->getSuccessor(1), BI); - EraseTerminatorInstAndDCECond(BI); - } else if (BI->getSuccessor(1) == BB) { - BranchInst::Create(BI->getSuccessor(0), BI); - EraseTerminatorInstAndDCECond(BI); - Changed = true; - } - } - } else if (SwitchInst *SI = dyn_cast(TI)) { - for (unsigned i = 1, e = SI->getNumCases(); i != e; ++i) - if (SI->getSuccessor(i) == BB) { - BB->removePredecessor(SI->getParent()); - SI->removeCase(i); - --i; --e; - Changed = true; - } - // If the default value is unreachable, figure out the most popular - // destination and make it the default. - if (SI->getSuccessor(0) == BB) { - std::map Popularity; - for (unsigned i = 1, e = SI->getNumCases(); i != e; ++i) - Popularity[SI->getSuccessor(i)]++; - - // Find the most popular block. - unsigned MaxPop = 0; - BasicBlock *MaxBlock = 0; - for (std::map::iterator - I = Popularity.begin(), E = Popularity.end(); I != E; ++I) { - if (I->second > MaxPop) { - MaxPop = I->second; - MaxBlock = I->first; - } - } - if (MaxBlock) { - // Make this the new default, allowing us to delete any explicit - // edges to it. - SI->setSuccessor(0, MaxBlock); - Changed = true; - - // If MaxBlock has phinodes in it, remove MaxPop-1 entries from - // it. - if (isa(MaxBlock->begin())) - for (unsigned i = 0; i != MaxPop-1; ++i) - MaxBlock->removePredecessor(SI->getParent()); - - for (unsigned i = 1, e = SI->getNumCases(); i != e; ++i) - if (SI->getSuccessor(i) == MaxBlock) { - SI->removeCase(i); - --i; --e; - } - } - } - } else if (InvokeInst *II = dyn_cast(TI)) { - if (II->getUnwindDest() == BB) { - // Convert the invoke to a call instruction. This would be a good - // place to note that the call does not throw though. - BranchInst *BI = BranchInst::Create(II->getNormalDest(), II); - II->removeFromParent(); // Take out of symbol table - - // Insert the call now... - SmallVector Args(II->op_begin(), II->op_end()-3); - CallInst *CI = CallInst::Create(II->getCalledValue(), - Args.begin(), Args.end(), - II->getName(), BI); - CI->setCallingConv(II->getCallingConv()); - CI->setAttributes(II->getAttributes()); - // If the invoke produced a value, the call does now instead. - II->replaceAllUsesWith(CI); - delete II; - Changed = true; - } - } - } + if (IBI->getNumDestinations() == 0) { + // If the indirectbr has no successors, change it to unreachable. + new UnreachableInst(IBI->getContext(), IBI); + EraseTerminatorInstAndDCECond(IBI); + return true; + } + + if (IBI->getNumDestinations() == 1) { + // If the indirectbr has one successor, change it to a direct branch. + BranchInst::Create(IBI->getDestination(0), IBI); + EraseTerminatorInstAndDCECond(IBI); + return true; + } + + if (SelectInst *SI = dyn_cast(IBI->getAddress())) { + if (SimplifyIndirectBrOnSelect(IBI, SI)) + return SimplifyCFG(BB) | true; + } + return Changed; +} - // If this block is now dead, remove it. - if (pred_begin(BB) == pred_end(BB) && BB != &Fn->getEntryBlock()) { - // We know there are no successors, so just nuke the block. - Fn->getBasicBlockList().erase(BB); +bool SimplifyCFGOpt::SimplifyUncondBranch(BranchInst *BI) { + BasicBlock *BB = BI->getParent(); + + // If the Terminator is the only non-phi instruction, simplify the block. + BasicBlock::iterator I = BB->getFirstNonPHIOrDbg(); + if (I->isTerminator() && BB != &BB->getParent()->getEntryBlock() && + TryToSimplifyUncondBranchFromEmptyBlock(BB)) + return true; + + // If the only instruction in the block is a seteq/setne comparison + // against a constant, try to simplify the block. + if (ICmpInst *ICI = dyn_cast(I)) + if (ICI->isEquality() && isa(ICI->getOperand(1))) { + for (++I; isa(I); ++I) + ; + if (I->isTerminator() && TryToSimplifyUncondBranchWithICmpInIt(ICI)) return true; - } } - } else if (IndirectBrInst *IBI = - dyn_cast(BB->getTerminator())) { - // Eliminate redundant destinations. - SmallPtrSet Succs; - for (unsigned i = 0, e = IBI->getNumDestinations(); i != e; ++i) { - BasicBlock *Dest = IBI->getDestination(i); - if (!Dest->hasAddressTaken() || !Succs.insert(Dest)) { - Dest->removePredecessor(BB); - IBI->removeDestination(i); - --i; --e; - Changed = true; - } - } + + return false; +} - if (IBI->getNumDestinations() == 0) { - // If the indirectbr has no successors, change it to unreachable. - new UnreachableInst(IBI->getContext(), IBI); - EraseTerminatorInstAndDCECond(IBI); - Changed = true; - } else if (IBI->getNumDestinations() == 1) { - // If the indirectbr has one successor, change it to a direct branch. - BranchInst::Create(IBI->getDestination(0), IBI); - EraseTerminatorInstAndDCECond(IBI); - Changed = true; - } else if (SelectInst *SI = dyn_cast(IBI->getAddress())) { - if (SimplifyIndirectBrOnSelect(IBI, SI)) + +bool SimplifyCFGOpt::SimplifyCondBranch(BranchInst *BI) { + BasicBlock *BB = BI->getParent(); + + // Conditional branch + if (isValueEqualityComparison(BI)) { + // If we only have one predecessor, and if it is a branch on this value, + // see if that predecessor totally determines the outcome of this + // switch. + if (BasicBlock *OnlyPred = BB->getSinglePredecessor()) + if (SimplifyEqualityComparisonWithOnlyPredecessor(BI, OnlyPred)) + return SimplifyCFG(BB) | true; + + // This block must be empty, except for the setcond inst, if it exists. + // Ignore dbg intrinsics. + BasicBlock::iterator I = BB->begin(); + // Ignore dbg intrinsics. + while (isa(I)) + ++I; + if (&*I == BI) { + if (FoldValueComparisonIntoPredecessors(BI)) + return SimplifyCFG(BB) | true; + } else if (&*I == cast(BI->getCondition())){ + ++I; + // Ignore dbg intrinsics. + while (isa(I)) + ++I; + if (&*I == BI && FoldValueComparisonIntoPredecessors(BI)) return SimplifyCFG(BB) | true; } } + + // Try to turn "br (X == 0 | X == 1), T, F" into a switch instruction. + if (SimplifyBranchOnICmpChain(BI, TD)) + return true; + + // We have a conditional branch to two blocks that are only reachable + // from BI. We know that the condbr dominates the two blocks, so see if + // there is any identical code in the "then" and "else" blocks. If so, we + // can hoist it up to the branching block. + if (BI->getSuccessor(0)->getSinglePredecessor() != 0) { + if (BI->getSuccessor(1)->getSinglePredecessor() != 0) { + if (HoistThenElseCodeToIf(BI)) + return SimplifyCFG(BB) | true; + } else { + // If Successor #1 has multiple preds, we may be able to conditionally + // execute Successor #0 if it branches to successor #1. + TerminatorInst *Succ0TI = BI->getSuccessor(0)->getTerminator(); + if (Succ0TI->getNumSuccessors() == 1 && + Succ0TI->getSuccessor(0) == BI->getSuccessor(1)) + if (SpeculativelyExecuteBB(BI, BI->getSuccessor(0))) + return SimplifyCFG(BB) | true; + } + } else if (BI->getSuccessor(1)->getSinglePredecessor() != 0) { + // If Successor #0 has multiple preds, we may be able to conditionally + // execute Successor #1 if it branches to successor #0. + TerminatorInst *Succ1TI = BI->getSuccessor(1)->getTerminator(); + if (Succ1TI->getNumSuccessors() == 1 && + Succ1TI->getSuccessor(0) == BI->getSuccessor(0)) + if (SpeculativelyExecuteBB(BI, BI->getSuccessor(1))) + return SimplifyCFG(BB) | true; + } + + // If this is a branch on a phi node in the current block, thread control + // through this block if any PHI node entries are constants. + if (PHINode *PN = dyn_cast(BI->getCondition())) + if (PN->getParent() == BI->getParent()) + if (FoldCondBranchOnPHI(BI)) + return SimplifyCFG(BB) | true; + + // If this basic block is ONLY a setcc and a branch, and if a predecessor + // branches to us and one of our successors, fold the setcc into the + // predecessor and use logical operations to pick the right destination. + if (FoldBranchToCommonDest(BI)) + return SimplifyCFG(BB) | true; + + // Scan predecessor blocks for conditional branches. + for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI) + if (BranchInst *PBI = dyn_cast((*PI)->getTerminator())) + if (PBI != BI && PBI->isConditional()) + if (SimplifyCondBranchToCondBranch(PBI, BI)) + return SimplifyCFG(BB) | true; + + return false; +} + +bool SimplifyCFGOpt::run(BasicBlock *BB) { + bool Changed = false; + Function *Fn = BB->getParent(); + + assert(BB && Fn && "Block not embedded in function!"); + assert(BB->getTerminator() && "Degenerate basic block encountered!"); + + // Remove basic blocks that have no predecessors (except the entry block)... + // or that just have themself as a predecessor. These are unreachable. + if ((pred_begin(BB) == pred_end(BB) && BB != &Fn->getEntryBlock()) || + BB->getSinglePredecessor() == BB) { + DEBUG(dbgs() << "Removing BB: \n" << *BB); + DeleteDeadBlock(BB); + return true; + } + + // Check to see if we can constant propagate this terminator instruction + // away... + Changed |= ConstantFoldTerminator(BB); + + // Check for and eliminate duplicate PHI nodes in this block. + Changed |= EliminateDuplicatePHINodes(BB); + + // Merge basic blocks into their predecessor if there is only one distinct + // pred, and if there is only one distinct successor of the predecessor, and + // if there are no PHI nodes. + // + if (MergeBlockIntoPredecessor(BB)) + return true; + + // If there is a trivial two-entry PHI node in this basic block, and we can + // eliminate it, do so now. + if (PHINode *PN = dyn_cast(BB->begin())) + if (PN->getNumIncomingValues() == 2) + Changed |= FoldTwoEntryPHINode(PN); + + if (BranchInst *BI = dyn_cast(BB->getTerminator())) { + if (BI->isUnconditional()) + return SimplifyUncondBranch(BI) | Changed; + + return SimplifyCondBranch(BI) | Changed; + } + + if (ReturnInst *RI = dyn_cast(BB->getTerminator())) + return SimplifyReturn(RI) | Changed; + + if (SwitchInst *SI = dyn_cast(BB->getTerminator())) + return SimplifySwitch(SI) | Changed; + + if (UnreachableInst *UI = dyn_cast(BB->getTerminator())) + return SimplifyUnreachable(UI) | Changed; + + if (UnwindInst *UI = dyn_cast(BB->getTerminator())) + return SimplifyUnwind(UI) | Changed; + + if (IndirectBrInst *IBI = dyn_cast(BB->getTerminator())) + return SimplifyIndirectBr(IBI) | Changed; return Changed; } From sabre at nondot.org Mon Dec 13 00:36:51 2010 From: sabre at nondot.org (Chris Lattner) Date: Mon, 13 Dec 2010 06:36:51 -0000 Subject: [llvm-commits] [llvm] r121689 - /llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp Message-ID: <20101213063651.3752F2A6C12C@llvm.org> Author: lattner Date: Mon Dec 13 00:36:51 2010 New Revision: 121689 URL: http://llvm.org/viewvc/llvm-project?rev=121689&view=rev Log: make this logic a bit simpler. Modified: llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp Modified: llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp?rev=121689&r1=121688&r2=121689&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp Mon Dec 13 00:36:51 2010 @@ -2200,7 +2200,7 @@ // see if that predecessor totally determines the outcome of this switch. if (BasicBlock *OnlyPred = BB->getSinglePredecessor()) if (SimplifyEqualityComparisonWithOnlyPredecessor(SI, OnlyPred)) - return SimplifyCFG(BB) || 1; + return SimplifyCFG(BB) | true; // If the block only contains the switch, see if we can fold the block // away into any preds. @@ -2210,7 +2210,7 @@ ++BBI; if (SI == &*BBI) if (FoldValueComparisonIntoPredecessors(SI)) - return SimplifyCFG(BB) || 1; + return SimplifyCFG(BB) | true; return false; } @@ -2397,27 +2397,26 @@ Changed |= FoldTwoEntryPHINode(PN); if (BranchInst *BI = dyn_cast(BB->getTerminator())) { - if (BI->isUnconditional()) - return SimplifyUncondBranch(BI) | Changed; - - return SimplifyCondBranch(BI) | Changed; + if (BI->isUnconditional()) { + if (SimplifyUncondBranch(BI)) return true; + } else { + if (SimplifyCondBranch(BI)) + return true; + } + } else if (ReturnInst *RI = dyn_cast(BB->getTerminator())) { + if (SimplifyReturn(RI)) return true; + } else if (SwitchInst *SI = dyn_cast(BB->getTerminator())) { + if (SimplifySwitch(SI)) return true; + } else if (UnreachableInst *UI = + dyn_cast(BB->getTerminator())) { + if (SimplifyUnreachable(UI)) return true; + } else if (UnwindInst *UI = dyn_cast(BB->getTerminator())) { + if (SimplifyUnwind(UI)) return true; + } else if (IndirectBrInst *IBI = + dyn_cast(BB->getTerminator())) { + if (SimplifyIndirectBr(IBI)) return true; } - if (ReturnInst *RI = dyn_cast(BB->getTerminator())) - return SimplifyReturn(RI) | Changed; - - if (SwitchInst *SI = dyn_cast(BB->getTerminator())) - return SimplifySwitch(SI) | Changed; - - if (UnreachableInst *UI = dyn_cast(BB->getTerminator())) - return SimplifyUnreachable(UI) | Changed; - - if (UnwindInst *UI = dyn_cast(BB->getTerminator())) - return SimplifyUnwind(UI) | Changed; - - if (IndirectBrInst *IBI = dyn_cast(BB->getTerminator())) - return SimplifyIndirectBr(IBI) | Changed; - return Changed; } From sabre at nondot.org Mon Dec 13 01:00:06 2010 From: sabre at nondot.org (Chris Lattner) Date: Mon, 13 Dec 2010 07:00:06 -0000 Subject: [llvm-commits] [llvm] r121690 - in /llvm/trunk: lib/Transforms/Utils/SimplifyCFG.cpp test/Transforms/SimplifyCFG/switch_create.ll Message-ID: <20101213070006.9EA102A6C12C@llvm.org> Author: lattner Date: Mon Dec 13 01:00:06 2010 New Revision: 121690 URL: http://llvm.org/viewvc/llvm-project?rev=121690&view=rev Log: Make simplifycfg reprocess newly formed "br (cond1 | cond2)" conditions when simplifying, allowing them to be eagerly turned into switches. This is the last step required to get "Example 7" from this blog post: http://blog.regehr.org/archives/320 On X86, we now generate this machine code, which (to my eye) seems better than the ICC generated code: _crud: ## @crud ## BB#0: ## %entry cmpb $33, %dil jb LBB0_4 ## BB#1: ## %switch.early.test addb $-34, %dil cmpb $58, %dil ja LBB0_3 ## BB#2: ## %switch.early.test movzbl %dil, %eax movabsq $288230376537592865, %rcx ## imm = 0x400000017001421 btq %rax, %rcx jb LBB0_4 LBB0_3: ## %lor.rhs xorl %eax, %eax ret LBB0_4: ## %lor.end movl $1, %eax ret Modified: llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp llvm/trunk/test/Transforms/SimplifyCFG/switch_create.ll Modified: llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp?rev=121690&r1=121689&r2=121690&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp Mon Dec 13 01:00:06 2010 @@ -1357,7 +1357,7 @@ // must be at the front of the block. BasicBlock::iterator FrontIt = BB->front(); // Ignore dbg intrinsics. - while(isa(FrontIt)) + while (isa(FrontIt)) ++FrontIt; // Allow a single instruction to be hoisted in addition to the compare @@ -1441,7 +1441,7 @@ UsedValues.erase(Pair.first); if (UsedValues.empty()) break; - if (Instruction* I = dyn_cast(Pair.first)) { + if (Instruction *I = dyn_cast(Pair.first)) { for (Instruction::op_iterator OI = I->op_begin(), OE = I->op_end(); OI != OE; ++OI) Worklist.push_back(std::make_pair(OI->get(), Pair.second+1)); @@ -1469,9 +1469,16 @@ // If we need to invert the condition in the pred block to match, do so now. if (InvertPredCond) { - Value *NewCond = - BinaryOperator::CreateNot(PBI->getCondition(), + Value *NewCond = PBI->getCondition(); + + if (NewCond->hasOneUse() && isa(NewCond)) { + CmpInst *CI = cast(NewCond); + CI->setPredicate(CI->getInversePredicate()); + } else { + NewCond = BinaryOperator::CreateNot(NewCond, PBI->getCondition()->getName()+".not", PBI); + } + PBI->setCondition(NewCond); BasicBlock *OldTrue = PBI->getSuccessor(0); BasicBlock *OldFalse = PBI->getSuccessor(1); @@ -1507,7 +1514,7 @@ AddPredecessorToBlock(FalseDest, PredBlock, BB); PBI->setSuccessor(1, FalseDest); } - return true; + return SimplifyCFG(PBI->getParent()) | true; } return false; } Modified: llvm/trunk/test/Transforms/SimplifyCFG/switch_create.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimplifyCFG/switch_create.ll?rev=121690&r1=121689&r2=121690&view=diff ============================================================================== --- llvm/trunk/test/Transforms/SimplifyCFG/switch_create.ll (original) +++ llvm/trunk/test/Transforms/SimplifyCFG/switch_create.ll Mon Dec 13 01:00:06 2010 @@ -203,5 +203,70 @@ ; CHECK: i8 97, label %if.then ; CHECK: ] ; CHECK: %A = phi i32 [ 0, %entry ], [ 42, %switch.early.test ], [ 42, %N ], [ 42, %switch.early.test ] +} + +define i32 @test9(i8 zeroext %c) nounwind ssp noredzone { +entry: + %cmp = icmp ult i8 %c, 33 + br i1 %cmp, label %lor.end, label %lor.lhs.false + +lor.lhs.false: ; preds = %entry + %cmp4 = icmp eq i8 %c, 46 + br i1 %cmp4, label %lor.end, label %lor.lhs.false6 + +lor.lhs.false6: ; preds = %lor.lhs.false + %cmp9 = icmp eq i8 %c, 44 + br i1 %cmp9, label %lor.end, label %lor.lhs.false11 + +lor.lhs.false11: ; preds = %lor.lhs.false6 + %cmp14 = icmp eq i8 %c, 58 + br i1 %cmp14, label %lor.end, label %lor.lhs.false16 + +lor.lhs.false16: ; preds = %lor.lhs.false11 + %cmp19 = icmp eq i8 %c, 59 + br i1 %cmp19, label %lor.end, label %lor.lhs.false21 + +lor.lhs.false21: ; preds = %lor.lhs.false16 + %cmp24 = icmp eq i8 %c, 60 + br i1 %cmp24, label %lor.end, label %lor.lhs.false26 + +lor.lhs.false26: ; preds = %lor.lhs.false21 + %cmp29 = icmp eq i8 %c, 62 + br i1 %cmp29, label %lor.end, label %lor.lhs.false31 +lor.lhs.false31: ; preds = %lor.lhs.false26 + %cmp34 = icmp eq i8 %c, 34 + br i1 %cmp34, label %lor.end, label %lor.lhs.false36 + +lor.lhs.false36: ; preds = %lor.lhs.false31 + %cmp39 = icmp eq i8 %c, 92 + br i1 %cmp39, label %lor.end, label %lor.rhs + +lor.rhs: ; preds = %lor.lhs.false36 + %cmp43 = icmp eq i8 %c, 39 + br label %lor.end + +lor.end: ; preds = %lor.rhs, %lor.lhs.false36, %lor.lhs.false31, %lor.lhs.false26, %lor.lhs.false21, %lor.lhs.false16, %lor.lhs.false11, %lor.lhs.false6, %lor.lhs.false, %entry + %0 = phi i1 [ true, %lor.lhs.false36 ], [ true, %lor.lhs.false31 ], [ true, %lor.lhs.false26 ], [ true, %lor.lhs.false21 ], [ true, %lor.lhs.false16 ], [ true, %lor.lhs.false11 ], [ true, %lor.lhs.false6 ], [ true, %lor.lhs.false ], [ true, %entry ], [ %cmp43, %lor.rhs ] + %conv46 = zext i1 %0 to i32 + ret i32 %conv46 + +; CHECK: @test9 +; CHECK: %cmp = icmp ult i8 %c, 33 +; CHECK: br i1 %cmp, label %lor.end, label %switch.early.test + +; CHECK: switch.early.test: +; CHECK: switch i8 %c, label %lor.rhs [ +; CHECK: i8 46, label %lor.end +; CHECK: i8 44, label %lor.end +; CHECK: i8 58, label %lor.end +; CHECK: i8 59, label %lor.end +; CHECK: i8 60, label %lor.end +; CHECK: i8 62, label %lor.end +; CHECK: i8 34, label %lor.end +; CHECK: i8 92, label %lor.end +; CHECK: i8 39, label %lor.end +; CHECK: ] } + + From sabre at nondot.org Mon Dec 13 01:35:47 2010 From: sabre at nondot.org (Chris Lattner) Date: Mon, 13 Dec 2010 07:35:47 -0000 Subject: [llvm-commits] [llvm] r121691 - /llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp Message-ID: <20101213073547.2CEE22A6C12C@llvm.org> Author: lattner Date: Mon Dec 13 01:35:47 2010 New Revision: 121691 URL: http://llvm.org/viewvc/llvm-project?rev=121691&view=rev Log: remove the verbose-asm "constant pool double" comments that we were printing for each constant pool entry. Using WriteTypeSymbolic here takes time proportional to the size of the module, for each constant pool entry. This speeds up -verbose-asm llc on 252.eon (a random testcase at my disposal) from 4.4s to 2.137s. llc takes 2.11s with asm-verbose off, so this is now a pretty reasonable cost for verbose comments. Modified: llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp Modified: llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp?rev=121691&r1=121690&r2=121691&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp Mon Dec 13 01:35:47 2010 @@ -920,14 +920,6 @@ const Type *Ty = CPE.getType(); Offset = NewOffset + TM.getTargetData()->getTypeAllocSize(Ty); - - // Emit the label with a comment on it. - if (isVerbose()) { - OutStreamer.GetCommentOS() << "constant pool "; - WriteTypeSymbolic(OutStreamer.GetCommentOS(), CPE.getType(), - MF->getFunction()->getParent()); - OutStreamer.GetCommentOS() << '\n'; - } OutStreamer.EmitLabel(GetCPISymbol(CPI)); if (CPE.isMachineConstantPoolEntry()) From sabre at nondot.org Mon Dec 13 01:41:29 2010 From: sabre at nondot.org (Chris Lattner) Date: Mon, 13 Dec 2010 07:41:29 -0000 Subject: [llvm-commits] [llvm] r121693 - in /llvm/trunk: lib/Transforms/Utils/SimplifyCFG.cpp test/Transforms/SimplifyCFG/switch_create.ll Message-ID: <20101213074129.A15B02A6C12C@llvm.org> Author: lattner Date: Mon Dec 13 01:41:29 2010 New Revision: 121693 URL: http://llvm.org/viewvc/llvm-project?rev=121693&view=rev Log: Completely disable the optimization I added in r121680 until I can track down a miscompile. This should bring the buildbots back to life Modified: llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp llvm/trunk/test/Transforms/SimplifyCFG/switch_create.ll Modified: llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp?rev=121693&r1=121692&r2=121693&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp Mon Dec 13 01:41:29 2010 @@ -331,8 +331,8 @@ isEQ)) { if (LHS == RHS) return LHS; + Vals.resize(NumVals); } - Vals.resize(NumVals); // The RHS of the or/and can't be folded in and we haven't used "Extra" yet, // set it and return success. @@ -348,12 +348,13 @@ // If the LHS can't be folded in, but Extra is available and RHS can, try to // use LHS as Extra. if (Extra == 0 || Extra == I->getOperand(0)) { + Value *OldExtra = Extra; Extra = I->getOperand(0); if (Value *RHS = GatherConstantCompares(I->getOperand(1), Vals, Extra, TD, isEQ)) return RHS; - Vals.resize(NumValsBeforeLHS); - Extra = 0; + assert(Vals.size() == NumValsBeforeLHS); + Extra = OldExtra; } return 0; @@ -1908,6 +1909,8 @@ // then we evaluate them with an explicit branch first. Split the block // right before the condbr to handle it. if (ExtraCase) { + return false; + BasicBlock *NewBB = BB->splitBasicBlock(BI, "switch.early.test"); // Remove the uncond branch added to the old block. TerminatorInst *OldTI = BB->getTerminator(); Modified: llvm/trunk/test/Transforms/SimplifyCFG/switch_create.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimplifyCFG/switch_create.ll?rev=121693&r1=121692&r2=121693&view=diff ============================================================================== --- llvm/trunk/test/Transforms/SimplifyCFG/switch_create.ll (original) +++ llvm/trunk/test/Transforms/SimplifyCFG/switch_create.ll Mon Dec 13 01:41:29 2010 @@ -168,13 +168,13 @@ ret void ; CHECK: @test7 -; CHECK: %cmp = icmp ult i32 %x, 32 -; CHECK: br i1 %cmp, label %if.then, label %switch.early.test -; CHECK: switch.early.test: -; CHECK: switch i8 %c, label %if.end [ -; CHECK: i8 99, label %if.then -; CHECK: i8 97, label %if.then -; CHECK: ] +; HECK: %cmp = icmp ult i32 %x, 32 +; HECK: br i1 %cmp, label %if.then, label %switch.early.test +; HECK: switch.early.test: +; HECK: switch i8 %c, label %if.end [ +; HECK: i8 99, label %if.then +; HECK: i8 97, label %if.then +; HECK: ] } define i32 @test8(i8 zeroext %c, i32 %x, i1 %C) nounwind ssp noredzone { @@ -197,14 +197,15 @@ ret i32 0 ; CHECK: @test8 -; CHECK: switch.early.test: -; CHECK: switch i8 %c, label %if.end [ -; CHECK: i8 99, label %if.then -; CHECK: i8 97, label %if.then -; CHECK: ] -; CHECK: %A = phi i32 [ 0, %entry ], [ 42, %switch.early.test ], [ 42, %N ], [ 42, %switch.early.test ] +; HECK: switch.early.test: +; HECK: switch i8 %c, label %if.end [ +; HECK: i8 99, label %if.then +; HECK: i8 97, label %if.then +; HECK: ] +; HECK: %A = phi i32 [ 0, %entry ], [ 42, %switch.early.test ], [ 42, %N ], [ 42, %switch.early.test ] } +;; This is "Example 7" from http://blog.regehr.org/archives/320 define i32 @test9(i8 zeroext %c) nounwind ssp noredzone { entry: %cmp = icmp ult i8 %c, 33 @@ -253,20 +254,20 @@ ; CHECK: @test9 ; CHECK: %cmp = icmp ult i8 %c, 33 -; CHECK: br i1 %cmp, label %lor.end, label %switch.early.test +; HECK: br i1 %cmp, label %lor.end, label %switch.early.test -; CHECK: switch.early.test: -; CHECK: switch i8 %c, label %lor.rhs [ -; CHECK: i8 46, label %lor.end -; CHECK: i8 44, label %lor.end -; CHECK: i8 58, label %lor.end -; CHECK: i8 59, label %lor.end -; CHECK: i8 60, label %lor.end -; CHECK: i8 62, label %lor.end -; CHECK: i8 34, label %lor.end -; CHECK: i8 92, label %lor.end -; CHECK: i8 39, label %lor.end -; CHECK: ] +; HECK: switch.early.test: +; HECK: switch i8 %c, label %lor.rhs [ +; HECK: i8 46, label %lor.end +; HECK: i8 44, label %lor.end +; HECK: i8 58, label %lor.end +; HECK: i8 59, label %lor.end +; HECK: i8 60, label %lor.end +; HECK: i8 62, label %lor.end +; HECK: i8 34, label %lor.end +; HECK: i8 92, label %lor.end +; HECK: i8 39, label %lor.end +; HECK: ] } From sabre at nondot.org Mon Dec 13 02:12:20 2010 From: sabre at nondot.org (Chris Lattner) Date: Mon, 13 Dec 2010 08:12:20 -0000 Subject: [llvm-commits] [llvm] r121695 - in /llvm/trunk: lib/Transforms/Utils/SimplifyCFG.cpp test/Transforms/SimplifyCFG/switch_create.ll Message-ID: <20101213081220.3239D2A6C12C@llvm.org> Author: lattner Date: Mon Dec 13 02:12:19 2010 New Revision: 121695 URL: http://llvm.org/viewvc/llvm-project?rev=121695&view=rev Log: reinstate my patch: the miscompile was caused by an inverted branch in the 'and' case. Modified: llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp llvm/trunk/test/Transforms/SimplifyCFG/switch_create.ll Modified: llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp?rev=121695&r1=121694&r2=121695&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp Mon Dec 13 02:12:19 2010 @@ -1909,13 +1909,15 @@ // then we evaluate them with an explicit branch first. Split the block // right before the condbr to handle it. if (ExtraCase) { - return false; - BasicBlock *NewBB = BB->splitBasicBlock(BI, "switch.early.test"); // Remove the uncond branch added to the old block. TerminatorInst *OldTI = BB->getTerminator(); - BranchInst::Create(EdgeBB, NewBB, ExtraCase, OldTI); + if (TrueWhenEqual) + BranchInst::Create(EdgeBB, NewBB, ExtraCase, OldTI); + else + BranchInst::Create(NewBB, EdgeBB, ExtraCase, OldTI); + OldTI->eraseFromParent(); // If there are PHI nodes in EdgeBB, then we need to add a new entry to them @@ -1955,6 +1957,7 @@ // Erase the old branch instruction. EraseTerminatorInstAndDCECond(BI); + return true; } Modified: llvm/trunk/test/Transforms/SimplifyCFG/switch_create.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimplifyCFG/switch_create.ll?rev=121695&r1=121694&r2=121695&view=diff ============================================================================== --- llvm/trunk/test/Transforms/SimplifyCFG/switch_create.ll (original) +++ llvm/trunk/test/Transforms/SimplifyCFG/switch_create.ll Mon Dec 13 02:12:19 2010 @@ -168,13 +168,13 @@ ret void ; CHECK: @test7 -; HECK: %cmp = icmp ult i32 %x, 32 -; HECK: br i1 %cmp, label %if.then, label %switch.early.test -; HECK: switch.early.test: -; HECK: switch i8 %c, label %if.end [ -; HECK: i8 99, label %if.then -; HECK: i8 97, label %if.then -; HECK: ] +; CHECK: %cmp = icmp ult i32 %x, 32 +; CHECK: br i1 %cmp, label %if.then, label %switch.early.test +; CHECK: switch.early.test: +; CHECK: switch i8 %c, label %if.end [ +; CHECK: i8 99, label %if.then +; CHECK: i8 97, label %if.then +; CHECK: ] } define i32 @test8(i8 zeroext %c, i32 %x, i1 %C) nounwind ssp noredzone { @@ -197,12 +197,12 @@ ret i32 0 ; CHECK: @test8 -; HECK: switch.early.test: -; HECK: switch i8 %c, label %if.end [ -; HECK: i8 99, label %if.then -; HECK: i8 97, label %if.then -; HECK: ] -; HECK: %A = phi i32 [ 0, %entry ], [ 42, %switch.early.test ], [ 42, %N ], [ 42, %switch.early.test ] +; CHECK: switch.early.test: +; CHECK: switch i8 %c, label %if.end [ +; CHECK: i8 99, label %if.then +; CHECK: i8 97, label %if.then +; CHECK: ] +; CHECK: %A = phi i32 [ 0, %entry ], [ 42, %switch.early.test ], [ 42, %N ], [ 42, %switch.early.test ] } ;; This is "Example 7" from http://blog.regehr.org/archives/320 @@ -254,20 +254,41 @@ ; CHECK: @test9 ; CHECK: %cmp = icmp ult i8 %c, 33 -; HECK: br i1 %cmp, label %lor.end, label %switch.early.test +; CHECK: br i1 %cmp, label %lor.end, label %switch.early.test -; HECK: switch.early.test: -; HECK: switch i8 %c, label %lor.rhs [ -; HECK: i8 46, label %lor.end -; HECK: i8 44, label %lor.end -; HECK: i8 58, label %lor.end -; HECK: i8 59, label %lor.end -; HECK: i8 60, label %lor.end -; HECK: i8 62, label %lor.end -; HECK: i8 34, label %lor.end -; HECK: i8 92, label %lor.end -; HECK: i8 39, label %lor.end -; HECK: ] +; CHECK: switch.early.test: +; CHECK: switch i8 %c, label %lor.rhs [ +; CHECK: i8 46, label %lor.end +; CHECK: i8 44, label %lor.end +; CHECK: i8 58, label %lor.end +; CHECK: i8 59, label %lor.end +; CHECK: i8 60, label %lor.end +; CHECK: i8 62, label %lor.end +; CHECK: i8 34, label %lor.end +; CHECK: i8 92, label %lor.end +; CHECK: i8 39, label %lor.end +; CHECK: ] } +define i32 @test10(i32 %mode, i1 %Cond) { + %A = icmp ne i32 %mode, 0 + %B = icmp ne i32 %mode, 51 + %C = and i1 %A, %B + %D = and i1 %C, %Cond + br i1 %D, label %T, label %F +T: + ret i32 123 +F: + ret i32 324 + +; CHECK: @test10 +; CHECK: br i1 %Cond, label %switch.early.test, label %F +; CHECK:switch.early.test: +; CHECK: switch i32 %mode, label %T [ +; CHECK: i32 51, label %F +; CHECK: i32 0, label %F +; CHECK: ] +} + + From sabre at nondot.org Mon Dec 13 02:39:01 2010 From: sabre at nondot.org (Chris Lattner) Date: Mon, 13 Dec 2010 08:39:01 -0000 Subject: [llvm-commits] [llvm] r121696 - in /llvm/trunk: lib/CodeGen/SelectionDAG/DAGCombiner.cpp test/CodeGen/X86/2008-11-29-DivideConstant16bit.ll test/CodeGen/X86/2008-11-29-DivideConstant16bitSigned.ll Message-ID: <20101213083902.0392A2A6C12D@llvm.org> Author: lattner Date: Mon Dec 13 02:39:01 2010 New Revision: 121696 URL: http://llvm.org/viewvc/llvm-project?rev=121696&view=rev Log: Add a couple dag combines to transform mulhi/mullo into a wider multiply when the wider type is legal. This allows us to compile: define zeroext i16 @test1(i16 zeroext %x) nounwind { entry: %div = udiv i16 %x, 33 ret i16 %div } into: test1: # @test1 movzwl 4(%esp), %eax imull $63551, %eax, %eax # imm = 0xF83F shrl $21, %eax ret instead of: test1: # @test1 movw $-1985, %ax # imm = 0xFFFFFFFFFFFFF83F mulw 4(%esp) andl $65504, %edx # imm = 0xFFE0 movl %edx, %eax shrl $5, %eax ret Implementing rdar://8760399 and example #4 from: http://blog.regehr.org/archives/320 We should implement the same thing for [su]mul_hilo, but I don't have immediate plans to do this. Removed: llvm/trunk/test/CodeGen/X86/2008-11-29-DivideConstant16bitSigned.ll Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp llvm/trunk/test/CodeGen/X86/2008-11-29-DivideConstant16bit.ll Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=121696&r1=121695&r2=121696&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Mon Dec 13 02:39:01 2010 @@ -1916,6 +1916,7 @@ SDValue N1 = N->getOperand(1); ConstantSDNode *N1C = dyn_cast(N1); EVT VT = N->getValueType(0); + DebugLoc DL = N->getDebugLoc(); // fold (mulhs x, 0) -> 0 if (N1C && N1C->isNullValue()) @@ -1929,6 +1930,22 @@ if (N0.getOpcode() == ISD::UNDEF || N1.getOpcode() == ISD::UNDEF) return DAG.getConstant(0, VT); + // If the type twice as wide is legal, transform the mulhs to a wider multiply + // plus a shift. + if (VT.isSimple() && !VT.isVector()) { + MVT Simple = VT.getSimpleVT(); + unsigned SimpleSize = Simple.getSizeInBits(); + EVT NewVT = EVT::getIntegerVT(*DAG.getContext(), SimpleSize*2); + if (TLI.isOperationLegal(ISD::MUL, NewVT)) { + N0 = DAG.getNode(ISD::SIGN_EXTEND, DL, NewVT, N0); + N1 = DAG.getNode(ISD::SIGN_EXTEND, DL, NewVT, N1); + N1 = DAG.getNode(ISD::MUL, DL, NewVT, N0, N1); + N1 = DAG.getNode(ISD::SRA, DL, NewVT, N1, + DAG.getConstant(SimpleSize, getShiftAmountTy())); + return DAG.getNode(ISD::TRUNCATE, DL, VT, N1); + } + } + return SDValue(); } @@ -1937,6 +1954,7 @@ SDValue N1 = N->getOperand(1); ConstantSDNode *N1C = dyn_cast(N1); EVT VT = N->getValueType(0); + DebugLoc DL = N->getDebugLoc(); // fold (mulhu x, 0) -> 0 if (N1C && N1C->isNullValue()) @@ -1948,6 +1966,22 @@ if (N0.getOpcode() == ISD::UNDEF || N1.getOpcode() == ISD::UNDEF) return DAG.getConstant(0, VT); + // If the type twice as wide is legal, transform the mulhu to a wider multiply + // plus a shift. + if (VT.isSimple() && !VT.isVector()) { + MVT Simple = VT.getSimpleVT(); + unsigned SimpleSize = Simple.getSizeInBits(); + EVT NewVT = EVT::getIntegerVT(*DAG.getContext(), SimpleSize*2); + if (TLI.isOperationLegal(ISD::MUL, NewVT)) { + N0 = DAG.getNode(ISD::ZERO_EXTEND, DL, NewVT, N0); + N1 = DAG.getNode(ISD::ZERO_EXTEND, DL, NewVT, N1); + N1 = DAG.getNode(ISD::MUL, DL, NewVT, N0, N1); + N1 = DAG.getNode(ISD::SRL, DL, NewVT, N1, + DAG.getConstant(SimpleSize, getShiftAmountTy())); + return DAG.getNode(ISD::TRUNCATE, DL, VT, N1); + } + } + return SDValue(); } @@ -2011,6 +2045,7 @@ SDValue Res = SimplifyNodeWithTwoResults(N, ISD::MUL, ISD::MULHS); if (Res.getNode()) return Res; + // TODO: Transform smul_lohi to mul if the wider mul is legal! return SDValue(); } @@ -2018,6 +2053,7 @@ SDValue Res = SimplifyNodeWithTwoResults(N, ISD::MUL, ISD::MULHU); if (Res.getNode()) return Res; + // TODO: Transform umul_lohi to mul if the wider mul is legal! return SDValue(); } Modified: llvm/trunk/test/CodeGen/X86/2008-11-29-DivideConstant16bit.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2008-11-29-DivideConstant16bit.ll?rev=121696&r1=121695&r2=121696&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/2008-11-29-DivideConstant16bit.ll (original) +++ llvm/trunk/test/CodeGen/X86/2008-11-29-DivideConstant16bit.ll Mon Dec 13 02:39:01 2010 @@ -1,9 +1,42 @@ -; RUN: llc < %s -mtriple=i686-pc-linux-gnu | grep -- -1985 | count 1 +; RUN: llc < %s -mtriple=i686-pc-linux-gnu -asm-verbose=0 | FileCheck %s target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32" target triple = "i686-pc-linux-gnu" -define zeroext i16 @a(i16 zeroext %x) nounwind { +define zeroext i16 @test1(i16 zeroext %x) nounwind { entry: - %div = udiv i16 %x, 33 ; [#uses=1] + %div = udiv i16 %x, 33 + ret i16 %div +; CHECK: test1: +; CHECK: imull $63551, %eax, %eax +; CHECK-NEXT: shrl $21, %eax +; CHECK-NEXT: ret +} + +define zeroext i16 @test2(i8 signext %x, i16 zeroext %c) nounwind readnone ssp noredzone { +entry: + %div = udiv i16 %c, 3 + ret i16 %div + +; CHECK: test2: +; CHECK: imull $43691, %eax, %eax +; CHECK-NEXT: shrl $17, %eax +; CHECK-NEXT: ret +} + +define zeroext i8 @test3(i8 zeroext %x, i8 zeroext %c) nounwind readnone ssp noredzone { +entry: + %div = udiv i8 %c, 3 + ret i8 %div + +; CHECK: test3: +; CHECK: imull $171, %eax, %eax +; CHECK-NEXT: shrb %ah +; CHECK-NEXT: movzbl %ah, %eax +; CHECK-NEXT: ret +} + +define signext i16 @test4(i16 signext %x) nounwind { +entry: + %div = sdiv i16 %x, 33 ; [#uses=1] ret i16 %div } Removed: llvm/trunk/test/CodeGen/X86/2008-11-29-DivideConstant16bitSigned.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2008-11-29-DivideConstant16bitSigned.ll?rev=121695&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/2008-11-29-DivideConstant16bitSigned.ll (original) +++ llvm/trunk/test/CodeGen/X86/2008-11-29-DivideConstant16bitSigned.ll (removed) @@ -1,9 +0,0 @@ -; RUN: llc < %s -mtriple=i686-pc-linux-gnu | grep -- -1985 -target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32" -target triple = "i686-pc-linux-gnu" - -define signext i16 @a(i16 signext %x) nounwind { -entry: - %div = sdiv i16 %x, 33 ; [#uses=1] - ret i16 %div -} From sabre at nondot.org Mon Dec 13 02:39:40 2010 From: sabre at nondot.org (Chris Lattner) Date: Mon, 13 Dec 2010 08:39:40 -0000 Subject: [llvm-commits] [llvm] r121697 - in /llvm/trunk/test/CodeGen/X86: 2008-11-29-DivideConstant16bit.ll divide-by-constant.ll Message-ID: <20101213083940.5A2552A6C12D@llvm.org> Author: lattner Date: Mon Dec 13 02:39:40 2010 New Revision: 121697 URL: http://llvm.org/viewvc/llvm-project?rev=121697&view=rev Log: rename test Added: llvm/trunk/test/CodeGen/X86/divide-by-constant.ll - copied unchanged from r121696, llvm/trunk/test/CodeGen/X86/2008-11-29-DivideConstant16bit.ll Removed: llvm/trunk/test/CodeGen/X86/2008-11-29-DivideConstant16bit.ll Removed: llvm/trunk/test/CodeGen/X86/2008-11-29-DivideConstant16bit.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2008-11-29-DivideConstant16bit.ll?rev=121696&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/2008-11-29-DivideConstant16bit.ll (original) +++ llvm/trunk/test/CodeGen/X86/2008-11-29-DivideConstant16bit.ll (removed) @@ -1,42 +0,0 @@ -; RUN: llc < %s -mtriple=i686-pc-linux-gnu -asm-verbose=0 | FileCheck %s -target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32" -target triple = "i686-pc-linux-gnu" - -define zeroext i16 @test1(i16 zeroext %x) nounwind { -entry: - %div = udiv i16 %x, 33 - ret i16 %div -; CHECK: test1: -; CHECK: imull $63551, %eax, %eax -; CHECK-NEXT: shrl $21, %eax -; CHECK-NEXT: ret -} - -define zeroext i16 @test2(i8 signext %x, i16 zeroext %c) nounwind readnone ssp noredzone { -entry: - %div = udiv i16 %c, 3 - ret i16 %div - -; CHECK: test2: -; CHECK: imull $43691, %eax, %eax -; CHECK-NEXT: shrl $17, %eax -; CHECK-NEXT: ret -} - -define zeroext i8 @test3(i8 zeroext %x, i8 zeroext %c) nounwind readnone ssp noredzone { -entry: - %div = udiv i8 %c, 3 - ret i8 %div - -; CHECK: test3: -; CHECK: imull $171, %eax, %eax -; CHECK-NEXT: shrb %ah -; CHECK-NEXT: movzbl %ah, %eax -; CHECK-NEXT: ret -} - -define signext i16 @test4(i16 signext %x) nounwind { -entry: - %div = sdiv i16 %x, 33 ; [#uses=1] - ret i16 %div -} From fvbommel at gmail.com Mon Dec 13 04:34:43 2010 From: fvbommel at gmail.com (Frits van Bommel) Date: Mon, 13 Dec 2010 11:34:43 +0100 Subject: [llvm-commits] [llvm] r121674 - in /llvm/trunk: lib/Transforms/Utils/SimplifyCFG.cpp test/Transforms/SimplifyCFG/switch_create.ll In-Reply-To: <20101213034357.E8F7E2A6C12C@llvm.org> References: <20101213034357.E8F7E2A6C12C@llvm.org> Message-ID: On Mon, Dec 13, 2010 at 4:43 AM, Chris Lattner wrote: > Author: lattner > Date: Sun Dec 12 21:43:57 2010 > New Revision: 121674 > > URL: http://llvm.org/viewvc/llvm-project?rev=121674&view=rev > Log: > Fix my previous patch to handle a degenerate case that the llvm-gcc > bootstrap buildbot tripped over. > + ?// Ok, the block is reachable from the default dest. ?If the constant we're > + ?// comparing exists in one of the other edges, then we can constant fold ICI > + ?// and zap it. > + ?if (SI->findCaseValue(Cst) != 0) { This should probably also make sure the successor for that case isn't equal to BB. (Yes, this is an even *more* degenerate case since BB is the default destination of the switch, but it's valid IR...) > + ? ?Value *V; > + ? ?if (ICI->getPredicate() == ICmpInst::ICMP_EQ) > + ? ? ?V = ConstantInt::getFalse(BB->getContext()); > + ? ?else > + ? ? ?V = ConstantInt::getTrue(BB->getContext()); > + > + ? ?ICI->replaceAllUsesWith(V); > + ? ?ICI->eraseFromParent(); > + ? ?// BB is now empty, so it is likely to simplify away. > + ? ?return SimplifyCFG(BB) | true; > + ?} > + By the way, the "if (SI->getDefaultDest() != BB)" just before this doesn't seem to handle the case where multiple cases jump to BB. From fvbommel at gmail.com Mon Dec 13 04:59:24 2010 From: fvbommel at gmail.com (Frits van Bommel) Date: Mon, 13 Dec 2010 11:59:24 +0100 Subject: [llvm-commits] [llvm] r121674 - in /llvm/trunk: lib/Transforms/Utils/SimplifyCFG.cpp test/Transforms/SimplifyCFG/switch_create.ll In-Reply-To: References: <20101213034357.E8F7E2A6C12C@llvm.org> Message-ID: On Mon, Dec 13, 2010 at 11:34 AM, Frits van Bommel wrote: > On Mon, Dec 13, 2010 at 4:43 AM, Chris Lattner wrote: >> + ?// Ok, the block is reachable from the default dest. ?If the constant we're >> + ?// comparing exists in one of the other edges, then we can constant fold ICI >> + ?// and zap it. >> + ?if (SI->findCaseValue(Cst) != 0) { > > This should probably also make sure the successor for that case isn't > equal to BB. (Yes, this is an even *more* degenerate case since BB is > the default destination of the switch, but it's valid IR...) > By the way, the "if (SI->getDefaultDest() != BB)" just before this > doesn't seem to handle the case where multiple cases jump to BB. Never mind, none of this code is reachable if there's more than one edge. I either overlooked the "return false if !BB->getSinglePredecessor()" code above it or forgot that getSinglePredecessor != getUniquePredecessor. From fvbommel at gmail.com Mon Dec 13 06:29:42 2010 From: fvbommel at gmail.com (Frits van Bommel) Date: Mon, 13 Dec 2010 13:29:42 +0100 Subject: [llvm-commits] [llvm] r121671 - in /llvm/trunk: lib/Transforms/Utils/SimplifyCFG.cpp test/Transforms/SimplifyCFG/switch_create.ll In-Reply-To: <20101213031854.39E3A2A6C12C@llvm.org> References: <20101213031854.39E3A2A6C12C@llvm.org> Message-ID: On Mon, Dec 13, 2010 at 4:18 AM, Chris Lattner wrote: > Author: lattner > Date: Sun Dec 12 21:18:54 2010 > New Revision: 121671 > > URL: http://llvm.org/viewvc/llvm-project?rev=121671&view=rev > Log: > fix a fairly serious oversight with switch formation from > or'd conditions. ?Previously we'd compile something like this: > > int crud (unsigned char c) { > ? return c == 62 || c == 34 || c == 92; > } > > into: > > ?switch i8 %c, label %lor.rhs [ > ? ?i8 62, label %lor.end > ? ?i8 34, label %lor.end > ?] > > lor.rhs: ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?; preds = %entry > ?%cmp8 = icmp eq i8 %c, 92 > ?br label %lor.end > > lor.end: ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?; preds = %entry, %entry, %lor.rhs > ?%0 = phi i1 [ true, %entry ], [ %cmp8, %lor.rhs ], [ true, %entry ] > ?%lor.ext = zext i1 %0 to i32 > ?ret i32 %lor.ext > > which failed to merge the compare-with-92 into the switch. ?With this patch > we simplify this all the way to: > > ?switch i8 %c, label %lor.rhs [ > ? ?i8 62, label %lor.end > ? ?i8 34, label %lor.end > ? ?i8 92, label %lor.end > ?] > > lor.rhs: ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?; preds = %entry > ?br label %lor.end > > lor.end: ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?; preds = %entry, %entry, %entry, %lor.rhs > ?%0 = phi i1 [ true, %entry ], [ false, %lor.rhs ], [ true, %entry ], [ true, %entry ] > ?%lor.ext = zext i1 %0 to i32 > ?ret i32 %lor.ext > > which is much better for codegen's switch lowering stuff. ?This kicks in 33 times > on 176.gcc (for example) cutting 103 instructions off the generated code. I have some code where this doesn't work, probably due to the requirement for the only use of the icmp to be a phi. A reduced test case: ===== bool foo(int x) { return x == 1; } bool bar(int x) { return x == 2; } bool baz(int x) { return x == 3; } bool quux(int x) { return foo(x) || bar(x) || baz(x); } ===== The problem seems to be that the return gets duplicated into the two branches before inlining, causing quux() to come out of clang -O3 like this: ===== define zeroext i1 @quux(int)(i32 %x) nounwind readnone { entry: switch i32 %x, label %lor.rhs [ i32 1, label %lor.end i32 2, label %lor.end ] lor.rhs: ; preds = %entry %cmp.i5 = icmp eq i32 %x, 3 ; [#uses=1] ret i1 %cmp.i5 lor.end: ; preds = %entry, %entry ret i1 true } ===== From geek4civic at gmail.com Mon Dec 13 09:07:10 2010 From: geek4civic at gmail.com (NAKAMURA Takumi) Date: Tue, 14 Dec 2010 00:07:10 +0900 Subject: [llvm-commits] [Review request][Win64] Improve allocating shadow area Message-ID: Good midnight, guys! I tweaked Win64's calling conversion. - On leaf functions(do not have win64's callee), redundant shadow area would not be emitted. - [PR8778] Calling parameters would be constructed properly onto dynamic stack allocation(alloca). This patch is not testsd widely. I would like to point out whatever I missed. Please take a look! ...Takumi -------------- next part -------------- From 9b0a03ce39694d036353b7d8d4b30fefb86b3b95 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Mon, 13 Dec 2010 17:59:20 +0900 Subject: [PATCH] Target/X86: Allocate Win64's shadow allocation, on stack, when callee requires one. In leaf functions, shadow area would not be allocated any more. --- lib/Target/X86/X86FrameInfo.cpp | 5 ----- lib/Target/X86/X86ISelLowering.cpp | 8 ++++++-- test/CodeGen/X86/2009-06-03-Win64DisableRedZone.ll | 4 ++-- test/CodeGen/X86/2009-06-03-Win64SpillXMM.ll | 9 ++++----- test/CodeGen/X86/win64_params.ll | 4 ++-- test/CodeGen/X86/win64_vararg.ll | 10 +++++----- 6 files changed, 19 insertions(+), 21 deletions(-) diff --git a/lib/Target/X86/X86FrameInfo.cpp b/lib/Target/X86/X86FrameInfo.cpp index c47b0fa..3733f6c 100644 --- a/lib/Target/X86/X86FrameInfo.cpp +++ b/lib/Target/X86/X86FrameInfo.cpp @@ -325,11 +325,6 @@ void X86FrameInfo::emitPrologue(MachineFunction &MF) const { if (HasFP) MinSize += SlotSize; StackSize = std::max(MinSize, StackSize > 128 ? StackSize - 128 : 0); MFI->setStackSize(StackSize); - } else if (IsWin64) { - // We need to always allocate 32 bytes as register spill area. - // FIXME: We might reuse these 32 bytes for leaf functions. - StackSize += 32; - MFI->setStackSize(StackSize); } // Insert stack pointer adjustment for later moving of return addr. Only diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 045bb93..fd93462 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -1807,8 +1807,7 @@ X86TargetLowering::LowerMemOpCallTo(SDValue Chain, DebugLoc dl, SelectionDAG &DAG, const CCValAssign &VA, ISD::ArgFlagsTy Flags) const { - const unsigned FirstStackArgOffset = (Subtarget->isTargetWin64() ? 32 : 0); - unsigned LocMemOffset = FirstStackArgOffset + VA.getLocMemOffset(); + unsigned LocMemOffset = VA.getLocMemOffset(); SDValue PtrOff = DAG.getIntPtrConstant(LocMemOffset); PtrOff = DAG.getNode(ISD::ADD, dl, getPointerTy(), StackPtr, PtrOff); if (Flags.isByVal()) @@ -1892,6 +1891,11 @@ X86TargetLowering::LowerCall(SDValue Chain, SDValue Callee, SmallVector ArgLocs; CCState CCInfo(CallConv, isVarArg, getTargetMachine(), ArgLocs, *DAG.getContext()); + + // Win64 CC requires at least 4 x 64bit of shadow allocation. + if (Subtarget->isTargetWin64()) + CCInfo.AllocateStack(32, 16); + CCInfo.AnalyzeCallOperands(Outs, CC_X86); // Get a count of how many bytes are to be pushed on the stack. diff --git a/test/CodeGen/X86/2009-06-03-Win64DisableRedZone.ll b/test/CodeGen/X86/2009-06-03-Win64DisableRedZone.ll index c598228..0413044 100644 --- a/test/CodeGen/X86/2009-06-03-Win64DisableRedZone.ll +++ b/test/CodeGen/X86/2009-06-03-Win64DisableRedZone.ll @@ -1,5 +1,5 @@ -; RUN: llc < %s | grep "subq.*\\\$40, \\\%rsp" -target triple = "x86_64-pc-mingw64" +; RUN: llc -mtriple=x86_64-pc-mingw64 < %s | FileCheck %s +; CHECK: subq $8, %rsp define x86_fp80 @a(i64 %x) nounwind readnone { entry: diff --git a/test/CodeGen/X86/2009-06-03-Win64SpillXMM.ll b/test/CodeGen/X86/2009-06-03-Win64SpillXMM.ll index 810a6f4..9833d96 100644 --- a/test/CodeGen/X86/2009-06-03-Win64SpillXMM.ll +++ b/test/CodeGen/X86/2009-06-03-Win64SpillXMM.ll @@ -1,8 +1,7 @@ -; RUN: llc < %s -o %t1 -; RUN: grep "subq.*\\\$72, \\\%rsp" %t1 -; RUN: grep "movaps \\\%xmm8, 32\\\(\\\%rsp\\\)" %t1 -; RUN: grep "movaps \\\%xmm7, 48\\\(\\\%rsp\\\)" %t1 -target triple = "x86_64-pc-mingw64" +; RUN: llc -mtriple=x86_64-pc-mingw64 < %s | FileCheck %s +; CHECK: subq $40, %rsp +; CHECK: movaps %xmm8, (%rsp) +; CHECK: movaps %xmm7, 16(%rsp) define i32 @a() nounwind { entry: diff --git a/test/CodeGen/X86/win64_params.ll b/test/CodeGen/X86/win64_params.ll index 0b67368..f9d4bf9 100644 --- a/test/CodeGen/X86/win64_params.ll +++ b/test/CodeGen/X86/win64_params.ll @@ -4,8 +4,8 @@ ; on the stack. define i32 @f6(i32 %p1, i32 %p2, i32 %p3, i32 %p4, i32 %p5, i32 %p6) nounwind readnone optsize { entry: -; CHECK: movl 80(%rsp), %eax -; CHECK: addl 72(%rsp), %eax +; CHECK: movl 48(%rsp), %eax +; CHECK: addl 40(%rsp), %eax %add = add nsw i32 %p6, %p5 ret i32 %add } diff --git a/test/CodeGen/X86/win64_vararg.ll b/test/CodeGen/X86/win64_vararg.ll index 072f36a..aa7d786 100644 --- a/test/CodeGen/X86/win64_vararg.ll +++ b/test/CodeGen/X86/win64_vararg.ll @@ -5,11 +5,11 @@ ; calculated. define void @average_va(i32 %count, ...) nounwind { entry: -; CHECK: subq $40, %rsp -; CHECK: movq %r9, 72(%rsp) -; CHECK: movq %r8, 64(%rsp) -; CHECK: movq %rdx, 56(%rsp) -; CHECK: leaq 56(%rsp), %rax +; CHECK: subq $8, %rsp +; CHECK: movq %r9, 40(%rsp) +; CHECK: movq %r8, 32(%rsp) +; CHECK: movq %rdx, 24(%rsp) +; CHECK: leaq 24(%rsp), %rax %ap = alloca i8*, align 8 ; [#uses=1] %ap1 = bitcast i8** %ap to i8* ; [#uses=1] -- 1.7.1.GIT From aggarwa4 at illinois.edu Mon Dec 13 09:55:23 2010 From: aggarwa4 at illinois.edu (Arushi Aggarwal) Date: Mon, 13 Dec 2010 15:55:23 -0000 Subject: [llvm-commits] [poolalloc] r121701 - in /poolalloc/trunk/lib/PoolAllocate: PoolAllocate.cpp TransformFunctionBody.cpp Message-ID: <20101213155523.EB9872A6C12E@llvm.org> Author: aggarwa4 Date: Mon Dec 13 09:55:23 2010 New Revision: 121701 URL: http://llvm.org/viewvc/llvm-project?rev=121701&view=rev Log: While building FuncInfo for the functions, we should look at the call graph to determine, which functions should be in the same EQ, and hence should get the same number of args. Since, we have already ensured that all targets, for the same call site have the same number of pool args, we can just choose any one to instrument the call site. Modified: poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp poolalloc/trunk/lib/PoolAllocate/TransformFunctionBody.cpp Modified: poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp?rev=121701&r1=121700&r2=121701&view=diff ============================================================================== --- poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp (original) +++ poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp Mon Dec 13 09:55:23 2010 @@ -658,6 +658,45 @@ // for corresponding arguments. Therefore, we want to process all the // functions in the same equivalence class once to avoid doing extra work. // + const DSCallGraph & callgraph = Graphs->getCallGraph(); + DSGraph* G = Graphs->getGlobalsGraph(); + DSGraph::ScalarMapTy& SM = G->getScalarMap(); + for (DSCallGraph::callee_key_iterator ii = callgraph.key_begin(), + ee = callgraph.key_end(); ii != ee; ++ii) { + bool isIndirect = ((*ii).getCalledFunction() == NULL); + + if (isIndirect) { + std::vector Functions; + DSCallGraph::callee_iterator csi = callgraph.callee_begin(*ii), + cse = callgraph.callee_end(*ii); + while(csi != cse) { + const Function *F = *csi; + DSCallGraph::scc_iterator sccii = callgraph.scc_begin(F), + sccee = callgraph.scc_end(F); + for(;sccii != sccee; ++sccii) { + DSGraph::ScalarMapTy::const_iterator I = SM.find(SM.getLeaderForGlobal(*sccii)); + if (I != SM.end() && !((*sccii)->isDeclaration())) { + Functions.push_back (*sccii); + } + } + ++csi; + } + const Function *F1 = (*ii).getInstruction()->getParent()->getParent(); + F1 = callgraph.sccLeader(&*F1); + + DSCallGraph::scc_iterator sccii = callgraph.scc_begin(F1), + sccee = callgraph.scc_end(F1); + for(;sccii != sccee; ++sccii) { + DSGraph::ScalarMapTy::const_iterator I = SM.find(SM.getLeaderForGlobal(*sccii)); + if (I != SM.end() && !((*sccii)->isDeclaration())) { + Functions.push_back (*sccii); + } + } + + FindFunctionPoolArgs (Functions); + } + } + /* EquivalenceClasses & GlobalECs = Graphs->getGlobalECs(); EquivalenceClasses::iterator EQSI = GlobalECs.begin(); EquivalenceClasses::iterator EQSE = GlobalECs.end(); @@ -691,7 +730,7 @@ // class and construct the FuncInfo structure for each one. // FindFunctionPoolArgs (Functions); - } + }*/ // // Make sure every function has a FuncInfo structure. Modified: poolalloc/trunk/lib/PoolAllocate/TransformFunctionBody.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/PoolAllocate/TransformFunctionBody.cpp?rev=121701&r1=121700&r2=121701&view=diff ============================================================================== --- poolalloc/trunk/lib/PoolAllocate/TransformFunctionBody.cpp (original) +++ poolalloc/trunk/lib/PoolAllocate/TransformFunctionBody.cpp Mon Dec 13 09:55:23 2010 @@ -935,12 +935,12 @@ // If this target takes more DSNodes than the last one we found, then // make *this* target our canonical target. // - if (CFI->ArgNodes.size() >= maxArgsWithNodes) { - maxArgsWithNodes = CFI->ArgNodes.size(); - CF = *sccii; - } + maxArgsWithNodes = CFI->ArgNodes.size(); + CF = *sccii; + break; } } + if(!CF){ const Function *F1 = OrigInst->getParent()->getParent(); F1 = callGraph.sccLeader(&*F1); @@ -960,10 +960,9 @@ // If this target takes more DSNodes than the last one we found, then // make *this* target our canonical target. // - if (CFI->ArgNodes.size() >= maxArgsWithNodes) { - maxArgsWithNodes = CFI->ArgNodes.size(); - CF = *sccii; - } + maxArgsWithNodes = CFI->ArgNodes.size(); + CF = *sccii; + } } // Assuming the call graph is always correct. And if the call graph reports, From benny.kra at googlemail.com Mon Dec 13 12:20:38 2010 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Mon, 13 Dec 2010 18:20:38 -0000 Subject: [llvm-commits] [llvm] r121705 - in /llvm/trunk: lib/Transforms/Utils/SimplifyCFG.cpp test/Transforms/SimplifyCFG/switch_create.ll Message-ID: <20101213182038.37A972A6C12C@llvm.org> Author: d0k Date: Mon Dec 13 12:20:38 2010 New Revision: 121705 URL: http://llvm.org/viewvc/llvm-project?rev=121705&view=rev Log: Fix sort predicate. qsort(3)'s predicate semantics differ from std::sort's. Fixes PR 8780. Modified: llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp llvm/trunk/test/Transforms/SimplifyCFG/switch_create.ll Modified: llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp?rev=121705&r1=121704&r2=121705&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp Mon Dec 13 12:20:38 2010 @@ -598,7 +598,7 @@ static int ConstantIntSortPredicate(const void *P1, const void *P2) { const ConstantInt *LHS = *(const ConstantInt**)P1; const ConstantInt *RHS = *(const ConstantInt**)P2; - return LHS->getValue().ult(RHS->getValue()); + return LHS->getValue().ult(RHS->getValue()) ? 1 : -1; } /// FoldValueComparisonIntoPredecessors - The specified terminator is a value Modified: llvm/trunk/test/Transforms/SimplifyCFG/switch_create.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimplifyCFG/switch_create.ll?rev=121705&r1=121704&r2=121705&view=diff ============================================================================== --- llvm/trunk/test/Transforms/SimplifyCFG/switch_create.ll (original) +++ llvm/trunk/test/Transforms/SimplifyCFG/switch_create.ll Mon Dec 13 12:20:38 2010 @@ -290,5 +290,44 @@ ; CHECK: ] } +; PR8780 +define i32 @test11(i32 %bar) nounwind { +entry: + %cmp = icmp eq i32 %bar, 4 + %cmp2 = icmp eq i32 %bar, 35 + %or.cond = or i1 %cmp, %cmp2 + %cmp5 = icmp eq i32 %bar, 53 + %or.cond1 = or i1 %or.cond, %cmp5 + %cmp8 = icmp eq i32 %bar, 24 + %or.cond2 = or i1 %or.cond1, %cmp8 + %cmp11 = icmp eq i32 %bar, 23 + %or.cond3 = or i1 %or.cond2, %cmp11 + %cmp14 = icmp eq i32 %bar, 55 + %or.cond4 = or i1 %or.cond3, %cmp14 + %cmp17 = icmp eq i32 %bar, 12 + %or.cond5 = or i1 %or.cond4, %cmp17 + %cmp20 = icmp eq i32 %bar, 35 + %or.cond6 = or i1 %or.cond5, %cmp20 + br i1 %or.cond6, label %if.then, label %if.end +if.then: ; preds = %entry + br label %return +if.end: ; preds = %entry + br label %return + +return: ; preds = %if.end, %if.then + %retval.0 = phi i32 [ 1, %if.then ], [ 0, %if.end ] + ret i32 %retval.0 + +; CHECK: @test11 +; CHECK: switch i32 %bar, label %if.end [ +; CHECK: i32 55, label %return +; CHECK: i32 53, label %return +; CHECK: i32 35, label %return +; CHECK: i32 24, label %return +; CHECK: i32 23, label %return +; CHECK: i32 12, label %return +; CHECK: i32 4, label %return +; CHECK: ] +} From aggarwa4 at illinois.edu Mon Dec 13 13:18:02 2010 From: aggarwa4 at illinois.edu (Arushi Aggarwal) Date: Mon, 13 Dec 2010 19:18:02 -0000 Subject: [llvm-commits] [poolalloc] r121707 - /poolalloc/trunk/lib/DSA/DSGraph.cpp Message-ID: <20101213191802.409EE2A6C12C@llvm.org> Author: aggarwa4 Date: Mon Dec 13 13:18:02 2010 New Revision: 121707 URL: http://llvm.org/viewvc/llvm-project?rev=121707&view=rev Log: As per getValueDest that creates DSNodes, there is no DSNode for Constant Null Values. Perform the same check here too. Modified: poolalloc/trunk/lib/DSA/DSGraph.cpp Modified: poolalloc/trunk/lib/DSA/DSGraph.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/DSGraph.cpp?rev=121707&r1=121706&r2=121707&view=diff ============================================================================== --- poolalloc/trunk/lib/DSA/DSGraph.cpp (original) +++ poolalloc/trunk/lib/DSA/DSGraph.cpp Mon Dec 13 13:18:02 2010 @@ -69,6 +69,9 @@ // Undef values, even ones of pointer type, don't get nodes. if (isa(V)) return false; + if (isa(V) && cast(V)->isNullValue()) + return false; + // Use the Aliasee of GlobalAliases // FIXME: This check might not be required, it's here because // something similar is done in the Local pass. From grosbach at apple.com Mon Dec 13 13:18:13 2010 From: grosbach at apple.com (Jim Grosbach) Date: Mon, 13 Dec 2010 19:18:13 -0000 Subject: [llvm-commits] [llvm] r121708 - /llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp Message-ID: <20101213191813.BFA822A6C12C@llvm.org> Author: grosbach Date: Mon Dec 13 13:18:13 2010 New Revision: 121708 URL: http://llvm.org/viewvc/llvm-project?rev=121708&view=rev Log: Trailing whitespace. Modified: llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp Modified: llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp?rev=121708&r1=121707&r2=121708&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp Mon Dec 13 13:18:13 2010 @@ -112,7 +112,7 @@ } assert ((Value < 4096) && "Out of range pc-relative fixup value!"); Value |= isAdd << 23; - + // Same addressing mode as fixup_arm_pcrel_10, // but with 16-bit halfwords swapped. if (Kind == ARM::fixup_t2_ldst_pcrel_12) { @@ -120,7 +120,7 @@ swapped |= (Value & 0x0000FFFF) << 16; return swapped; } - + return Value; } case ARM::fixup_arm_adr_pcrel_12: { @@ -143,14 +143,14 @@ case ARM::fixup_t2_branch: { Value = Value - 4; Value >>= 1; // Low bit is not encoded. - + uint64_t out = 0; out |= (Value & 0x80000) << 7; // S bit out |= (Value & 0x40000) >> 7; // J2 bit out |= (Value & 0x20000) >> 4; // J1 bit out |= (Value & 0x1F800) << 5; // imm6 field out |= (Value & 0x007FF); // imm11 field - + uint64_t swapped = (out & 0xFFFF0000) >> 16; swapped |= (out & 0x0000FFFF) << 16; return swapped; @@ -159,9 +159,9 @@ // The value doesn't encode the low bit (always zero) and is offset by // four. The value is encoded into disjoint bit positions in the destination // opcode. x = unchanged, I = immediate value bit, S = sign extension bit - // + // // BL: xxxxxSIIIIIIIIII xxxxxIIIIIIIIIII - // + // // Note that the halfwords are stored high first, low second; so we need // to transpose the fixup value here to map properly. unsigned isNeg = (int64_t(Value) < 0) ? 1 : 0; @@ -177,9 +177,9 @@ // four (see fixup_arm_thumb_cp). The value is encoded into disjoint bit // positions in the destination opcode. x = unchanged, I = immediate value // bit, S = sign extension bit, 0 = zero. - // + // // BLX: xxxxxSIIIIIIIIII xxxxxIIIIIIIIII0 - // + // // Note that the halfwords are stored high first, low second; so we need // to transpose the fixup value here to map properly. unsigned isNeg = (int64_t(Value) < 0) ? 1 : 0; From grosbach at apple.com Mon Dec 13 13:25:46 2010 From: grosbach at apple.com (Jim Grosbach) Date: Mon, 13 Dec 2010 19:25:46 -0000 Subject: [llvm-commits] [llvm] r121709 - /llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp Message-ID: <20101213192546.AE1BF2A6C12C@llvm.org> Author: grosbach Date: Mon Dec 13 13:25:46 2010 New Revision: 121709 URL: http://llvm.org/viewvc/llvm-project?rev=121709&view=rev Log: Use 32-bit types for 32-bit values. Modified: llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp Modified: llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp?rev=121709&r1=121708&r2=121709&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp Mon Dec 13 13:25:46 2010 @@ -144,14 +144,14 @@ Value = Value - 4; Value >>= 1; // Low bit is not encoded. - uint64_t out = 0; + uint32_t out = 0; out |= (Value & 0x80000) << 7; // S bit out |= (Value & 0x40000) >> 7; // J2 bit out |= (Value & 0x20000) >> 4; // J1 bit out |= (Value & 0x1F800) << 5; // imm6 field out |= (Value & 0x007FF); // imm11 field - uint64_t swapped = (out & 0xFFFF0000) >> 16; + uint32_t swapped = (out & 0xFFFF0000) >> 16; swapped |= (out & 0x0000FFFF) << 16; return swapped; } @@ -226,7 +226,7 @@ // Same addressing mode as fixup_arm_pcrel_10, // but with 16-bit halfwords swapped. if (Kind == ARM::fixup_t2_pcrel_10) { - uint64_t swapped = (Value & 0xFFFF0000) >> 16; + uint32_t swapped = (Value & 0xFFFF0000) >> 16; swapped |= (Value & 0x0000FFFF) << 16; return swapped; } From resistor at mac.com Mon Dec 13 13:31:11 2010 From: resistor at mac.com (Owen Anderson) Date: Mon, 13 Dec 2010 19:31:11 -0000 Subject: [llvm-commits] [llvm] r121710 - in /llvm/trunk: lib/Target/ARM/ARMAsmBackend.cpp lib/Target/ARM/ARMCodeEmitter.cpp lib/Target/ARM/ARMFixupKinds.h lib/Target/ARM/ARMInstrInfo.td lib/Target/ARM/ARMInstrThumb2.td lib/Target/ARM/ARMMCCodeEmitter.cpp utils/TableGen/EDEmitter.cpp utils/TableGen/X86RecognizableInstr.cpp Message-ID: <20101213193111.DCC252A6C12C@llvm.org> Author: resistor Date: Mon Dec 13 13:31:11 2010 New Revision: 121710 URL: http://llvm.org/viewvc/llvm-project?rev=121710&view=rev Log: In Thumb2, direct branches can be encoded as either a "short" conditional branch with a null predicate, or as a "long" direct branch. While the mnemonics are the same, they encode the branch offset differently, and the Darwin assembler appears to prefer the "long" form for direct branches. Thus, in the name of bitwise equivalence, provide encoding and fixup support for it. Modified: llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp llvm/trunk/lib/Target/ARM/ARMFixupKinds.h llvm/trunk/lib/Target/ARM/ARMInstrInfo.td llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp llvm/trunk/utils/TableGen/EDEmitter.cpp llvm/trunk/utils/TableGen/X86RecognizableInstr.cpp Modified: llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp?rev=121710&r1=121709&r2=121710&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp Mon Dec 13 13:31:11 2010 @@ -140,11 +140,32 @@ // These values don't encode the low two bits since they're always zero. // Offset by 8 just as above. return 0xffffff & ((Value - 8) >> 2); - case ARM::fixup_t2_branch: { + case ARM::fixup_t2_uncondbranch: { Value = Value - 4; Value >>= 1; // Low bit is not encoded. uint32_t out = 0; + bool I = Value & 0x800000; + bool J1 = Value & 0x400000; + bool J2 = Value & 0x200000; + J1 ^= I; + J2 ^= I; + + out |= I << 26; // S bit + out |= !J1 << 13; // J1 bit + out |= !J2 << 11; // J2 bit + out |= (Value & 0x1FF800) << 5; // imm6 field + out |= (Value & 0x0007FF); // imm11 field + + uint64_t swapped = (out & 0xFFFF0000) >> 16; + swapped |= (out & 0x0000FFFF) << 16; + return swapped; + } + case ARM::fixup_t2_condbranch: { + Value = Value - 4; + Value >>= 1; // Low bit is not encoded. + + uint64_t out = 0; out |= (Value & 0x80000) << 7; // S bit out |= (Value & 0x40000) >> 7; // J2 bit out |= (Value & 0x20000) >> 4; // J1 bit @@ -332,7 +353,8 @@ case FK_Data_4: case ARM::fixup_t2_ldst_pcrel_12: - case ARM::fixup_t2_branch: + case ARM::fixup_t2_condbranch: + case ARM::fixup_t2_uncondbranch: case ARM::fixup_t2_pcrel_10: case ARM::fixup_arm_thumb_bl: case ARM::fixup_arm_thumb_blx: Modified: llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp?rev=121710&r1=121709&r2=121710&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp Mon Dec 13 13:31:11 2010 @@ -183,6 +183,8 @@ const { return 0; } unsigned getBranchTargetOpValue(const MachineInstr &MI, unsigned Op) const { return 0; } + unsigned getUnconditionalBranchTargetOpValue(const MachineInstr &MI, + unsigned Op) const { return 0; } unsigned getCCOutOpValue(const MachineInstr &MI, unsigned Op) const { return 0; } unsigned getSOImmOpValue(const MachineInstr &MI, unsigned Op) Modified: llvm/trunk/lib/Target/ARM/ARMFixupKinds.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMFixupKinds.h?rev=121710&r1=121709&r2=121710&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMFixupKinds.h (original) +++ llvm/trunk/lib/Target/ARM/ARMFixupKinds.h Mon Dec 13 13:31:11 2010 @@ -36,9 +36,12 @@ // fixup_arm_branch - 24-bit PC relative relocation for direct branch // instructions. fixup_arm_branch, - // fixup_t2_branch - 20-bit PC relative relocation for Thumb2 direct branch - // instructions. - fixup_t2_branch, + // fixup_t2_condbranch - 20-bit PC relative relocation for Thumb2 direct + // uconditional branch instructions. + fixup_t2_condbranch, + // fixup_t2_uncondbranch - 20-bit PC relative relocation for Thumb2 direct + // branch unconditional branch instructions. + fixup_t2_uncondbranch, // fixup_arm_thumb_br - 12-bit fixup for Thumb B instructions. fixup_arm_thumb_br, Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=121710&r1=121709&r2=121710&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Mon Dec 13 13:31:11 2010 @@ -293,6 +293,10 @@ let EncoderMethod = "getBranchTargetOpValue"; } +def uncondbrtarget : Operand { + let EncoderMethod = "getUnconditionalBranchTargetOpValue"; +} + // Call target. def bltarget : Operand { // Encoded the same as branch targets. Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td?rev=121710&r1=121709&r2=121710&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td Mon Dec 13 13:31:11 2010 @@ -2961,7 +2961,7 @@ let isBranch = 1, isTerminator = 1, isBarrier = 1 in { let isPredicable = 1 in -def t2B : T2XI<(outs), (ins brtarget:$target), IIC_Br, +def t2B : T2XI<(outs), (ins uncondbrtarget:$target), IIC_Br, "b.w\t$target", [(br bb:$target)]> { let Inst{31-27} = 0b11110; Modified: llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp?rev=121710&r1=121709&r2=121710&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp Mon Dec 13 13:31:11 2010 @@ -57,7 +57,8 @@ MCFixupKindInfo::FKF_IsAligned}, { "fixup_arm_adr_pcrel_12", 1, 24, MCFixupKindInfo::FKF_IsPCRel }, { "fixup_arm_branch", 1, 24, MCFixupKindInfo::FKF_IsPCRel }, -{ "fixup_t2_branch", 0, 32, MCFixupKindInfo::FKF_IsPCRel }, +{ "fixup_t2_condbranch", 0, 32, MCFixupKindInfo::FKF_IsPCRel }, +{ "fixup_t2_uncondbranch", 0, 32, MCFixupKindInfo::FKF_IsPCRel }, { "fixup_arm_thumb_br", 0, 16, MCFixupKindInfo::FKF_IsPCRel }, { "fixup_arm_thumb_bl", 0, 32, MCFixupKindInfo::FKF_IsPCRel }, { "fixup_arm_thumb_blx", 7, 21, MCFixupKindInfo::FKF_IsPCRel }, @@ -122,6 +123,12 @@ uint32_t getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, SmallVectorImpl &Fixups) const; + /// getUnconditionalBranchTargetOpValue - Return encoding info for 24-bit + /// immediate Thumb2 direct branch target. + uint32_t getUnconditionalBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, + SmallVectorImpl &Fixups) const; + + /// getAdrLabelOpValue - Return encoding info for 12-bit immediate /// ADR label target. uint32_t getAdrLabelOpValue(const MCInst &MI, unsigned OpIdx, @@ -499,10 +506,34 @@ // coupling between MC and TM anywhere we can help it. const ARMSubtarget &Subtarget = TM.getSubtarget(); if (Subtarget.isThumb2()) - return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_branch, Fixups); + return + ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_condbranch, Fixups); return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_branch, Fixups); } +/// getUnconditionalBranchTargetOpValue - Return encoding info for 24-bit +/// immediate branch target. +uint32_t ARMMCCodeEmitter:: +getUnconditionalBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, + SmallVectorImpl &Fixups) const { + unsigned Val = + ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_uncondbranch, Fixups); + bool I = (Val & 0x800000); + bool J1 = (Val & 0x400000); + bool J2 = (Val & 0x200000); + if (I ^ J1) + Val &= ~0x400000; + else + Val |= 0x400000; + + if (I ^ J2) + Val &= ~0x200000; + else + Val |= 0x200000; + + return Val; +} + /// getAdrLabelOpValue - Return encoding info for 12-bit immediate ADR label /// target. uint32_t ARMMCCodeEmitter:: Modified: llvm/trunk/utils/TableGen/EDEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/EDEmitter.cpp?rev=121710&r1=121709&r2=121710&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/EDEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/EDEmitter.cpp Mon Dec 13 13:31:11 2010 @@ -322,6 +322,7 @@ PCR("offset32"); PCR("offset64"); PCR("brtarget"); + PCR("uncondbrtarget"); PCR("bltarget"); return 1; @@ -587,6 +588,7 @@ IMM("neon_vcvt_imm32"); MISC("brtarget", "kOperandTypeARMBranchTarget"); // ? + MISC("uncondbrtarget", "kOperandTypeARMBranchTarget"); // ? MISC("t_brtarget", "kOperandTypeARMBranchTarget"); // ? MISC("t_bcctarget", "kOperandTypeARMBranchTarget"); // ? MISC("t_cbtarget", "kOperandTypeARMBranchTarget"); // ? Modified: llvm/trunk/utils/TableGen/X86RecognizableInstr.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/X86RecognizableInstr.cpp?rev=121710&r1=121709&r2=121710&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/X86RecognizableInstr.cpp (original) +++ llvm/trunk/utils/TableGen/X86RecognizableInstr.cpp Mon Dec 13 13:31:11 2010 @@ -857,6 +857,7 @@ TYPE("i32imm_pcrel", TYPE_REL32) TYPE("SSECC", TYPE_IMM3) TYPE("brtarget", TYPE_RELv) + TYPE("uncondbrtarget", TYPE_RELv) TYPE("brtarget8", TYPE_REL8) TYPE("f80mem", TYPE_M80FP) TYPE("lea32mem", TYPE_LEA) From sabre at nondot.org Mon Dec 13 13:55:30 2010 From: sabre at nondot.org (Chris Lattner) Date: Mon, 13 Dec 2010 19:55:30 -0000 Subject: [llvm-commits] [llvm] r121711 - /llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp Message-ID: <20101213195530.C7A922A6C12C@llvm.org> Author: lattner Date: Mon Dec 13 13:55:30 2010 New Revision: 121711 URL: http://llvm.org/viewvc/llvm-project?rev=121711&view=rev Log: add some DEBUG's. Modified: llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp Modified: llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp?rev=121711&r1=121710&r2=121711&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp Mon Dec 13 13:55:30 2010 @@ -1905,10 +1905,16 @@ BasicBlock *BB = BI->getParent(); + DEBUG(dbgs() << "CONVERTING 'icmp' CHAIN with " << Values.size() + << " cases into SWITCH. BB is:\n" << *BB); + // If there are any extra values that couldn't be folded into the switch // then we evaluate them with an explicit branch first. Split the block // right before the condbr to handle it. if (ExtraCase) { + DEBUG(dbgs() << " ** 'icmp' chain unhandled condition: " << *ExtraCase + << '\n'); + BasicBlock *NewBB = BB->splitBasicBlock(BI, "switch.early.test"); // Remove the uncond branch added to the old block. TerminatorInst *OldTI = BB->getTerminator(); @@ -2361,7 +2367,7 @@ // branches to us and one of our successors, fold the setcc into the // predecessor and use logical operations to pick the right destination. if (FoldBranchToCommonDest(BI)) - return SimplifyCFG(BB) | true; + return true; // Scan predecessor blocks for conditional branches. for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI) @@ -2413,8 +2419,7 @@ if (BI->isUnconditional()) { if (SimplifyUncondBranch(BI)) return true; } else { - if (SimplifyCondBranch(BI)) - return true; + if (SimplifyCondBranch(BI)) return true; } } else if (ReturnInst *RI = dyn_cast(BB->getTerminator())) { if (SimplifyReturn(RI)) return true; From evan.cheng at apple.com Mon Dec 13 14:32:54 2010 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 13 Dec 2010 20:32:54 -0000 Subject: [llvm-commits] [llvm] r121714 - /llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Message-ID: <20101213203254.800EF2A6C12C@llvm.org> Author: evancheng Date: Mon Dec 13 14:32:54 2010 New Revision: 121714 URL: http://llvm.org/viewvc/llvm-project?rev=121714&view=rev Log: Generalize BFI isel lowering a bit. Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=121714&r1=121713&r2=121714&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Mon Dec 13 14:32:54 2010 @@ -4713,57 +4713,43 @@ if (VT != MVT::i32) return SDValue(); + SDValue N00 = N0.getOperand(0); // The value and the mask need to be constants so we can verify this is // actually a bitfield set. If the mask is 0xffff, we can do better // via a movt instruction, so don't use BFI in that case. - ConstantSDNode *C = dyn_cast(N0.getOperand(1)); - if (!C) + SDValue MaskOp = N0.getOperand(1); + ConstantSDNode *MaskC = dyn_cast(MaskOp); + if (!MaskC) return SDValue(); - unsigned Mask = C->getZExtValue(); + unsigned Mask = MaskC->getZExtValue(); if (Mask == 0xffff) return SDValue(); SDValue Res; // Case (1): or (and A, mask), val => ARMbfi A, val, mask - if ((C = dyn_cast(N1))) { - unsigned Val = C->getZExtValue(); + ConstantSDNode *N1C = dyn_cast(N1); + if (N1C) { + unsigned Val = N1C->getZExtValue(); if ((Val & ~Mask) != Val) return SDValue(); if (ARM::isBitFieldInvertedMask(Mask)) { Val >>= CountTrailingZeros_32(~Mask); - Res = DAG.getNode(ARMISD::BFI, DL, VT, N0.getOperand(0), + Res = DAG.getNode(ARMISD::BFI, DL, VT, N00, DAG.getConstant(Val, MVT::i32), DAG.getConstant(Mask, MVT::i32)); // Do not add new nodes to DAG combiner worklist. DCI.CombineTo(N, Res, false); - } else if (N0.getOperand(0).getOpcode() == ISD::SHL && - isa(N0.getOperand(0).getOperand(1)) && - ARM::isBitFieldInvertedMask(~Mask)) { - // Case (3): or (and (shl A, #shamt), mask), B => ARMbfi B, A, ~mask - // where lsb(mask) == #shamt - SDValue ShAmt = N0.getOperand(0).getOperand(1); - unsigned ShAmtC = cast(ShAmt)->getZExtValue(); - unsigned LSB = CountTrailingZeros_32(Mask); - if (ShAmtC != LSB) - return SDValue(); - //unsigned Width = (32 - CountLeadingZeros_32(Mask)) - LSB; - - Res = DAG.getNode(ARMISD::BFI, DL, VT, N1, - N0.getOperand(0).getOperand(0), - DAG.getConstant(~Mask, MVT::i32)); - - // Do not add new nodes to DAG combiner worklist. - DCI.CombineTo(N, Res, false); + return SDValue(); } } else if (N1.getOpcode() == ISD::AND) { // case (2) or (and A, mask), (and B, mask2) => ARMbfi A, (lsr B, amt), mask - C = dyn_cast(N1.getOperand(1)); - if (!C) + ConstantSDNode *N11C = dyn_cast(N1.getOperand(1)); + if (!N11C) return SDValue(); - unsigned Mask2 = C->getZExtValue(); + unsigned Mask2 = N11C->getZExtValue(); if (ARM::isBitFieldInvertedMask(Mask) && ARM::isBitFieldInvertedMask(~Mask2) && @@ -4777,10 +4763,11 @@ unsigned lsb = CountTrailingZeros_32(Mask2); Res = DAG.getNode(ISD::SRL, DL, VT, N1.getOperand(0), DAG.getConstant(lsb, MVT::i32)); - Res = DAG.getNode(ARMISD::BFI, DL, VT, N0.getOperand(0), Res, + Res = DAG.getNode(ARMISD::BFI, DL, VT, N00, Res, DAG.getConstant(Mask, MVT::i32)); // Do not add new nodes to DAG combiner worklist. DCI.CombineTo(N, Res, false); + return SDValue(); } else if (ARM::isBitFieldInvertedMask(~Mask) && ARM::isBitFieldInvertedMask(Mask2) && (CountPopulation_32(~Mask) == CountPopulation_32(Mask2))) { @@ -4791,15 +4778,34 @@ return SDValue(); // 2b unsigned lsb = CountTrailingZeros_32(Mask); - Res = DAG.getNode(ISD::SRL, DL, VT, N0.getOperand(0), + Res = DAG.getNode(ISD::SRL, DL, VT, N00, DAG.getConstant(lsb, MVT::i32)); Res = DAG.getNode(ARMISD::BFI, DL, VT, N1.getOperand(0), Res, DAG.getConstant(Mask2, MVT::i32)); // Do not add new nodes to DAG combiner worklist. DCI.CombineTo(N, Res, false); + return SDValue(); } } + if (DAG.MaskedValueIsZero(N1, MaskC->getAPIntValue()) && + N00.getOpcode() == ISD::SHL && isa(N00.getOperand(1)) && + ARM::isBitFieldInvertedMask(~Mask)) { + // Case (3): or (and (shl A, #shamt), mask), B => ARMbfi B, A, ~mask + // where lsb(mask) == #shamt and masked bits of B are known zero. + SDValue ShAmt = N00.getOperand(1); + unsigned ShAmtC = cast(ShAmt)->getZExtValue(); + unsigned LSB = CountTrailingZeros_32(Mask); + if (ShAmtC != LSB) + return SDValue(); + + Res = DAG.getNode(ARMISD::BFI, DL, VT, N1, N00.getOperand(0), + DAG.getConstant(~Mask, MVT::i32)); + + // Do not add new nodes to DAG combiner worklist. + DCI.CombineTo(N, Res, false); + } + return SDValue(); } From jasonwkim at google.com Mon Dec 13 14:37:26 2010 From: jasonwkim at google.com (Jason Kim) Date: Mon, 13 Dec 2010 12:37:26 -0800 Subject: [llvm-commits] [LLVMdev] PR 8199 - Can we get patches reviewed? In-Reply-To: References: Message-ID: Hi David. I think the regulars want the patches posted on llvm-commits for review However, taking a look at the second one (lit2.patch, attached), there's couple of utilities missing in the list - like elf-dump etc. I'd vote getting rid of the llvm-gcc bindir being prepended as the easiest solution to fix this. But I don't know WHY that path was being prepended in the first place. (Perhaps someone with a longer memory then I can comment?) If the list of executables changes, then the explicit list of known tools need to change as well. Problem is, I can't immediately think of a nice way to get the list of generated execs exported to llvm-lit, -jason On Mon, Dec 13, 2010 at 11:34 AM, David Greene wrote: > I would like to see if we can get patches posted to PR 8199 reviewed > ASAP. ?These patches fix some problems with the lit tool and get the > test suites working for me. ?I won't be able to contribute any code > until this PR gets resolved. > > Patch #1 or Patch #3 on the PR both fix the problem. ?The difference in > the patches is how ^ and $ are treated in substitution matching. ?Read > the bug comments for details. > > Thanks! > > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?-Dave > > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu ? ? ? ? http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev > -------------- next part -------------- A non-text attachment was scrubbed... Name: lit2.patch Type: text/x-patch Size: 3021 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20101213/cabea872/attachment.bin From wendling at apple.com Mon Dec 13 14:58:47 2010 From: wendling at apple.com (Bill Wendling) Date: Mon, 13 Dec 2010 12:58:47 -0800 Subject: [llvm-commits] [llvm] r121675 - /llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp In-Reply-To: <20101213041519.9DE9B2A6C12C@llvm.org> References: <20101213041519.9DE9B2A6C12C@llvm.org> Message-ID: <7635E375-1A01-4247-9B3C-85EBC21349EB@apple.com> On Dec 12, 2010, at 8:15 PM, Chris Lattner wrote: > Author: lattner > Date: Sun Dec 12 22:15:19 2010 > New Revision: 121675 > > URL: http://llvm.org/viewvc/llvm-project?rev=121675&view=rev > Log: > inline a function, making the result much simpler. > Chris, This doesn't have the same semantics as the original non-inlined version. TrueWhenEqual should be "false" if the dyn_cast fails. -bw > Modified: > llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp > > Modified: llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp?rev=121675&r1=121674&r2=121675&view=diff > ============================================================================== > --- llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp (original) > +++ llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp Sun Dec 12 22:15:19 2010 > @@ -347,31 +347,6 @@ > return 0; > } > > -/// GatherValueComparisons - If the specified Cond is an 'and' or 'or' of a > -/// bunch of comparisons of one value against constants, return the value and > -/// the constants being compared. > -static bool GatherValueComparisons(Value *CondV, Value *&CompVal, > - std::vector &Values, > - const TargetData *TD) { > - Instruction *Cond = dyn_cast(CondV); > - if (Cond == 0) return false; > - > - if (Cond->getOpcode() == Instruction::Or) { > - CompVal = GatherConstantSetEQs(Cond, Values, TD); > - > - // Return true to indicate that the condition is true if the CompVal is > - // equal to one of the constants. > - return true; > - } > - if (Cond->getOpcode() == Instruction::And) { > - CompVal = GatherConstantSetNEs(Cond, Values, TD); > - > - // Return false to indicate that the condition is false if the CompVal is > - // equal to one of the constants. > - return false; > - } > - return false; > -} > > static void EraseTerminatorInstAndDCECond(TerminatorInst *TI) { > Instruction* Cond = 0; > @@ -2096,8 +2071,17 @@ > // 'setne's and'ed together, collect them. > Value *CompVal = 0; > std::vector Values; > - bool TrueWhenEqual = GatherValueComparisons(BI->getCondition(), CompVal, > - Values, TD); > + bool TrueWhenEqual = true; > + > + if (Instruction *Cond = dyn_cast(BI->getCondition())) { > + if (Cond->getOpcode() == Instruction::Or) { > + CompVal = GatherConstantSetEQs(Cond, Values, TD); > + } else if (Cond->getOpcode() == Instruction::And) { > + CompVal = GatherConstantSetNEs(Cond, Values, TD); > + TrueWhenEqual = false; > + } > + } > + > if (CompVal) { > // There might be duplicate constants in the list, which the switch > // instruction can't handle, remove them now. > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20101213/68062073/attachment.html From bob.wilson at apple.com Mon Dec 13 15:05:44 2010 From: bob.wilson at apple.com (Bob Wilson) Date: Mon, 13 Dec 2010 21:05:44 -0000 Subject: [llvm-commits] [llvm] r121715 - /llvm/trunk/lib/Target/ARM/ARMInstrNEON.td Message-ID: <20101213210544.794D82A6C12C@llvm.org> Author: bwilson Date: Mon Dec 13 15:05:44 2010 New Revision: 121715 URL: http://llvm.org/viewvc/llvm-project?rev=121715&view=rev Log: Remove unused instruction class arguments. Modified: llvm/trunk/lib/Target/ARM/ARMInstrNEON.td Modified: llvm/trunk/lib/Target/ARM/ARMInstrNEON.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrNEON.td?rev=121715&r1=121714&r2=121715&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrNEON.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrNEON.td Mon Dec 13 15:05:44 2010 @@ -1670,7 +1670,7 @@ // Basic 2-register operations: single-, double- and quad-register. class N2VS op24_23, bits<2> op21_20, bits<2> op19_18, bits<2> op17_16, bits<5> op11_7, bit op4, string OpcodeStr, - string Dt, ValueType ResTy, ValueType OpTy, SDNode OpNode> + string Dt> : N2V; @@ -1744,13 +1744,10 @@ // Basic 3-register operations: single-, double- and quad-register. class N3VS op21_20, bits<4> op11_8, bit op4, - string OpcodeStr, string Dt, ValueType ResTy, ValueType OpTy, - SDNode OpNode, bit Commutable> + string OpcodeStr, string Dt> : N3V { - let isCommutable = Commutable; -} + IIC_VBIND, OpcodeStr, Dt, "$Vd, $Vn, $Vm", "", []>; class N3VD op21_20, bits<4> op11_8, bit op4, InstrItinClass itin, string OpcodeStr, string Dt, @@ -1923,10 +1920,8 @@ // Multiply-Add/Sub operations: single-, double- and quad-register. class N3VSMulOp op21_20, bits<4> op11_8, bit op4, - InstrItinClass itin, string OpcodeStr, string Dt, - ValueType Ty, SDPatternOperator MulOp, SDNode OpNode> - : N3V + : N3V; @@ -4716,17 +4711,17 @@ // Vector Add Operations used for single-precision FP let neverHasSideEffects = 1 in -def VADDfd_sfp : N3VS<0,0,0b00,0b1101,0, "vadd", "f32", v2f32, v2f32, fadd, 1>; +def VADDfd_sfp : N3VS<0,0,0b00,0b1101,0, "vadd", "f32">; def : N3VSPat; // Vector Sub Operations used for single-precision FP let neverHasSideEffects = 1 in -def VSUBfd_sfp : N3VS<0,0,0b10,0b1101,0, "vsub", "f32", v2f32, v2f32, fsub, 0>; +def VSUBfd_sfp : N3VS<0,0,0b10,0b1101,0, "vsub", "f32">; def : N3VSPat; // Vector Multiply Operations used for single-precision FP let neverHasSideEffects = 1 in -def VMULfd_sfp : N3VS<1,0,0b00,0b1101,1, "vmul", "f32", v2f32, v2f32, fmul, 1>; +def VMULfd_sfp : N3VS<1,0,0b00,0b1101,1, "vmul", "f32">; def : N3VSPat; // Vector Multiply-Accumulate/Subtract used for single-precision FP @@ -4734,14 +4729,12 @@ // we want to avoid them for now. e.g., alternating vmla/vadd instructions. let neverHasSideEffects = 1 in -def VMLAfd_sfp : N3VSMulOp<0,0,0b00,0b1101,1, IIC_VMACD, "vmla", "f32", - v2f32, fmul_su, fadd>; +def VMLAfd_sfp : N3VSMulOp<0,0,0b00,0b1101,1, IIC_VMACD, "vmla", "f32">; def : N3VSMulOpPat, Requires<[HasNEON, UseNEONForFP, UseFPVMLx]>; let neverHasSideEffects = 1 in -def VMLSfd_sfp : N3VSMulOp<0,0,0b10,0b1101,1, IIC_VMACD, "vmls", "f32", - v2f32, fmul_su, fsub>; +def VMLSfd_sfp : N3VSMulOp<0,0,0b10,0b1101,1, IIC_VMACD, "vmls", "f32">; def : N3VSMulOpPat, Requires<[HasNEON, UseNEONForFP, UseFPVMLx]>; @@ -4775,23 +4768,19 @@ // Vector Convert between single-precision FP and integer let neverHasSideEffects = 1 in -def VCVTf2sd_sfp : N2VS<0b11, 0b11, 0b10, 0b11, 0b01110, 0, "vcvt", "s32.f32", - v2i32, v2f32, fp_to_sint>; +def VCVTf2sd_sfp : N2VS<0b11, 0b11, 0b10, 0b11, 0b01110, 0, "vcvt", "s32.f32">; def : N2VSPat; let neverHasSideEffects = 1 in -def VCVTf2ud_sfp : N2VS<0b11, 0b11, 0b10, 0b11, 0b01111, 0, "vcvt", "u32.f32", - v2i32, v2f32, fp_to_uint>; +def VCVTf2ud_sfp : N2VS<0b11, 0b11, 0b10, 0b11, 0b01111, 0, "vcvt", "u32.f32">; def : N2VSPat; let neverHasSideEffects = 1 in -def VCVTs2fd_sfp : N2VS<0b11, 0b11, 0b10, 0b11, 0b01100, 0, "vcvt", "f32.s32", - v2f32, v2i32, sint_to_fp>; +def VCVTs2fd_sfp : N2VS<0b11, 0b11, 0b10, 0b11, 0b01100, 0, "vcvt", "f32.s32">; def : N2VSPat; let neverHasSideEffects = 1 in -def VCVTu2fd_sfp : N2VS<0b11, 0b11, 0b10, 0b11, 0b01101, 0, "vcvt", "f32.u32", - v2f32, v2i32, uint_to_fp>; +def VCVTu2fd_sfp : N2VS<0b11, 0b11, 0b10, 0b11, 0b01101, 0, "vcvt", "f32.u32">; def : N2VSPat; //===----------------------------------------------------------------------===// From bob.wilson at apple.com Mon Dec 13 15:05:52 2010 From: bob.wilson at apple.com (Bob Wilson) Date: Mon, 13 Dec 2010 21:05:52 -0000 Subject: [llvm-commits] [llvm] r121716 - in /llvm/trunk/lib/Target/ARM: ARMExpandPseudoInsts.cpp ARMInstrNEON.td Message-ID: <20101213210552.862962A6C12C@llvm.org> Author: bwilson Date: Mon Dec 13 15:05:52 2010 New Revision: 121716 URL: http://llvm.org/viewvc/llvm-project?rev=121716&view=rev Log: Use pseudo instructions for 2-register Neon instructions for scalar FP. Partial fix for Radar 8711675. Modified: llvm/trunk/lib/Target/ARM/ARMExpandPseudoInsts.cpp llvm/trunk/lib/Target/ARM/ARMInstrNEON.td Modified: llvm/trunk/lib/Target/ARM/ARMExpandPseudoInsts.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMExpandPseudoInsts.cpp?rev=121716&r1=121715&r2=121716&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMExpandPseudoInsts.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMExpandPseudoInsts.cpp Mon Dec 13 15:05:52 2010 @@ -54,6 +54,7 @@ void ExpandLaneOp(MachineBasicBlock::iterator &MBBI); void ExpandVTBL(MachineBasicBlock::iterator &MBBI, unsigned Opc, bool IsExt, unsigned NumRegs); + void ExpandNeonSFP2(MachineBasicBlock::iterator &MBBI, unsigned Opc); }; char ARMExpandPseudo::ID = 0; } @@ -612,6 +613,21 @@ MI.eraseFromParent(); } +/// ExpandNeonSFP2 - Translate a 2-register Neon pseudo instruction used for +/// scalar floating-point to a real instruction. +void ARMExpandPseudo::ExpandNeonSFP2(MachineBasicBlock::iterator &MBBI, + unsigned Opc) { + MachineInstr &MI = *MBBI; + MachineBasicBlock &MBB = *MI.getParent(); + MachineInstrBuilder MIB = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(Opc)); + MIB.addOperand(MI.getOperand(0)) // destination register + .addOperand(MI.getOperand(1)) // source register + .addOperand(MI.getOperand(2)) // predicate + .addOperand(MI.getOperand(3)); // predicate register + TransferImpOps(MI, MIB, MIB); + MI.eraseFromParent(); +} + bool ARMExpandPseudo::ExpandMBB(MachineBasicBlock &MBB) { bool Modified = false; @@ -1145,18 +1161,19 @@ ExpandLaneOp(MBBI); break; - case ARM::VTBL2Pseudo: - ExpandVTBL(MBBI, ARM::VTBL2, false, 2); break; - case ARM::VTBL3Pseudo: - ExpandVTBL(MBBI, ARM::VTBL3, false, 3); break; - case ARM::VTBL4Pseudo: - ExpandVTBL(MBBI, ARM::VTBL4, false, 4); break; - case ARM::VTBX2Pseudo: - ExpandVTBL(MBBI, ARM::VTBX2, true, 2); break; - case ARM::VTBX3Pseudo: - ExpandVTBL(MBBI, ARM::VTBX3, true, 3); break; - case ARM::VTBX4Pseudo: - ExpandVTBL(MBBI, ARM::VTBX4, true, 4); break; + case ARM::VTBL2Pseudo: ExpandVTBL(MBBI, ARM::VTBL2, false, 2); break; + case ARM::VTBL3Pseudo: ExpandVTBL(MBBI, ARM::VTBL3, false, 3); break; + case ARM::VTBL4Pseudo: ExpandVTBL(MBBI, ARM::VTBL4, false, 4); break; + case ARM::VTBX2Pseudo: ExpandVTBL(MBBI, ARM::VTBX2, true, 2); break; + case ARM::VTBX3Pseudo: ExpandVTBL(MBBI, ARM::VTBX3, true, 3); break; + case ARM::VTBX4Pseudo: ExpandVTBL(MBBI, ARM::VTBX4, true, 4); break; + + case ARM::VABSfd_sfp: ExpandNeonSFP2(MBBI, ARM::VABSfd); break; + case ARM::VNEGfd_sfp: ExpandNeonSFP2(MBBI, ARM::VNEGfd); break; + case ARM::VCVTf2sd_sfp: ExpandNeonSFP2(MBBI, ARM::VCVTf2sd); break; + case ARM::VCVTf2ud_sfp: ExpandNeonSFP2(MBBI, ARM::VCVTf2ud); break; + case ARM::VCVTs2fd_sfp: ExpandNeonSFP2(MBBI, ARM::VCVTs2fd); break; + case ARM::VCVTu2fd_sfp: ExpandNeonSFP2(MBBI, ARM::VCVTu2fd); break; } if (ModifiedOp) Modified: llvm/trunk/lib/Target/ARM/ARMInstrNEON.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrNEON.td?rev=121716&r1=121715&r2=121716&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrNEON.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrNEON.td Mon Dec 13 15:05:52 2010 @@ -1668,12 +1668,9 @@ //===----------------------------------------------------------------------===// // Basic 2-register operations: single-, double- and quad-register. -class N2VS op24_23, bits<2> op21_20, bits<2> op19_18, - bits<2> op17_16, bits<5> op11_7, bit op4, string OpcodeStr, - string Dt> - : N2V; +let neverHasSideEffects = 1 in +class N2VS + : PseudoNeonI<(outs DPR_VFP2:$Vd), (ins DPR_VFP2:$Vm), IIC_VUNAD, "", []>; class N2VD op24_23, bits<2> op21_20, bits<2> op19_18, bits<2> op17_16, bits<5> op11_7, bit op4, string OpcodeStr, string Dt, ValueType ResTy, ValueType OpTy, SDNode OpNode> @@ -4681,7 +4678,7 @@ // NEON instructions for single-precision FP math //===----------------------------------------------------------------------===// -class N2VSPat +class N2VSPat : NEONFPPat<(ResTy (OpNode SPR:$a)), (EXTRACT_SUBREG (OpTy (Inst (INSERT_SUBREG (OpTy (IMPLICIT_DEF)), SPR:$a, ssub_0))), @@ -4739,17 +4736,11 @@ Requires<[HasNEON, UseNEONForFP, UseFPVMLx]>; // Vector Absolute used for single-precision FP -let neverHasSideEffects = 1 in -def VABSfd_sfp : N2V<0b11, 0b11, 0b10, 0b01, 0b01110, 0, 0, - (outs DPR_VFP2:$Vd), (ins DPR_VFP2:$Vm), IIC_VUNAD, - "vabs", "f32", "$Vd, $Vm", "", []>; +def VABSfd_sfp : N2VS; def : N2VSPat; // Vector Negate used for single-precision FP -let neverHasSideEffects = 1 in -def VNEGfd_sfp : N2V<0b11, 0b11, 0b10, 0b01, 0b01111, 0, 0, - (outs DPR_VFP2:$Vd), (ins DPR_VFP2:$Vm), IIC_VUNAD, - "vneg", "f32", "$Vd, $Vm", "", []>; +def VNEGfd_sfp : N2VS; def : N2VSPat; // Vector Maximum used for single-precision FP @@ -4767,20 +4758,16 @@ def : N3VSPat; // Vector Convert between single-precision FP and integer -let neverHasSideEffects = 1 in -def VCVTf2sd_sfp : N2VS<0b11, 0b11, 0b10, 0b11, 0b01110, 0, "vcvt", "s32.f32">; +def VCVTf2sd_sfp : N2VS; def : N2VSPat; -let neverHasSideEffects = 1 in -def VCVTf2ud_sfp : N2VS<0b11, 0b11, 0b10, 0b11, 0b01111, 0, "vcvt", "u32.f32">; +def VCVTf2ud_sfp : N2VS; def : N2VSPat; -let neverHasSideEffects = 1 in -def VCVTs2fd_sfp : N2VS<0b11, 0b11, 0b10, 0b11, 0b01100, 0, "vcvt", "f32.s32">; +def VCVTs2fd_sfp : N2VS; def : N2VSPat; -let neverHasSideEffects = 1 in -def VCVTu2fd_sfp : N2VS<0b11, 0b11, 0b10, 0b11, 0b01101, 0, "vcvt", "f32.u32">; +def VCVTu2fd_sfp : N2VS; def : N2VSPat; //===----------------------------------------------------------------------===// From sabre at nondot.org Mon Dec 13 15:31:20 2010 From: sabre at nondot.org (Chris Lattner) Date: Mon, 13 Dec 2010 13:31:20 -0800 Subject: [llvm-commits] [llvm] r121675 - /llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp In-Reply-To: <7635E375-1A01-4247-9B3C-85EBC21349EB@apple.com> References: <20101213041519.9DE9B2A6C12C@llvm.org> <7635E375-1A01-4247-9B3C-85EBC21349EB@apple.com> Message-ID: <854385A6-A2BD-4C96-98D5-2EEBBF2F86A6@nondot.org> On Dec 13, 2010, at 12:58 PM, Bill Wendling wrote: >> >> URL: http://llvm.org/viewvc/llvm-project?rev=121675&view=rev >> Log: >> inline a function, making the result much simpler. >> > Chris, > > This doesn't have the same semantics as the original non-inlined version. TrueWhenEqual should be "false" if the dyn_cast fails. Doesn't matter, it isn't used in that case. -Chris -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20101213/65132a29/attachment.html From bob.wilson at apple.com Mon Dec 13 15:58:05 2010 From: bob.wilson at apple.com (Bob Wilson) Date: Mon, 13 Dec 2010 21:58:05 -0000 Subject: [llvm-commits] [llvm] r121718 - in /llvm/trunk/lib/Target/ARM: ARMExpandPseudoInsts.cpp ARMInstrNEON.td Message-ID: <20101213215805.DD3292A6C12C@llvm.org> Author: bwilson Date: Mon Dec 13 15:58:05 2010 New Revision: 121718 URL: http://llvm.org/viewvc/llvm-project?rev=121718&view=rev Log: Use COPY_TO_REGCLASS instead of pseudo instructions for Neon FP patterns. Jakob Olesen suggested that we can avoid the need for separate pseudo instructions here by using COPY_TO_REGCLASS in the patterns. The pattern gets pretty ugly but it seems to work well. Partial fix for Radar 8711675. Modified: llvm/trunk/lib/Target/ARM/ARMExpandPseudoInsts.cpp llvm/trunk/lib/Target/ARM/ARMInstrNEON.td Modified: llvm/trunk/lib/Target/ARM/ARMExpandPseudoInsts.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMExpandPseudoInsts.cpp?rev=121718&r1=121717&r2=121718&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMExpandPseudoInsts.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMExpandPseudoInsts.cpp Mon Dec 13 15:58:05 2010 @@ -54,7 +54,6 @@ void ExpandLaneOp(MachineBasicBlock::iterator &MBBI); void ExpandVTBL(MachineBasicBlock::iterator &MBBI, unsigned Opc, bool IsExt, unsigned NumRegs); - void ExpandNeonSFP2(MachineBasicBlock::iterator &MBBI, unsigned Opc); }; char ARMExpandPseudo::ID = 0; } @@ -613,21 +612,6 @@ MI.eraseFromParent(); } -/// ExpandNeonSFP2 - Translate a 2-register Neon pseudo instruction used for -/// scalar floating-point to a real instruction. -void ARMExpandPseudo::ExpandNeonSFP2(MachineBasicBlock::iterator &MBBI, - unsigned Opc) { - MachineInstr &MI = *MBBI; - MachineBasicBlock &MBB = *MI.getParent(); - MachineInstrBuilder MIB = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(Opc)); - MIB.addOperand(MI.getOperand(0)) // destination register - .addOperand(MI.getOperand(1)) // source register - .addOperand(MI.getOperand(2)) // predicate - .addOperand(MI.getOperand(3)); // predicate register - TransferImpOps(MI, MIB, MIB); - MI.eraseFromParent(); -} - bool ARMExpandPseudo::ExpandMBB(MachineBasicBlock &MBB) { bool Modified = false; @@ -1167,13 +1151,6 @@ case ARM::VTBX2Pseudo: ExpandVTBL(MBBI, ARM::VTBX2, true, 2); break; case ARM::VTBX3Pseudo: ExpandVTBL(MBBI, ARM::VTBX3, true, 3); break; case ARM::VTBX4Pseudo: ExpandVTBL(MBBI, ARM::VTBX4, true, 4); break; - - case ARM::VABSfd_sfp: ExpandNeonSFP2(MBBI, ARM::VABSfd); break; - case ARM::VNEGfd_sfp: ExpandNeonSFP2(MBBI, ARM::VNEGfd); break; - case ARM::VCVTf2sd_sfp: ExpandNeonSFP2(MBBI, ARM::VCVTf2sd); break; - case ARM::VCVTf2ud_sfp: ExpandNeonSFP2(MBBI, ARM::VCVTf2ud); break; - case ARM::VCVTs2fd_sfp: ExpandNeonSFP2(MBBI, ARM::VCVTs2fd); break; - case ARM::VCVTu2fd_sfp: ExpandNeonSFP2(MBBI, ARM::VCVTu2fd); break; } if (ModifiedOp) Modified: llvm/trunk/lib/Target/ARM/ARMInstrNEON.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrNEON.td?rev=121718&r1=121717&r2=121718&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrNEON.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrNEON.td Mon Dec 13 15:58:05 2010 @@ -1669,8 +1669,6 @@ // Basic 2-register operations: single-, double- and quad-register. let neverHasSideEffects = 1 in -class N2VS - : PseudoNeonI<(outs DPR_VFP2:$Vd), (ins DPR_VFP2:$Vm), IIC_VUNAD, "", []>; class N2VD op24_23, bits<2> op21_20, bits<2> op19_18, bits<2> op17_16, bits<5> op11_7, bit op4, string OpcodeStr, string Dt, ValueType ResTy, ValueType OpTy, SDNode OpNode> @@ -4678,11 +4676,14 @@ // NEON instructions for single-precision FP math //===----------------------------------------------------------------------===// -class N2VSPat +class N2VSPat : NEONFPPat<(ResTy (OpNode SPR:$a)), - (EXTRACT_SUBREG (OpTy (Inst (INSERT_SUBREG (OpTy (IMPLICIT_DEF)), - SPR:$a, ssub_0))), - ssub_0)>; + (EXTRACT_SUBREG + (OpTy (COPY_TO_REGCLASS + (OpTy (Inst (INSERT_SUBREG + (OpTy (COPY_TO_REGCLASS (OpTy (IMPLICIT_DEF)), DPR_VFP2)), + SPR:$a, ssub_0))), + DPR_VFP2)), ssub_0)>; class N3VSPat : NEONFPPat<(f32 (OpNode SPR:$a, SPR:$b)), @@ -4736,12 +4737,10 @@ Requires<[HasNEON, UseNEONForFP, UseFPVMLx]>; // Vector Absolute used for single-precision FP -def VABSfd_sfp : N2VS; -def : N2VSPat; +def : N2VSPat; // Vector Negate used for single-precision FP -def VNEGfd_sfp : N2VS; -def : N2VSPat; +def : N2VSPat; // Vector Maximum used for single-precision FP let neverHasSideEffects = 1 in @@ -4758,17 +4757,10 @@ def : N3VSPat; // Vector Convert between single-precision FP and integer -def VCVTf2sd_sfp : N2VS; -def : N2VSPat; - -def VCVTf2ud_sfp : N2VS; -def : N2VSPat; - -def VCVTs2fd_sfp : N2VS; -def : N2VSPat; - -def VCVTu2fd_sfp : N2VS; -def : N2VSPat; +def : N2VSPat; +def : N2VSPat; +def : N2VSPat; +def : N2VSPat; //===----------------------------------------------------------------------===// // Non-Instruction Patterns From bob.wilson at apple.com Mon Dec 13 16:05:55 2010 From: bob.wilson at apple.com (Bob Wilson) Date: Mon, 13 Dec 2010 22:05:55 -0000 Subject: [llvm-commits] [llvm] r121719 - /llvm/trunk/lib/Target/ARM/ARMInstrNEON.td Message-ID: <20101213220555.703ED2A6C12E@llvm.org> Author: bwilson Date: Mon Dec 13 16:05:55 2010 New Revision: 121719 URL: http://llvm.org/viewvc/llvm-project?rev=121719&view=rev Log: Delete a line that I forgot to revert previously. Modified: llvm/trunk/lib/Target/ARM/ARMInstrNEON.td Modified: llvm/trunk/lib/Target/ARM/ARMInstrNEON.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrNEON.td?rev=121719&r1=121718&r2=121719&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrNEON.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrNEON.td Mon Dec 13 16:05:55 2010 @@ -1668,7 +1668,6 @@ //===----------------------------------------------------------------------===// // Basic 2-register operations: single-, double- and quad-register. -let neverHasSideEffects = 1 in class N2VD op24_23, bits<2> op21_20, bits<2> op19_18, bits<2> op17_16, bits<5> op11_7, bit op4, string OpcodeStr, string Dt, ValueType ResTy, ValueType OpTy, SDNode OpNode> From resistor at mac.com Mon Dec 13 16:29:52 2010 From: resistor at mac.com (Owen Anderson) Date: Mon, 13 Dec 2010 22:29:52 -0000 Subject: [llvm-commits] [llvm] r121721 - in /llvm/trunk: lib/Target/ARM/ARMAsmBackend.cpp lib/Target/ARM/ARMCodeEmitter.cpp lib/Target/ARM/ARMConstantIslandPass.cpp lib/Target/ARM/ARMExpandPseudoInsts.cpp lib/Target/ARM/ARMFixupKinds.h lib/Target/ARM/ARMInstrThumb2.td lib/Target/ARM/ARMMCCodeEmitter.cpp utils/TableGen/EDEmitter.cpp Message-ID: <20101213222952.D813F2A6C12C@llvm.org> Author: resistor Date: Mon Dec 13 16:29:52 2010 New Revision: 121721 URL: http://llvm.org/viewvc/llvm-project?rev=121721&view=rev Log: Make Thumb2 LEA-like instruction into pseudos, which map down to ADR. Provide correct fixups for Thumb2 ADR, which is _of course_ different from ARM ADR fixups, or any other Thumb2 fixup. Modified: llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp llvm/trunk/lib/Target/ARM/ARMExpandPseudoInsts.cpp llvm/trunk/lib/Target/ARM/ARMFixupKinds.h llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp llvm/trunk/utils/TableGen/EDEmitter.cpp Modified: llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp?rev=121721&r1=121720&r2=121721&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp Mon Dec 13 16:29:52 2010 @@ -136,6 +136,25 @@ // Encode the immediate and shift the opcode into place. return ARM_AM::getSOImmVal(Value) | (opc << 21); } + + case ARM::fixup_t2_adr_pcrel_12: { + Value -= 4; + unsigned opc = 0; + if ((int64_t)Value < 0) { + Value = -Value; + opc = 5; + } + + uint32_t out = (opc << 21); + out |= (Value & 0x800) << 14; + out |= (Value & 0x700) << 4; + out |= (Value & 0x0FF); + + uint64_t swapped = (out & 0xFFFF0000) >> 16; + swapped |= (out & 0x0000FFFF) << 16; + return swapped; + } + case ARM::fixup_arm_branch: // These values don't encode the low two bits since they're always zero. // Offset by 8 just as above. @@ -356,6 +375,7 @@ case ARM::fixup_t2_condbranch: case ARM::fixup_t2_uncondbranch: case ARM::fixup_t2_pcrel_10: + case ARM::fixup_t2_adr_pcrel_12: case ARM::fixup_arm_thumb_bl: case ARM::fixup_arm_thumb_blx: return 4; Modified: llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp?rev=121721&r1=121720&r2=121721&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp Mon Dec 13 16:29:52 2010 @@ -213,6 +213,8 @@ const { return 0; } unsigned getImmMinusOneOpValue(const MachineInstr &MI, unsigned Op) const { return 0; } + unsigned getT2AdrLabelOpValue(const MachineInstr &MI, unsigned Op) + const { return 0; } unsigned getAddrMode6AddressOpValue(const MachineInstr &MI, unsigned Op) const { return 0; } unsigned getAddrMode6DupAddressOpValue(const MachineInstr &MI, unsigned Op) Modified: llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp?rev=121721&r1=121720&r2=121721&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp Mon Dec 13 16:29:52 2010 @@ -594,7 +594,7 @@ NegOk = true; IsSoImm = true; break; - case ARM::t2LEApcrel: + case ARM::t2ADR: Bits = 12; NegOk = true; break; @@ -1555,7 +1555,7 @@ unsigned Bits = 0; switch (Opcode) { default: break; - case ARM::t2LEApcrel: + case ARM::t2ADR: if (isARMLowRegister(U.MI->getOperand(0).getReg())) { NewOpc = ARM::tLEApcrel; Bits = 8; @@ -1754,16 +1754,16 @@ if (!OptOk) continue; - // Now scan back again to find the tLEApcrel or t2LEApcrelJT instruction + // Now scan back again to find the tLEApcrel or t2ADR instruction // that gave us the initial base register definition. for (--PrevI; PrevI != B && !PrevI->definesRegister(BaseReg); --PrevI) ; - // The instruction should be a tLEApcrel or t2LEApcrelJT; we want + // The instruction should be a tLEApcrel or t2ADR; we want // to delete it as well. MachineInstr *LeaMI = PrevI; if ((LeaMI->getOpcode() != ARM::tLEApcrelJT && - LeaMI->getOpcode() != ARM::t2LEApcrelJT) || + LeaMI->getOpcode() != ARM::t2ADR) || LeaMI->getOperand(0).getReg() != BaseReg) OptOk = false; Modified: llvm/trunk/lib/Target/ARM/ARMExpandPseudoInsts.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMExpandPseudoInsts.cpp?rev=121721&r1=121720&r2=121721&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMExpandPseudoInsts.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMExpandPseudoInsts.cpp Mon Dec 13 16:29:52 2010 @@ -763,6 +763,21 @@ break; } + case ARM::t2LEApcrel: + case ARM::t2LEApcrelJT: { + bool DstIsDead = MI.getOperand(0).isDead(); + MachineInstrBuilder MIB = BuildMI(MBB, MBBI, MI.getDebugLoc(), + TII->get(ARM::t2ADR)) + .addReg(MI.getOperand(0).getReg(), + RegState::Define | getDeadRegState(DstIsDead)) // Dst reg + .addOperand(MI.getOperand(1)) // Label + .addOperand(MI.getOperand(2)) // Pred + .addOperand(MI.getOperand(3)); + TransferImpOps(MI, MIB, MIB); + MI.eraseFromParent(); + return MIB; + } + case ARM::MOVi32imm: case ARM::MOVCCi32imm: case ARM::t2MOVi32imm: Modified: llvm/trunk/lib/Target/ARM/ARMFixupKinds.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMFixupKinds.h?rev=121721&r1=121720&r2=121721&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMFixupKinds.h (original) +++ llvm/trunk/lib/Target/ARM/ARMFixupKinds.h Mon Dec 13 16:29:52 2010 @@ -33,6 +33,9 @@ // fixup_arm_adr_pcrel_12 - 12-bit PC relative relocation for the ADR // instruction. fixup_arm_adr_pcrel_12, + // fixup_t2_adr_pcrel_12 - 12-bit PC relative relocation for the ADR + // instruction. + fixup_t2_adr_pcrel_12, // fixup_arm_branch - 24-bit PC relative relocation for direct branch // instructions. fixup_arm_branch, Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td?rev=121721&r1=121720&r2=121721&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td Mon Dec 13 16:29:52 2010 @@ -131,6 +131,12 @@ let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm); } +// ADR instruction labels. +def t2adrlabel : Operand { + let EncoderMethod = "getT2AdrLabelOpValue"; +} + + // t2addrmode_imm8 := reg +/- imm8 def t2addrmode_imm8 : Operand, ComplexPattern { @@ -1128,10 +1134,11 @@ // LEApcrel - Load a pc-relative address into a register without offending the // assembler. -let neverHasSideEffects = 1 in { -let isReMaterializable = 1 in -def t2LEApcrel : T2PCOneRegImm<(outs rGPR:$Rd), (ins i32imm:$label, pred:$p), IIC_iALUi, - "adr${p}.w\t$Rd, #$label", []> { +let neverHasSideEffects = 1, isReMaterializable = 1 in { + +def t2ADR : T2PCOneRegImm<(outs rGPR:$Rd), + (ins t2adrlabel:$addr, pred:$p), + IIC_iALUi, "adr{$p}.w\t$Rd, #$addr", []> { let Inst{31-27} = 0b11110; let Inst{25-24} = 0b10; // Inst{23:21} = '11' (add = FALSE) or '00' (add = TRUE) @@ -1139,20 +1146,22 @@ let Inst{20} = 0; let Inst{19-16} = 0b1111; // Rn let Inst{15} = 0; - - + + bits<4> Rd; + bits<13> addr; + let Inst{11-8} = Rd; + let Inst{23} = addr{12}; + let Inst{21} = addr{12}; + let Inst{26} = addr{11}; + let Inst{14-12} = addr{10-8}; + let Inst{7-0} = addr{7-0}; } -} // neverHasSideEffects -def t2LEApcrelJT : T2PCOneRegImm<(outs rGPR:$Rd), + +def t2LEApcrel : PseudoInst<(outs rGPR:$Rd), (ins i32imm:$label, pred:$p), + IIC_iALUi, []>; +def t2LEApcrelJT : PseudoInst<(outs rGPR:$Rd), (ins i32imm:$label, nohash_imm:$id, pred:$p), IIC_iALUi, - "adr${p}.w\t$Rd, #${label}_${id}", []> { - let Inst{31-27} = 0b11110; - let Inst{25-24} = 0b10; - // Inst{23:21} = '11' (add = FALSE) or '00' (add = TRUE) - let Inst{22} = 0; - let Inst{20} = 0; - let Inst{19-16} = 0b1111; // Rn - let Inst{15} = 0; + []>; } Modified: llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp?rev=121721&r1=121720&r2=121721&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp Mon Dec 13 16:29:52 2010 @@ -56,6 +56,8 @@ { "fixup_t2_pcrel_10", 0, 32, MCFixupKindInfo::FKF_IsPCRel | MCFixupKindInfo::FKF_IsAligned}, { "fixup_arm_adr_pcrel_12", 1, 24, MCFixupKindInfo::FKF_IsPCRel }, +{ "fixup_t2_adr_pcrel_12", 0, 32, MCFixupKindInfo::FKF_IsPCRel | + MCFixupKindInfo::FKF_IsAligned}, { "fixup_arm_branch", 1, 24, MCFixupKindInfo::FKF_IsPCRel }, { "fixup_t2_condbranch", 0, 32, MCFixupKindInfo::FKF_IsPCRel }, { "fixup_t2_uncondbranch", 0, 32, MCFixupKindInfo::FKF_IsPCRel }, @@ -133,6 +135,9 @@ /// ADR label target. uint32_t getAdrLabelOpValue(const MCInst &MI, unsigned OpIdx, SmallVectorImpl &Fixups) const; + uint32_t getT2AdrLabelOpValue(const MCInst &MI, unsigned OpIdx, + SmallVectorImpl &Fixups) const; + /// getAddrModeImm12OpValue - Return encoding info for 'reg +/- imm12' /// operand. @@ -544,6 +549,16 @@ Fixups); } +/// getAdrLabelOpValue - Return encoding info for 12-bit immediate ADR label +/// target. +uint32_t ARMMCCodeEmitter:: +getT2AdrLabelOpValue(const MCInst &MI, unsigned OpIdx, + SmallVectorImpl &Fixups) const { + assert(MI.getOperand(OpIdx).isExpr() && "Unexpected adr target type!"); + return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_adr_pcrel_12, + Fixups); +} + /// getTAddrModeRegRegOpValue - Return encoding info for 'reg + reg' operand. uint32_t ARMMCCodeEmitter:: getTAddrModeRegRegOpValue(const MCInst &MI, unsigned OpIdx, Modified: llvm/trunk/utils/TableGen/EDEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/EDEmitter.cpp?rev=121721&r1=121720&r2=121721&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/EDEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/EDEmitter.cpp Mon Dec 13 16:29:52 2010 @@ -584,6 +584,7 @@ IMM("t_imm_s4"); IMM("pclabel"); IMM("adrlabel"); + IMM("t2adrlabel"); IMM("shift_imm"); IMM("neon_vcvt_imm32"); From gohman at apple.com Mon Dec 13 16:47:57 2010 From: gohman at apple.com (Dan Gohman) Date: Mon, 13 Dec 2010 22:47:57 -0000 Subject: [llvm-commits] [llvm] r121723 - /llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Message-ID: <20101213224757.374D82A6C12C@llvm.org> Author: djg Date: Mon Dec 13 16:47:57 2010 New Revision: 121723 URL: http://llvm.org/viewvc/llvm-project?rev=121723&view=rev Log: Update memdep to handle PartialAlias as MayAlias. Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp?rev=121723&r1=121722&r2=121723&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp (original) +++ llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Mon Dec 13 16:47:57 2010 @@ -291,7 +291,7 @@ continue; // May-alias loads don't depend on each other without a dependence. - if (isLoad && R == AliasAnalysis::MayAlias) + if (isLoad && R != AliasAnalysis::MustAlias) continue; // Stores don't alias loads from read-only memory. @@ -323,9 +323,9 @@ if (R == AliasAnalysis::NoAlias) continue; - if (R == AliasAnalysis::MayAlias) - return MemDepResult::getClobber(Inst); - return MemDepResult::getDef(Inst); + if (R == AliasAnalysis::MustAlias) + return MemDepResult::getDef(Inst); + return MemDepResult::getClobber(Inst); } // If this is an allocation, and if we know that the accessed pointer is to From gohman at apple.com Mon Dec 13 16:50:24 2010 From: gohman at apple.com (Dan Gohman) Date: Mon, 13 Dec 2010 22:50:24 -0000 Subject: [llvm-commits] [llvm] r121725 - in /llvm/trunk: lib/Analysis/BasicAliasAnalysis.cpp test/Analysis/TypeBasedAliasAnalysis/precedence.ll Message-ID: <20101213225024.5F8072A6C12C@llvm.org> Author: djg Date: Mon Dec 13 16:50:24 2010 New Revision: 121725 URL: http://llvm.org/viewvc/llvm-project?rev=121725&view=rev Log: Reapply r121520, PartialAlias implementation for BasicAA, now that memdep is updated to handle it. Modified: llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp llvm/trunk/test/Analysis/TypeBasedAliasAnalysis/precedence.ll Modified: llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp?rev=121725&r1=121724&r2=121725&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp (original) +++ llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp Mon Dec 13 16:50:24 2010 @@ -857,6 +857,17 @@ if (GEP1BaseOffset == 0 && GEP1VariableIndices.empty()) return MustAlias; + // If there is a difference betwen the pointers, but the difference is + // less than the size of the associated memory object, then we know + // that the objects are partially overlapping. + if (GEP1BaseOffset != 0 && GEP1VariableIndices.empty()) { + if (GEP1BaseOffset >= 0 ? + (V2Size != UnknownSize && (uint64_t)GEP1BaseOffset < V2Size) : + (V1Size != UnknownSize && -(uint64_t)GEP1BaseOffset < V1Size && + GEP1BaseOffset != INT64_MIN)) + return PartialAlias; + } + // If we have a known constant offset, see if this offset is larger than the // access size being queried. If so, and if no variable indices can remove // pieces of this constant, then we know we have a no-alias. For example, Modified: llvm/trunk/test/Analysis/TypeBasedAliasAnalysis/precedence.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/TypeBasedAliasAnalysis/precedence.ll?rev=121725&r1=121724&r2=121725&view=diff ============================================================================== --- llvm/trunk/test/Analysis/TypeBasedAliasAnalysis/precedence.ll (original) +++ llvm/trunk/test/Analysis/TypeBasedAliasAnalysis/precedence.ll Mon Dec 13 16:50:24 2010 @@ -1,5 +1,5 @@ -; RUN: opt -enable-tbaa -basicaa -tbaa -gvn -instcombine -S < %s | grep {ret i32 0} -; RUN: opt -enable-tbaa -tbaa -basicaa -gvn -instcombine -S < %s | grep {ret i32 1075000115} +; RUN: opt -enable-tbaa -basicaa -tbaa -gvn -instcombine -S < %s | FileCheck %s --check-prefix=TBAA +; RUN: opt -enable-tbaa -tbaa -basicaa -gvn -instcombine -S < %s | FileCheck %s --check-prefix=BASICAA ; According to the TBAA metadata the load and store don't alias. However, ; according to the actual code, they do. The order of the alias analysis @@ -7,6 +7,12 @@ target datalayout = "e-p:64:64:64" +; Test for simple MustAlias aliasing. + +; TBAA: @trouble +; TBAA: ret i32 0 +; BASICAA: @trouble +; BASICAA: ret i32 1075000115 define i32 @trouble(i32* %x) nounwind { entry: store i32 0, i32* %x, !tbaa !0 @@ -16,6 +22,25 @@ ret i32 %tmp3 } +; Test for PartialAlias aliasing. GVN doesn't yet eliminate the load +; in the BasicAA case. + +; TBAA: @offset +; TBAA: ret i64 0 +; BASICAA: @offset +; BASICAA: ret i64 %tmp3 +define i64 @offset(i64* %x) nounwind { +entry: + store i64 0, i64* %x, !tbaa !4 + %0 = bitcast i64* %x to i8* + %1 = getelementptr i8* %0, i64 1 + store i8 1, i8* %1, !tbaa !5 + %tmp3 = load i64* %x, !tbaa !4 + ret i64 %tmp3 +} + !0 = metadata !{metadata !"int", metadata !1} !1 = metadata !{metadata !"simple"} !3 = metadata !{metadata !"float", metadata !1} +!4 = metadata !{metadata !"long", metadata !1} +!5 = metadata !{metadata !"small", metadata !1} From resistor at mac.com Mon Dec 13 16:51:08 2010 From: resistor at mac.com (Owen Anderson) Date: Mon, 13 Dec 2010 22:51:08 -0000 Subject: [llvm-commits] [llvm] r121726 - in /llvm/trunk: lib/Target/ARM/ARMAsmBackend.cpp lib/Target/ARM/ARMCodeEmitter.cpp lib/Target/ARM/ARMConstantIslandPass.cpp lib/Target/ARM/ARMExpandPseudoInsts.cpp lib/Target/ARM/ARMFixupKinds.h lib/Target/ARM/ARMInstrThumb2.td lib/Target/ARM/ARMMCCodeEmitter.cpp utils/TableGen/EDEmitter.cpp Message-ID: <20101213225108.C82E02A6C12C@llvm.org> Author: resistor Date: Mon Dec 13 16:51:08 2010 New Revision: 121726 URL: http://llvm.org/viewvc/llvm-project?rev=121726&view=rev Log: Revert r121721, which broke buildbots. Modified: llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp llvm/trunk/lib/Target/ARM/ARMExpandPseudoInsts.cpp llvm/trunk/lib/Target/ARM/ARMFixupKinds.h llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp llvm/trunk/utils/TableGen/EDEmitter.cpp Modified: llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp?rev=121726&r1=121725&r2=121726&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp Mon Dec 13 16:51:08 2010 @@ -136,25 +136,6 @@ // Encode the immediate and shift the opcode into place. return ARM_AM::getSOImmVal(Value) | (opc << 21); } - - case ARM::fixup_t2_adr_pcrel_12: { - Value -= 4; - unsigned opc = 0; - if ((int64_t)Value < 0) { - Value = -Value; - opc = 5; - } - - uint32_t out = (opc << 21); - out |= (Value & 0x800) << 14; - out |= (Value & 0x700) << 4; - out |= (Value & 0x0FF); - - uint64_t swapped = (out & 0xFFFF0000) >> 16; - swapped |= (out & 0x0000FFFF) << 16; - return swapped; - } - case ARM::fixup_arm_branch: // These values don't encode the low two bits since they're always zero. // Offset by 8 just as above. @@ -375,7 +356,6 @@ case ARM::fixup_t2_condbranch: case ARM::fixup_t2_uncondbranch: case ARM::fixup_t2_pcrel_10: - case ARM::fixup_t2_adr_pcrel_12: case ARM::fixup_arm_thumb_bl: case ARM::fixup_arm_thumb_blx: return 4; Modified: llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp?rev=121726&r1=121725&r2=121726&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp Mon Dec 13 16:51:08 2010 @@ -213,8 +213,6 @@ const { return 0; } unsigned getImmMinusOneOpValue(const MachineInstr &MI, unsigned Op) const { return 0; } - unsigned getT2AdrLabelOpValue(const MachineInstr &MI, unsigned Op) - const { return 0; } unsigned getAddrMode6AddressOpValue(const MachineInstr &MI, unsigned Op) const { return 0; } unsigned getAddrMode6DupAddressOpValue(const MachineInstr &MI, unsigned Op) Modified: llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp?rev=121726&r1=121725&r2=121726&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp Mon Dec 13 16:51:08 2010 @@ -594,7 +594,7 @@ NegOk = true; IsSoImm = true; break; - case ARM::t2ADR: + case ARM::t2LEApcrel: Bits = 12; NegOk = true; break; @@ -1555,7 +1555,7 @@ unsigned Bits = 0; switch (Opcode) { default: break; - case ARM::t2ADR: + case ARM::t2LEApcrel: if (isARMLowRegister(U.MI->getOperand(0).getReg())) { NewOpc = ARM::tLEApcrel; Bits = 8; @@ -1754,16 +1754,16 @@ if (!OptOk) continue; - // Now scan back again to find the tLEApcrel or t2ADR instruction + // Now scan back again to find the tLEApcrel or t2LEApcrelJT instruction // that gave us the initial base register definition. for (--PrevI; PrevI != B && !PrevI->definesRegister(BaseReg); --PrevI) ; - // The instruction should be a tLEApcrel or t2ADR; we want + // The instruction should be a tLEApcrel or t2LEApcrelJT; we want // to delete it as well. MachineInstr *LeaMI = PrevI; if ((LeaMI->getOpcode() != ARM::tLEApcrelJT && - LeaMI->getOpcode() != ARM::t2ADR) || + LeaMI->getOpcode() != ARM::t2LEApcrelJT) || LeaMI->getOperand(0).getReg() != BaseReg) OptOk = false; Modified: llvm/trunk/lib/Target/ARM/ARMExpandPseudoInsts.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMExpandPseudoInsts.cpp?rev=121726&r1=121725&r2=121726&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMExpandPseudoInsts.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMExpandPseudoInsts.cpp Mon Dec 13 16:51:08 2010 @@ -763,21 +763,6 @@ break; } - case ARM::t2LEApcrel: - case ARM::t2LEApcrelJT: { - bool DstIsDead = MI.getOperand(0).isDead(); - MachineInstrBuilder MIB = BuildMI(MBB, MBBI, MI.getDebugLoc(), - TII->get(ARM::t2ADR)) - .addReg(MI.getOperand(0).getReg(), - RegState::Define | getDeadRegState(DstIsDead)) // Dst reg - .addOperand(MI.getOperand(1)) // Label - .addOperand(MI.getOperand(2)) // Pred - .addOperand(MI.getOperand(3)); - TransferImpOps(MI, MIB, MIB); - MI.eraseFromParent(); - return MIB; - } - case ARM::MOVi32imm: case ARM::MOVCCi32imm: case ARM::t2MOVi32imm: Modified: llvm/trunk/lib/Target/ARM/ARMFixupKinds.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMFixupKinds.h?rev=121726&r1=121725&r2=121726&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMFixupKinds.h (original) +++ llvm/trunk/lib/Target/ARM/ARMFixupKinds.h Mon Dec 13 16:51:08 2010 @@ -33,9 +33,6 @@ // fixup_arm_adr_pcrel_12 - 12-bit PC relative relocation for the ADR // instruction. fixup_arm_adr_pcrel_12, - // fixup_t2_adr_pcrel_12 - 12-bit PC relative relocation for the ADR - // instruction. - fixup_t2_adr_pcrel_12, // fixup_arm_branch - 24-bit PC relative relocation for direct branch // instructions. fixup_arm_branch, Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td?rev=121726&r1=121725&r2=121726&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td Mon Dec 13 16:51:08 2010 @@ -131,12 +131,6 @@ let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm); } -// ADR instruction labels. -def t2adrlabel : Operand { - let EncoderMethod = "getT2AdrLabelOpValue"; -} - - // t2addrmode_imm8 := reg +/- imm8 def t2addrmode_imm8 : Operand, ComplexPattern { @@ -1134,11 +1128,10 @@ // LEApcrel - Load a pc-relative address into a register without offending the // assembler. -let neverHasSideEffects = 1, isReMaterializable = 1 in { - -def t2ADR : T2PCOneRegImm<(outs rGPR:$Rd), - (ins t2adrlabel:$addr, pred:$p), - IIC_iALUi, "adr{$p}.w\t$Rd, #$addr", []> { +let neverHasSideEffects = 1 in { +let isReMaterializable = 1 in +def t2LEApcrel : T2PCOneRegImm<(outs rGPR:$Rd), (ins i32imm:$label, pred:$p), IIC_iALUi, + "adr${p}.w\t$Rd, #$label", []> { let Inst{31-27} = 0b11110; let Inst{25-24} = 0b10; // Inst{23:21} = '11' (add = FALSE) or '00' (add = TRUE) @@ -1146,22 +1139,20 @@ let Inst{20} = 0; let Inst{19-16} = 0b1111; // Rn let Inst{15} = 0; - - bits<4> Rd; - bits<13> addr; - let Inst{11-8} = Rd; - let Inst{23} = addr{12}; - let Inst{21} = addr{12}; - let Inst{26} = addr{11}; - let Inst{14-12} = addr{10-8}; - let Inst{7-0} = addr{7-0}; -} -def t2LEApcrel : PseudoInst<(outs rGPR:$Rd), (ins i32imm:$label, pred:$p), - IIC_iALUi, []>; -def t2LEApcrelJT : PseudoInst<(outs rGPR:$Rd), + +} +} // neverHasSideEffects +def t2LEApcrelJT : T2PCOneRegImm<(outs rGPR:$Rd), (ins i32imm:$label, nohash_imm:$id, pred:$p), IIC_iALUi, - []>; + "adr${p}.w\t$Rd, #${label}_${id}", []> { + let Inst{31-27} = 0b11110; + let Inst{25-24} = 0b10; + // Inst{23:21} = '11' (add = FALSE) or '00' (add = TRUE) + let Inst{22} = 0; + let Inst{20} = 0; + let Inst{19-16} = 0b1111; // Rn + let Inst{15} = 0; } Modified: llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp?rev=121726&r1=121725&r2=121726&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp Mon Dec 13 16:51:08 2010 @@ -56,8 +56,6 @@ { "fixup_t2_pcrel_10", 0, 32, MCFixupKindInfo::FKF_IsPCRel | MCFixupKindInfo::FKF_IsAligned}, { "fixup_arm_adr_pcrel_12", 1, 24, MCFixupKindInfo::FKF_IsPCRel }, -{ "fixup_t2_adr_pcrel_12", 0, 32, MCFixupKindInfo::FKF_IsPCRel | - MCFixupKindInfo::FKF_IsAligned}, { "fixup_arm_branch", 1, 24, MCFixupKindInfo::FKF_IsPCRel }, { "fixup_t2_condbranch", 0, 32, MCFixupKindInfo::FKF_IsPCRel }, { "fixup_t2_uncondbranch", 0, 32, MCFixupKindInfo::FKF_IsPCRel }, @@ -135,9 +133,6 @@ /// ADR label target. uint32_t getAdrLabelOpValue(const MCInst &MI, unsigned OpIdx, SmallVectorImpl &Fixups) const; - uint32_t getT2AdrLabelOpValue(const MCInst &MI, unsigned OpIdx, - SmallVectorImpl &Fixups) const; - /// getAddrModeImm12OpValue - Return encoding info for 'reg +/- imm12' /// operand. @@ -549,16 +544,6 @@ Fixups); } -/// getAdrLabelOpValue - Return encoding info for 12-bit immediate ADR label -/// target. -uint32_t ARMMCCodeEmitter:: -getT2AdrLabelOpValue(const MCInst &MI, unsigned OpIdx, - SmallVectorImpl &Fixups) const { - assert(MI.getOperand(OpIdx).isExpr() && "Unexpected adr target type!"); - return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_adr_pcrel_12, - Fixups); -} - /// getTAddrModeRegRegOpValue - Return encoding info for 'reg + reg' operand. uint32_t ARMMCCodeEmitter:: getTAddrModeRegRegOpValue(const MCInst &MI, unsigned OpIdx, Modified: llvm/trunk/utils/TableGen/EDEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/EDEmitter.cpp?rev=121726&r1=121725&r2=121726&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/EDEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/EDEmitter.cpp Mon Dec 13 16:51:08 2010 @@ -584,7 +584,6 @@ IMM("t_imm_s4"); IMM("pclabel"); IMM("adrlabel"); - IMM("t2adrlabel"); IMM("shift_imm"); IMM("neon_vcvt_imm32"); From jasonwkim at google.com Mon Dec 13 16:53:55 2010 From: jasonwkim at google.com (Jason Kim) Date: Mon, 13 Dec 2010 14:53:55 -0800 Subject: [llvm-commits] llvm tree busted as of -r121721. Message-ID: ARM tests are failing :( Help! LLVM :: CodeGen/ARM/2009-08-29-TooLongSplat.ll LLVM :: CodeGen/Thumb2/2010-04-26-CopyRegCrash.ll LLVM :: CodeGen/Thumb2/2010-06-14-NEONCoalescer.ll LLVM :: CodeGen/Thumb2/buildvector-crash.ll LLVM :: CodeGen/Thumb2/thumb2-jtb.ll LLVM :: CodeGen/Thumb2/thumb2-tbb.ll LLVM :: CodeGen/Thumb2/thumb2-tbh.ll Thanks! -jason From gohman at apple.com Mon Dec 13 16:53:18 2010 From: gohman at apple.com (Dan Gohman) Date: Mon, 13 Dec 2010 22:53:18 -0000 Subject: [llvm-commits] [llvm] r121727 - /llvm/trunk/lib/Analysis/Lint.cpp Message-ID: <20101213225318.B6D712A6C12C@llvm.org> Author: djg Date: Mon Dec 13 16:53:18 2010 New Revision: 121727 URL: http://llvm.org/viewvc/llvm-project?rev=121727&view=rev Log: Update a comment. Modified: llvm/trunk/lib/Analysis/Lint.cpp Modified: llvm/trunk/lib/Analysis/Lint.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/Lint.cpp?rev=121727&r1=121726&r2=121727&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/Lint.cpp (original) +++ llvm/trunk/lib/Analysis/Lint.cpp Mon Dec 13 16:53:18 2010 @@ -226,10 +226,9 @@ "Undefined behavior: Call argument type mismatches " "callee parameter type", &I); - // Check that noalias arguments don't alias other arguments. The - // AliasAnalysis API isn't expressive enough for what we really want - // to do. Known partial overlap is not distinguished from the case - // where nothing is known. + // Check that noalias arguments don't alias other arguments. This is + // not fully precise because we don't know the sizes of the dereferenced + // memory regions. if (Formal->hasNoAliasAttr() && Actual->getType()->isPointerTy()) for (CallSite::arg_iterator BI = CS.arg_begin(); BI != AE; ++BI) if (AI != BI && (*BI)->getType()->isPointerTy()) { From sabre at nondot.org Mon Dec 13 17:02:20 2010 From: sabre at nondot.org (Chris Lattner) Date: Mon, 13 Dec 2010 23:02:20 -0000 Subject: [llvm-commits] [llvm] r121728 - in /llvm/trunk: lib/Transforms/Utils/SimplifyCFG.cpp test/Transforms/SimplifyCFG/switch_create.ll Message-ID: <20101213230220.1220D2A6C12C@llvm.org> Author: lattner Date: Mon Dec 13 17:02:19 2010 New Revision: 121728 URL: http://llvm.org/viewvc/llvm-project?rev=121728&view=rev Log: temporarily disable part of my previous patch, which causes an iterator invalidation issue, causing a crash on some versions of perlbmk. Modified: llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp llvm/trunk/test/Transforms/SimplifyCFG/switch_create.ll Modified: llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp?rev=121728&r1=121727&r2=121728&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp Mon Dec 13 17:02:19 2010 @@ -1515,7 +1515,7 @@ AddPredecessorToBlock(FalseDest, PredBlock, BB); PBI->setSuccessor(1, FalseDest); } - return SimplifyCFG(PBI->getParent()) | true; + return SimplifyCFG(BB) | true; } return false; } Modified: llvm/trunk/test/Transforms/SimplifyCFG/switch_create.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimplifyCFG/switch_create.ll?rev=121728&r1=121727&r2=121728&view=diff ============================================================================== --- llvm/trunk/test/Transforms/SimplifyCFG/switch_create.ll (original) +++ llvm/trunk/test/Transforms/SimplifyCFG/switch_create.ll Mon Dec 13 17:02:19 2010 @@ -253,21 +253,21 @@ ret i32 %conv46 ; CHECK: @test9 -; CHECK: %cmp = icmp ult i8 %c, 33 -; CHECK: br i1 %cmp, label %lor.end, label %switch.early.test +; HECK: %cmp = icmp ult i8 %c, 33 +; HECK: br i1 %cmp, label %lor.end, label %switch.early.test -; CHECK: switch.early.test: -; CHECK: switch i8 %c, label %lor.rhs [ -; CHECK: i8 46, label %lor.end -; CHECK: i8 44, label %lor.end -; CHECK: i8 58, label %lor.end -; CHECK: i8 59, label %lor.end -; CHECK: i8 60, label %lor.end -; CHECK: i8 62, label %lor.end -; CHECK: i8 34, label %lor.end -; CHECK: i8 92, label %lor.end -; CHECK: i8 39, label %lor.end -; CHECK: ] +; HECK: switch.early.test: +; HECK: switch i8 %c, label %lor.rhs [ +; HECK: i8 46, label %lor.end +; HECK: i8 44, label %lor.end +; HECK: i8 58, label %lor.end +; HECK: i8 59, label %lor.end +; HECK: i8 60, label %lor.end +; HECK: i8 62, label %lor.end +; HECK: i8 34, label %lor.end +; HECK: i8 92, label %lor.end +; HECK: i8 39, label %lor.end +; HECK: ] } define i32 @test10(i32 %mode, i1 %Cond) { @@ -331,3 +331,24 @@ ; CHECK: i32 4, label %return ; CHECK: ] } + +define void @test12() nounwind { +entry: + br label %bb49.us.us + +bb49.us.us: + %A = icmp eq i32 undef, undef + br i1 %A, label %bb55.us.us, label %malformed + +bb48.us.us: + %B = icmp ugt i32 undef, undef + br i1 %B, label %bb55.us.us, label %bb49.us.us + +bb55.us.us: + br label %bb48.us.us + +malformed: + ret void +; CHECK: @test12 + +} \ No newline at end of file From bob.wilson at apple.com Mon Dec 13 17:02:31 2010 From: bob.wilson at apple.com (Bob Wilson) Date: Mon, 13 Dec 2010 23:02:31 -0000 Subject: [llvm-commits] [llvm] r121729 - /llvm/trunk/lib/Target/ARM/ARMInstrNEON.td Message-ID: <20101213230231.66B232A6C12C@llvm.org> Author: bwilson Date: Mon Dec 13 17:02:31 2010 New Revision: 121729 URL: http://llvm.org/viewvc/llvm-project?rev=121729&view=rev Log: Simplify N2VSPat, removing some unnecessary type arguments. Modified: llvm/trunk/lib/Target/ARM/ARMInstrNEON.td Modified: llvm/trunk/lib/Target/ARM/ARMInstrNEON.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrNEON.td?rev=121729&r1=121728&r2=121729&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrNEON.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrNEON.td Mon Dec 13 17:02:31 2010 @@ -4675,14 +4675,13 @@ // NEON instructions for single-precision FP math //===----------------------------------------------------------------------===// -class N2VSPat - : NEONFPPat<(ResTy (OpNode SPR:$a)), +class N2VSPat + : NEONFPPat<(f32 (OpNode SPR:$a)), (EXTRACT_SUBREG - (OpTy (COPY_TO_REGCLASS - (OpTy (Inst (INSERT_SUBREG - (OpTy (COPY_TO_REGCLASS (OpTy (IMPLICIT_DEF)), DPR_VFP2)), - SPR:$a, ssub_0))), - DPR_VFP2)), ssub_0)>; + (v2f32 (COPY_TO_REGCLASS + (Inst (INSERT_SUBREG + (v2f32 (COPY_TO_REGCLASS (v2f32 (IMPLICIT_DEF)), DPR_VFP2)), + SPR:$a, ssub_0)), DPR_VFP2)), ssub_0)>; class N3VSPat : NEONFPPat<(f32 (OpNode SPR:$a, SPR:$b)), @@ -4736,10 +4735,10 @@ Requires<[HasNEON, UseNEONForFP, UseFPVMLx]>; // Vector Absolute used for single-precision FP -def : N2VSPat; +def : N2VSPat; // Vector Negate used for single-precision FP -def : N2VSPat; +def : N2VSPat; // Vector Maximum used for single-precision FP let neverHasSideEffects = 1 in @@ -4756,10 +4755,10 @@ def : N3VSPat; // Vector Convert between single-precision FP and integer -def : N2VSPat; -def : N2VSPat; -def : N2VSPat; -def : N2VSPat; +def : N2VSPat; +def : N2VSPat; +def : N2VSPat; +def : N2VSPat; //===----------------------------------------------------------------------===// // Non-Instruction Patterns From bob.wilson at apple.com Mon Dec 13 17:02:37 2010 From: bob.wilson at apple.com (Bob Wilson) Date: Mon, 13 Dec 2010 23:02:37 -0000 Subject: [llvm-commits] [llvm] r121730 - in /llvm/trunk: lib/Target/ARM/ARMBaseInstrInfo.cpp lib/Target/ARM/ARMInstrNEON.td test/CodeGen/Thumb2/cross-rc-coalescing-2.ll utils/TableGen/ARMDecoderEmitter.cpp Message-ID: <20101213230237.E81992A6C12D@llvm.org> Author: bwilson Date: Mon Dec 13 17:02:37 2010 New Revision: 121730 URL: http://llvm.org/viewvc/llvm-project?rev=121730&view=rev Log: Remove the rest of the *_sfp Neon instruction patterns. Use the same COPY_TO_REGCLASS approach as for the 2-register *_sfp instructions. This change made a big difference in the code generated for the CodeGen/Thumb2/cross-rc-coalescing-2.ll test: The coalescer is still doing a fine job, but some instructions that were previously moved outside the loop are not moved now. It's using fewer VFP registers now, which is generally a good thing, so I think the estimates for register pressure changed and that affected the LICM behavior. Since that isn't obviously wrong, I've just changed the test file. This completes the work for Radar 8711675. Modified: llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp llvm/trunk/lib/Target/ARM/ARMInstrNEON.td llvm/trunk/test/CodeGen/Thumb2/cross-rc-coalescing-2.ll llvm/trunk/utils/TableGen/ARMDecoderEmitter.cpp Modified: llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp?rev=121730&r1=121729&r2=121730&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp Mon Dec 13 17:02:37 2010 @@ -58,8 +58,6 @@ { ARM::VMLSS, ARM::VMULS, ARM::VSUBS, false, false }, { ARM::VMLAD, ARM::VMULD, ARM::VADDD, false, false }, { ARM::VMLSD, ARM::VMULD, ARM::VSUBD, false, false }, - { ARM::VMLAfd_sfp, ARM::VMULfd_sfp, ARM::VADDfd_sfp, false, false }, - { ARM::VMLSfd_sfp, ARM::VMULfd_sfp, ARM::VSUBfd_sfp, false, false }, { ARM::VNMLAS, ARM::VNMULS, ARM::VSUBS, true, false }, { ARM::VNMLSS, ARM::VMULS, ARM::VSUBS, true, false }, { ARM::VNMLAD, ARM::VNMULD, ARM::VSUBD, true, false }, Modified: llvm/trunk/lib/Target/ARM/ARMInstrNEON.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrNEON.td?rev=121730&r1=121729&r2=121730&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrNEON.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrNEON.td Mon Dec 13 17:02:37 2010 @@ -1667,7 +1667,7 @@ // Instruction Classes //===----------------------------------------------------------------------===// -// Basic 2-register operations: single-, double- and quad-register. +// Basic 2-register operations: double- and quad-register. class N2VD op24_23, bits<2> op21_20, bits<2> op19_18, bits<2> op17_16, bits<5> op11_7, bit op4, string OpcodeStr, string Dt, ValueType ResTy, ValueType OpTy, SDNode OpNode> @@ -1736,13 +1736,7 @@ (ins QPR:$src1, QPR:$src2), itin, OpcodeStr, Dt, "$Vd, $Vm", "$src1 = $Vd, $src2 = $Vm", []>; -// Basic 3-register operations: single-, double- and quad-register. -class N3VS op21_20, bits<4> op11_8, bit op4, - string OpcodeStr, string Dt> - : N3V; - +// Basic 3-register operations: double- and quad-register. class N3VD op21_20, bits<4> op11_8, bit op4, InstrItinClass itin, string OpcodeStr, string Dt, ValueType ResTy, ValueType OpTy, SDNode OpNode, bit Commutable> @@ -1912,13 +1906,7 @@ let isCommutable = 0; } -// Multiply-Add/Sub operations: single-, double- and quad-register. -class N3VSMulOp op21_20, bits<4> op11_8, bit op4, - InstrItinClass itin, string OpcodeStr, string Dt> - : N3V; - +// Multiply-Add/Sub operations: double- and quad-register. class N3VDMulOp op21_20, bits<4> op11_8, bit op4, InstrItinClass itin, string OpcodeStr, string Dt, ValueType Ty, SDPatternOperator MulOp, SDPatternOperator OpNode> @@ -4678,83 +4666,47 @@ class N2VSPat : NEONFPPat<(f32 (OpNode SPR:$a)), (EXTRACT_SUBREG - (v2f32 (COPY_TO_REGCLASS - (Inst (INSERT_SUBREG + (v2f32 (COPY_TO_REGCLASS (Inst + (INSERT_SUBREG (v2f32 (COPY_TO_REGCLASS (v2f32 (IMPLICIT_DEF)), DPR_VFP2)), SPR:$a, ssub_0)), DPR_VFP2)), ssub_0)>; class N3VSPat : NEONFPPat<(f32 (OpNode SPR:$a, SPR:$b)), - (EXTRACT_SUBREG (v2f32 - (Inst (INSERT_SUBREG (v2f32 (IMPLICIT_DEF)), - SPR:$a, ssub_0), - (INSERT_SUBREG (v2f32 (IMPLICIT_DEF)), - SPR:$b, ssub_0))), - ssub_0)>; + (EXTRACT_SUBREG + (v2f32 (COPY_TO_REGCLASS (Inst + (INSERT_SUBREG + (v2f32 (COPY_TO_REGCLASS (v2f32 (IMPLICIT_DEF)), DPR_VFP2)), + SPR:$a, ssub_0), + (INSERT_SUBREG + (v2f32 (COPY_TO_REGCLASS (v2f32 (IMPLICIT_DEF)), DPR_VFP2)), + SPR:$b, ssub_0)), DPR_VFP2)), ssub_0)>; class N3VSMulOpPat : NEONFPPat<(f32 (OpNode SPR:$acc, (f32 (MulNode SPR:$a, SPR:$b)))), - (EXTRACT_SUBREG (Inst (INSERT_SUBREG (v2f32 (IMPLICIT_DEF)), - SPR:$acc, ssub_0), - (INSERT_SUBREG (v2f32 (IMPLICIT_DEF)), - SPR:$a, ssub_0), - (INSERT_SUBREG (v2f32 (IMPLICIT_DEF)), - SPR:$b, ssub_0)), - ssub_0)>; - -// These need separate instructions because they must use DPR_VFP2 register -// class which have SPR sub-registers. - -// Vector Add Operations used for single-precision FP -let neverHasSideEffects = 1 in -def VADDfd_sfp : N3VS<0,0,0b00,0b1101,0, "vadd", "f32">; -def : N3VSPat; - -// Vector Sub Operations used for single-precision FP -let neverHasSideEffects = 1 in -def VSUBfd_sfp : N3VS<0,0,0b10,0b1101,0, "vsub", "f32">; -def : N3VSPat; - -// Vector Multiply Operations used for single-precision FP -let neverHasSideEffects = 1 in -def VMULfd_sfp : N3VS<1,0,0b00,0b1101,1, "vmul", "f32">; -def : N3VSPat; - -// Vector Multiply-Accumulate/Subtract used for single-precision FP -// vml[as].f32 can cause 4-8 cycle stalls in following ASIMD instructions, so -// we want to avoid them for now. e.g., alternating vmla/vadd instructions. - -let neverHasSideEffects = 1 in -def VMLAfd_sfp : N3VSMulOp<0,0,0b00,0b1101,1, IIC_VMACD, "vmla", "f32">; -def : N3VSMulOpPat, - Requires<[HasNEON, UseNEONForFP, UseFPVMLx]>; + (EXTRACT_SUBREG + (v2f32 (COPY_TO_REGCLASS (Inst + (INSERT_SUBREG + (v2f32 (COPY_TO_REGCLASS (v2f32 (IMPLICIT_DEF)), DPR_VFP2)), + SPR:$acc, ssub_0), + (INSERT_SUBREG + (v2f32 (COPY_TO_REGCLASS (v2f32 (IMPLICIT_DEF)), DPR_VFP2)), + SPR:$a, ssub_0), + (INSERT_SUBREG + (v2f32 (COPY_TO_REGCLASS (v2f32 (IMPLICIT_DEF)), DPR_VFP2)), + SPR:$b, ssub_0)), DPR_VFP2)), ssub_0)>; -let neverHasSideEffects = 1 in -def VMLSfd_sfp : N3VSMulOp<0,0,0b10,0b1101,1, IIC_VMACD, "vmls", "f32">; -def : N3VSMulOpPat, +def : N3VSPat; +def : N3VSPat; +def : N3VSPat; +def : N3VSMulOpPat, + Requires<[HasNEON, UseNEONForFP, UseFPVMLx]>; +def : N3VSMulOpPat, Requires<[HasNEON, UseNEONForFP, UseFPVMLx]>; - -// Vector Absolute used for single-precision FP def : N2VSPat; - -// Vector Negate used for single-precision FP def : N2VSPat; - -// Vector Maximum used for single-precision FP -let neverHasSideEffects = 1 in -def VMAXfd_sfp : N3V<0, 0, 0b00, 0b1111, 0, 0, (outs DPR_VFP2:$Vd), - (ins DPR_VFP2:$Vn, DPR_VFP2:$Vm), N3RegFrm, IIC_VBIND, - "vmax", "f32", "$Vd, $Vn, $Vm", "", []>; -def : N3VSPat; - -// Vector Minimum used for single-precision FP -let neverHasSideEffects = 1 in -def VMINfd_sfp : N3V<0, 0, 0b10, 0b1111, 0, 0, (outs DPR_VFP2:$Vd), - (ins DPR_VFP2:$Vn, DPR_VFP2:$Vm), N3RegFrm, IIC_VBIND, - "vmin", "f32", "$Vd, $Vn, $Vm", "", []>; -def : N3VSPat; - -// Vector Convert between single-precision FP and integer +def : N3VSPat; +def : N3VSPat; def : N2VSPat; def : N2VSPat; def : N2VSPat; Modified: llvm/trunk/test/CodeGen/Thumb2/cross-rc-coalescing-2.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Thumb2/cross-rc-coalescing-2.ll?rev=121730&r1=121729&r2=121730&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/Thumb2/cross-rc-coalescing-2.ll (original) +++ llvm/trunk/test/CodeGen/Thumb2/cross-rc-coalescing-2.ll Mon Dec 13 17:02:37 2010 @@ -15,9 +15,6 @@ ; Loop preheader ; CHECK: vmov.f32 -; CHECK: vsub.f32 -; CHECK: vadd.f32 -; CHECK: vmul.f32 bb7: ; preds = %bb9, %bb.nph %s1.02 = phi float [ undef, %bb.nph ], [ %35, %bb9 ] ; [#uses=3] %tmp79 = add i32 undef, undef ; [#uses=1] @@ -73,8 +70,6 @@ br i1 %34, label %bb8, label %bb9 bb9: ; preds = %bb8 -; CHECK: %bb9 -; CHECK: vmov.f32 %35 = fadd float 0.000000e+00, undef ; [#uses=1] br label %bb7 } Modified: llvm/trunk/utils/TableGen/ARMDecoderEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/ARMDecoderEmitter.cpp?rev=121730&r1=121729&r2=121730&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/ARMDecoderEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/ARMDecoderEmitter.cpp Mon Dec 13 17:02:37 2010 @@ -1613,11 +1613,6 @@ Name == "VNEGScc") return false; - // Ignore the *_sfp instructions when decoding. They are used by the - // compiler to implement scalar floating point operations using vector - // operations in order to work around some performance issues. - if (Name.find("_sfp") != std::string::npos) return false; - // LDMIA_RET is a special case of LDM (Load Multiple) where the registers // loaded include the PC, causing a branch to a loaded address. Ignore // the LDMIA_RET instruction when decoding. From jason.w.kim.2009 at gmail.com Mon Dec 13 17:16:07 2010 From: jason.w.kim.2009 at gmail.com (Jason W Kim) Date: Mon, 13 Dec 2010 23:16:07 -0000 Subject: [llvm-commits] [llvm] r121732 - in /llvm/trunk: lib/MC/ELFObjectWriter.cpp test/CodeGen/ARM/2010-12-13-reloc-pic.ll Message-ID: <20101213231607.8D88F2A6C12C@llvm.org> Author: jasonwkim Date: Mon Dec 13 17:16:07 2010 New Revision: 121732 URL: http://llvm.org/viewvc/llvm-project?rev=121732&view=rev Log: First cut of ARM/MC/ELF PIC relocations. Test has fixme, to move to .s -> .o test when AsmParser works better. Added: llvm/trunk/test/CodeGen/ARM/2010-12-13-reloc-pic.ll Modified: llvm/trunk/lib/MC/ELFObjectWriter.cpp Modified: llvm/trunk/lib/MC/ELFObjectWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/ELFObjectWriter.cpp?rev=121732&r1=121731&r2=121732&view=diff ============================================================================== --- llvm/trunk/lib/MC/ELFObjectWriter.cpp (original) +++ llvm/trunk/lib/MC/ELFObjectWriter.cpp Mon Dec 13 17:16:07 2010 @@ -1535,22 +1535,40 @@ unsigned Type = 0; if (IsPCRel) { - switch (Modifier) { - default: assert(0 && "Unimplemented Modifier"); - case MCSymbolRefExpr::VK_None: break; - } switch ((unsigned)Fixup.getKind()) { default: assert(0 && "Unimplemented"); - case ARM::fixup_arm_branch: Type = ELF::R_ARM_CALL; break; + case FK_Data_4: + switch (Modifier) { + default: llvm_unreachable("Unsupported Modifier"); + case MCSymbolRefExpr::VK_None: + Type = ELF::R_ARM_BASE_PREL; break; + case MCSymbolRefExpr::VK_ARM_TLSGD: + assert(0 && "unimplemented"); break; + case MCSymbolRefExpr::VK_ARM_GOTTPOFF: + Type = ELF::R_ARM_TLS_IE32; + } break; + case ARM::fixup_arm_branch: + switch (Modifier) { + case MCSymbolRefExpr::VK_ARM_PLT: + Type = ELF::R_ARM_PLT32; break; + default: + Type = ELF::R_ARM_CALL; break; + } break; } } else { switch ((unsigned)Fixup.getKind()) { default: llvm_unreachable("invalid fixup kind!"); case FK_Data_4: switch (Modifier) { - default: llvm_unreachable("Unsupported Modifier"); + default: llvm_unreachable("Unsupported Modifier"); break; + case MCSymbolRefExpr::VK_ARM_GOT: + Type = ELF::R_ARM_GOT_BREL; break; + case MCSymbolRefExpr::VK_ARM_TLSGD: + Type = ELF::R_ARM_TLS_GD32; break; case MCSymbolRefExpr::VK_ARM_GOTTPOFF: - Type = ELF::R_ARM_TLS_IE32; + Type = ELF::R_ARM_TLS_IE32; break; + case MCSymbolRefExpr::VK_ARM_GOTOFF: + Type = ELF::R_ARM_GOTOFF32; break; } break; case ARM::fixup_arm_ldst_pcrel_12: case ARM::fixup_arm_pcrel_10: Added: 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=121732&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/ARM/2010-12-13-reloc-pic.ll (added) +++ llvm/trunk/test/CodeGen/ARM/2010-12-13-reloc-pic.ll Mon Dec 13 17:16:07 2010 @@ -0,0 +1,100 @@ +; RUN: llc %s -mtriple=armv7-linux-gnueabi -arm-use-movt -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, +;; redo as .s -> .o test once ARM AsmParser is working better + +; ModuleID = 'large2.pnacl.bc' +target triple = "armv7-none-linux-gnueabi" + +%struct._Bigint = type { %struct._Bigint*, i32, i32, i32, i32, [1 x i32] } +%struct.__FILE = type { i8*, i32, i32, i16, i16, %struct.__sbuf, i32, %struct._reent*, i8*, i32 (%struct._reent*, i8*, i8*, i32)*, i32 (%struct._reent*, i8*, i8*, i32)*, i32 (%struct._reent*, i8*, i32, i32)*, i32 (%struct._reent*, i8*)*, %struct.__sbuf, i8*, i32, [3 x i8], [1 x i8], %struct.__sbuf, i32, i32, %struct._flock_t, %struct._mbstate_t, i32 } +%struct.__sbuf = type { i8*, i32 } +%struct.__tm = type { i32, i32, i32, i32, i32, i32, i32, i32, i32 } +%struct._atexit = type { %struct._atexit*, i32, [32 x void ()*], %struct._on_exit_args* } +%struct._flock_t = type { i32, i32, i32, i32, i32 } +%struct._glue = type { %struct._glue*, i32, %struct.__FILE* } +%struct._mbstate_t = type { i32, %union.anon } +%struct._misc_reent = type { i8*, %struct._mbstate_t, %struct._mbstate_t, %struct._mbstate_t, [8 x i8], i32, %struct._mbstate_t, %struct._mbstate_t, %struct._mbstate_t, %struct._mbstate_t, %struct._mbstate_t } +%struct._mprec = type { %struct._Bigint*, i32, %struct._Bigint*, %struct._Bigint** } +%struct._on_exit_args = type { [32 x i8*], [32 x i8*], i32, i32 } +%struct._rand48 = type { [3 x i16], [3 x i16], i16, i64 } +%struct._reent = type { %struct.__FILE*, %struct.__FILE*, %struct.__FILE*, i32, i32, i8*, i32, i32, i8*, %struct._mprec*, void (%struct._reent*)*, i32, i32, i8*, %struct._rand48*, %struct.__tm*, i8*, void (i32)**, %struct._atexit*, %struct._atexit, %struct._glue, %struct.__FILE*, %struct._misc_reent*, i8* } +%union.anon = type { i32 } + + at buf = constant [2 x i8] c"x\00", align 4 + at _impure_ptr = external thread_local global %struct._reent* + at .str = private constant [22 x i8] c"This should fault...\0A\00", align 4 + at .str1 = private constant [40 x i8] c"We're still running. This is not good.\0A\00", align 4 + +define i32 @main() nounwind { +entry: + %0 = load %struct._reent** @_impure_ptr, align 4 + %1 = getelementptr inbounds %struct._reent* %0, i32 0, i32 1 + %2 = load %struct.__FILE** %1, align 4 + %3 = bitcast %struct.__FILE* %2 to i8* + %4 = tail call i32 @fwrite(i8* getelementptr inbounds ([22 x i8]* @.str, i32 0, i32 0), i32 1, i32 21, i8* %3) nounwind + %5 = load %struct._reent** @_impure_ptr, align 4 + %6 = getelementptr inbounds %struct._reent* %5, i32 0, i32 1 + %7 = load %struct.__FILE** %6, align 4 + %8 = tail call i32 @fflush(%struct.__FILE* %7) nounwind + store i8 121, i8* getelementptr inbounds ([2 x i8]* @buf, i32 0, i32 0), align 4 + %9 = load %struct._reent** @_impure_ptr, align 4 + %10 = getelementptr inbounds %struct._reent* %9, i32 0, i32 1 + %11 = load %struct.__FILE** %10, align 4 + %12 = bitcast %struct.__FILE* %11 to i8* + %13 = tail call i32 @fwrite(i8* getelementptr inbounds ([40 x i8]* @.str1, i32 0, i32 0), i32 1, i32 39, i8* %12) nounwind + ret i32 1 +} + + +; PIC01: Relocation 0x00000000 +; PIC01-NEXT: 'r_offset', 0x0000001c +; PIC01-NEXT: 'r_sym' +; PIC01-NEXT: 'r_type', 0x0000001b + + +; PIC01: Relocation 0x00000001 +; PIC01-NEXT: 'r_offset', 0x00000038 +; PIC01-NEXT: 'r_sym' +; PIC01-NEXT: 'r_type', 0x0000001b + +; PIC01: Relocation 0x00000002 +; PIC01-NEXT: 'r_offset', 0x00000044 +; PIC01-NEXT: 'r_sym' +; PIC01-NEXT: 'r_type', 0x0000001b + +; PIC01: Relocation 0x00000003 +; PIC01-NEXT: 'r_offset', 0x00000070 +; PIC01-NEXT: 'r_sym' +; PIC01-NEXT: 'r_type', 0x0000001b + +; PIC01: Relocation 0x00000004 +; PIC01-NEXT: 'r_offset', 0x0000007c +; PIC01-NEXT: 'r_sym' +; PIC01-NEXT: 'r_type', 0x00000019 + + +; PIC01: Relocation 0x00000005 +; PIC01-NEXT: 'r_offset', 0x00000080 +; PIC01-NEXT: 'r_sym' +; PIC01-NEXT: 'r_type', 0x00000018 + +; PIC01: Relocation 0x00000006 +; PIC01-NEXT: 'r_offset', 0x00000084 +; PIC01-NEXT: 'r_sym' +; PIC01-NEXT: 'r_type', 0x00000068 + +; PIC01: Relocation 0x00000007 +; PIC01-NEXT: 'r_offset', 0x00000088 +; PIC01-NEXT: 'r_sym' +; PIC01-NEXT: 'r_type', 0x0000001a + +; PIC01: Relocation 0x00000008 +; PIC01-NEXT: 'r_offset', 0x0000008c +; PIC01-NEXT: 'r_sym' +; PIC01-NEXT: 'r_type', 0x00000018 + +declare i32 @fwrite(i8* nocapture, i32, i32, i8* nocapture) nounwind + +declare i32 @fflush(%struct.__FILE* nocapture) nounwind From grosbach at apple.com Mon Dec 13 17:19:53 2010 From: grosbach at apple.com (Jim Grosbach) Date: Mon, 13 Dec 2010 15:19:53 -0800 Subject: [llvm-commits] [llvm] r121721 - in /llvm/trunk: lib/Target/ARM/ARMAsmBackend.cpp lib/Target/ARM/ARMCodeEmitter.cpp lib/Target/ARM/ARMConstantIslandPass.cpp lib/Target/ARM/ARMExpandPseudoInsts.cpp lib/Target/ARM/ARMFixupKinds.h lib/Target/ARM/ARMInstrThumb2.td lib/Target/ARM/ARMMCCodeEmitter.cpp utils/TableGen/EDEmitter.cpp In-Reply-To: <20101213222952.D813F2A6C12C@llvm.org> References: <20101213222952.D813F2A6C12C@llvm.org> Message-ID: <07BA5055-A490-44C1-AA98-E3538D978663@apple.com> Hi Owen, I don't think you're going to be able to expand these pseudos that early. Note that the label is formed differently in the asm string for LEApcrel and LEApcrelJT. That currently ends up "working" through some egregious luck at MC time even though the symbols are wrong. Better is to keep them as pseudos until MC lowering as part of ARMAsmPrinter, where the symbol can be created and properly (see the ARM versions of these insns for reference, and possibly re-use w/ some opcode tweaking). -Jim On Dec 13, 2010, at 2:29 PM, Owen Anderson wrote: > Author: resistor > Date: Mon Dec 13 16:29:52 2010 > New Revision: 121721 > > URL: http://llvm.org/viewvc/llvm-project?rev=121721&view=rev > Log: > Make Thumb2 LEA-like instruction into pseudos, which map down to ADR. Provide correct fixups for Thumb2 ADR, > which is _of course_ different from ARM ADR fixups, or any other Thumb2 fixup. > > Modified: > llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp > llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp > llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp > llvm/trunk/lib/Target/ARM/ARMExpandPseudoInsts.cpp > llvm/trunk/lib/Target/ARM/ARMFixupKinds.h > llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td > llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp > llvm/trunk/utils/TableGen/EDEmitter.cpp > > Modified: llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp?rev=121721&r1=121720&r2=121721&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp (original) > +++ llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp Mon Dec 13 16:29:52 2010 > @@ -136,6 +136,25 @@ > // Encode the immediate and shift the opcode into place. > return ARM_AM::getSOImmVal(Value) | (opc << 21); > } > + > + case ARM::fixup_t2_adr_pcrel_12: { > + Value -= 4; > + unsigned opc = 0; > + if ((int64_t)Value < 0) { > + Value = -Value; > + opc = 5; > + } > + > + uint32_t out = (opc << 21); > + out |= (Value & 0x800) << 14; > + out |= (Value & 0x700) << 4; > + out |= (Value & 0x0FF); > + > + uint64_t swapped = (out & 0xFFFF0000) >> 16; > + swapped |= (out & 0x0000FFFF) << 16; > + return swapped; > + } > + > case ARM::fixup_arm_branch: > // These values don't encode the low two bits since they're always zero. > // Offset by 8 just as above. > @@ -356,6 +375,7 @@ > case ARM::fixup_t2_condbranch: > case ARM::fixup_t2_uncondbranch: > case ARM::fixup_t2_pcrel_10: > + case ARM::fixup_t2_adr_pcrel_12: > case ARM::fixup_arm_thumb_bl: > case ARM::fixup_arm_thumb_blx: > return 4; > > Modified: llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp?rev=121721&r1=121720&r2=121721&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp (original) > +++ llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp Mon Dec 13 16:29:52 2010 > @@ -213,6 +213,8 @@ > const { return 0; } > unsigned getImmMinusOneOpValue(const MachineInstr &MI, unsigned Op) > const { return 0; } > + unsigned getT2AdrLabelOpValue(const MachineInstr &MI, unsigned Op) > + const { return 0; } > unsigned getAddrMode6AddressOpValue(const MachineInstr &MI, unsigned Op) > const { return 0; } > unsigned getAddrMode6DupAddressOpValue(const MachineInstr &MI, unsigned Op) > > Modified: llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp?rev=121721&r1=121720&r2=121721&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp (original) > +++ llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp Mon Dec 13 16:29:52 2010 > @@ -594,7 +594,7 @@ > NegOk = true; > IsSoImm = true; > break; > - case ARM::t2LEApcrel: > + case ARM::t2ADR: > Bits = 12; > NegOk = true; > break; > @@ -1555,7 +1555,7 @@ > unsigned Bits = 0; > switch (Opcode) { > default: break; > - case ARM::t2LEApcrel: > + case ARM::t2ADR: > if (isARMLowRegister(U.MI->getOperand(0).getReg())) { > NewOpc = ARM::tLEApcrel; > Bits = 8; > @@ -1754,16 +1754,16 @@ > if (!OptOk) > continue; > > - // Now scan back again to find the tLEApcrel or t2LEApcrelJT instruction > + // Now scan back again to find the tLEApcrel or t2ADR instruction > // that gave us the initial base register definition. > for (--PrevI; PrevI != B && !PrevI->definesRegister(BaseReg); --PrevI) > ; > > - // The instruction should be a tLEApcrel or t2LEApcrelJT; we want > + // The instruction should be a tLEApcrel or t2ADR; we want > // to delete it as well. > MachineInstr *LeaMI = PrevI; > if ((LeaMI->getOpcode() != ARM::tLEApcrelJT && > - LeaMI->getOpcode() != ARM::t2LEApcrelJT) || > + LeaMI->getOpcode() != ARM::t2ADR) || > LeaMI->getOperand(0).getReg() != BaseReg) > OptOk = false; > > > Modified: llvm/trunk/lib/Target/ARM/ARMExpandPseudoInsts.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMExpandPseudoInsts.cpp?rev=121721&r1=121720&r2=121721&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/ARM/ARMExpandPseudoInsts.cpp (original) > +++ llvm/trunk/lib/Target/ARM/ARMExpandPseudoInsts.cpp Mon Dec 13 16:29:52 2010 > @@ -763,6 +763,21 @@ > break; > } > > + case ARM::t2LEApcrel: > + case ARM::t2LEApcrelJT: { > + bool DstIsDead = MI.getOperand(0).isDead(); > + MachineInstrBuilder MIB = BuildMI(MBB, MBBI, MI.getDebugLoc(), > + TII->get(ARM::t2ADR)) > + .addReg(MI.getOperand(0).getReg(), > + RegState::Define | getDeadRegState(DstIsDead)) // Dst reg > + .addOperand(MI.getOperand(1)) // Label > + .addOperand(MI.getOperand(2)) // Pred > + .addOperand(MI.getOperand(3)); > + TransferImpOps(MI, MIB, MIB); > + MI.eraseFromParent(); > + return MIB; > + } > + > case ARM::MOVi32imm: > case ARM::MOVCCi32imm: > case ARM::t2MOVi32imm: > > Modified: llvm/trunk/lib/Target/ARM/ARMFixupKinds.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMFixupKinds.h?rev=121721&r1=121720&r2=121721&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/ARM/ARMFixupKinds.h (original) > +++ llvm/trunk/lib/Target/ARM/ARMFixupKinds.h Mon Dec 13 16:29:52 2010 > @@ -33,6 +33,9 @@ > // fixup_arm_adr_pcrel_12 - 12-bit PC relative relocation for the ADR > // instruction. > fixup_arm_adr_pcrel_12, > + // fixup_t2_adr_pcrel_12 - 12-bit PC relative relocation for the ADR > + // instruction. > + fixup_t2_adr_pcrel_12, > // fixup_arm_branch - 24-bit PC relative relocation for direct branch > // instructions. > fixup_arm_branch, > > Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td?rev=121721&r1=121720&r2=121721&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td (original) > +++ llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td Mon Dec 13 16:29:52 2010 > @@ -131,6 +131,12 @@ > let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm); > } > > +// ADR instruction labels. > +def t2adrlabel : Operand { > + let EncoderMethod = "getT2AdrLabelOpValue"; > +} > + > + > // t2addrmode_imm8 := reg +/- imm8 > def t2addrmode_imm8 : Operand, > ComplexPattern { > @@ -1128,10 +1134,11 @@ > > // LEApcrel - Load a pc-relative address into a register without offending the > // assembler. > -let neverHasSideEffects = 1 in { > -let isReMaterializable = 1 in > -def t2LEApcrel : T2PCOneRegImm<(outs rGPR:$Rd), (ins i32imm:$label, pred:$p), IIC_iALUi, > - "adr${p}.w\t$Rd, #$label", []> { > +let neverHasSideEffects = 1, isReMaterializable = 1 in { > + > +def t2ADR : T2PCOneRegImm<(outs rGPR:$Rd), > + (ins t2adrlabel:$addr, pred:$p), > + IIC_iALUi, "adr{$p}.w\t$Rd, #$addr", []> { > let Inst{31-27} = 0b11110; > let Inst{25-24} = 0b10; > // Inst{23:21} = '11' (add = FALSE) or '00' (add = TRUE) > @@ -1139,20 +1146,22 @@ > let Inst{20} = 0; > let Inst{19-16} = 0b1111; // Rn > let Inst{15} = 0; > - > - > + > + bits<4> Rd; > + bits<13> addr; > + let Inst{11-8} = Rd; > + let Inst{23} = addr{12}; > + let Inst{21} = addr{12}; > + let Inst{26} = addr{11}; > + let Inst{14-12} = addr{10-8}; > + let Inst{7-0} = addr{7-0}; > } > -} // neverHasSideEffects > -def t2LEApcrelJT : T2PCOneRegImm<(outs rGPR:$Rd), > + > +def t2LEApcrel : PseudoInst<(outs rGPR:$Rd), (ins i32imm:$label, pred:$p), > + IIC_iALUi, []>; > +def t2LEApcrelJT : PseudoInst<(outs rGPR:$Rd), > (ins i32imm:$label, nohash_imm:$id, pred:$p), IIC_iALUi, > - "adr${p}.w\t$Rd, #${label}_${id}", []> { > - let Inst{31-27} = 0b11110; > - let Inst{25-24} = 0b10; > - // Inst{23:21} = '11' (add = FALSE) or '00' (add = TRUE) > - let Inst{22} = 0; > - let Inst{20} = 0; > - let Inst{19-16} = 0b1111; // Rn > - let Inst{15} = 0; > + []>; > } > > > > Modified: llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp?rev=121721&r1=121720&r2=121721&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp (original) > +++ llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp Mon Dec 13 16:29:52 2010 > @@ -56,6 +56,8 @@ > { "fixup_t2_pcrel_10", 0, 32, MCFixupKindInfo::FKF_IsPCRel | > MCFixupKindInfo::FKF_IsAligned}, > { "fixup_arm_adr_pcrel_12", 1, 24, MCFixupKindInfo::FKF_IsPCRel }, > +{ "fixup_t2_adr_pcrel_12", 0, 32, MCFixupKindInfo::FKF_IsPCRel | > + MCFixupKindInfo::FKF_IsAligned}, > { "fixup_arm_branch", 1, 24, MCFixupKindInfo::FKF_IsPCRel }, > { "fixup_t2_condbranch", 0, 32, MCFixupKindInfo::FKF_IsPCRel }, > { "fixup_t2_uncondbranch", 0, 32, MCFixupKindInfo::FKF_IsPCRel }, > @@ -133,6 +135,9 @@ > /// ADR label target. > uint32_t getAdrLabelOpValue(const MCInst &MI, unsigned OpIdx, > SmallVectorImpl &Fixups) const; > + uint32_t getT2AdrLabelOpValue(const MCInst &MI, unsigned OpIdx, > + SmallVectorImpl &Fixups) const; > + > > /// getAddrModeImm12OpValue - Return encoding info for 'reg +/- imm12' > /// operand. > @@ -544,6 +549,16 @@ > Fixups); > } > > +/// getAdrLabelOpValue - Return encoding info for 12-bit immediate ADR label > +/// target. > +uint32_t ARMMCCodeEmitter:: > +getT2AdrLabelOpValue(const MCInst &MI, unsigned OpIdx, > + SmallVectorImpl &Fixups) const { > + assert(MI.getOperand(OpIdx).isExpr() && "Unexpected adr target type!"); > + return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_adr_pcrel_12, > + Fixups); > +} > + > /// getTAddrModeRegRegOpValue - Return encoding info for 'reg + reg' operand. > uint32_t ARMMCCodeEmitter:: > getTAddrModeRegRegOpValue(const MCInst &MI, unsigned OpIdx, > > Modified: llvm/trunk/utils/TableGen/EDEmitter.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/EDEmitter.cpp?rev=121721&r1=121720&r2=121721&view=diff > ============================================================================== > --- llvm/trunk/utils/TableGen/EDEmitter.cpp (original) > +++ llvm/trunk/utils/TableGen/EDEmitter.cpp Mon Dec 13 16:29:52 2010 > @@ -584,6 +584,7 @@ > IMM("t_imm_s4"); > IMM("pclabel"); > IMM("adrlabel"); > + IMM("t2adrlabel"); > IMM("shift_imm"); > IMM("neon_vcvt_imm32"); > > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From dag at cray.com Mon Dec 13 17:27:47 2010 From: dag at cray.com (David A. Greene) Date: Mon, 13 Dec 2010 17:27:47 -0600 Subject: [llvm-commits] [LLVMdev] PR 8199 - Can we get patches reviewed? In-Reply-To: (Jason Kim's message of "Mon, 13 Dec 2010 14:37:26 -0600") References: Message-ID: Jason Kim writes: > I'd vote getting rid of the llvm-gcc bindir being prepended as the > easiest solution to fix this. That won't fix the underlying problem. What if the tester just happens to have an llc, opt, etc. in her PATH? We need to give absolute paths to the tools we're testing, otherwise we don't know what we're testing. > If the list of executables changes, then the explicit list of known > tools need to change as well. > Problem is, I can't immediately think of a nice way to get the list of > generated execs exported to llvm-lit, Do we create new tools all that often? -Dave From resistor at mac.com Mon Dec 13 17:49:28 2010 From: resistor at mac.com (Owen Anderson) Date: Mon, 13 Dec 2010 23:49:28 -0000 Subject: [llvm-commits] [llvm] r121733 - in /llvm/trunk: lib/Transforms/Utils/SimplifyCFG.cpp test/Transforms/SimplifyCFG/switch_create.ll Message-ID: <20101213234928.715CD2A6C12C@llvm.org> Author: resistor Date: Mon Dec 13 17:49:28 2010 New Revision: 121733 URL: http://llvm.org/viewvc/llvm-project?rev=121733&view=rev Log: Fix recent buildbot breakage by pulling SimplifyCFG back to its state as of r121694, the most recent state where I'm confident there were no crashes or miscompilations. XFAIL the test added since then for now. Modified: llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp llvm/trunk/test/Transforms/SimplifyCFG/switch_create.ll Modified: llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp?rev=121733&r1=121732&r2=121733&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp Mon Dec 13 17:49:28 2010 @@ -1515,7 +1515,7 @@ AddPredecessorToBlock(FalseDest, PredBlock, BB); PBI->setSuccessor(1, FalseDest); } - return SimplifyCFG(BB) | true; + return SimplifyCFG(PBI->getParent()) | true; } return false; } @@ -1905,25 +1905,17 @@ BasicBlock *BB = BI->getParent(); - DEBUG(dbgs() << "CONVERTING 'icmp' CHAIN with " << Values.size() - << " cases into SWITCH. BB is:\n" << *BB); - // If there are any extra values that couldn't be folded into the switch // then we evaluate them with an explicit branch first. Split the block // right before the condbr to handle it. if (ExtraCase) { - DEBUG(dbgs() << " ** 'icmp' chain unhandled condition: " << *ExtraCase - << '\n'); + return false; BasicBlock *NewBB = BB->splitBasicBlock(BI, "switch.early.test"); // Remove the uncond branch added to the old block. TerminatorInst *OldTI = BB->getTerminator(); - if (TrueWhenEqual) - BranchInst::Create(EdgeBB, NewBB, ExtraCase, OldTI); - else - BranchInst::Create(NewBB, EdgeBB, ExtraCase, OldTI); - + BranchInst::Create(EdgeBB, NewBB, ExtraCase, OldTI); OldTI->eraseFromParent(); // If there are PHI nodes in EdgeBB, then we need to add a new entry to them @@ -1963,7 +1955,6 @@ // Erase the old branch instruction. EraseTerminatorInstAndDCECond(BI); - return true; } @@ -2367,7 +2358,7 @@ // branches to us and one of our successors, fold the setcc into the // predecessor and use logical operations to pick the right destination. if (FoldBranchToCommonDest(BI)) - return true; + return SimplifyCFG(BB) | true; // Scan predecessor blocks for conditional branches. for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI) @@ -2419,7 +2410,8 @@ if (BI->isUnconditional()) { if (SimplifyUncondBranch(BI)) return true; } else { - if (SimplifyCondBranch(BI)) return true; + if (SimplifyCondBranch(BI)) + return true; } } else if (ReturnInst *RI = dyn_cast(BB->getTerminator())) { if (SimplifyReturn(RI)) return true; Modified: llvm/trunk/test/Transforms/SimplifyCFG/switch_create.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimplifyCFG/switch_create.ll?rev=121733&r1=121732&r2=121733&view=diff ============================================================================== --- llvm/trunk/test/Transforms/SimplifyCFG/switch_create.ll (original) +++ llvm/trunk/test/Transforms/SimplifyCFG/switch_create.ll Mon Dec 13 17:49:28 2010 @@ -1,4 +1,5 @@ ; RUN: opt < %s -simplifycfg -S | FileCheck %s +; XFAIL: * declare void @foo1() From resistor at mac.com Mon Dec 13 17:53:53 2010 From: resistor at mac.com (Owen Anderson) Date: Mon, 13 Dec 2010 15:53:53 -0800 Subject: [llvm-commits] [llvm] r121728 - in /llvm/trunk: lib/Transforms/Utils/SimplifyCFG.cpp test/Transforms/SimplifyCFG/switch_create.ll In-Reply-To: <20101213230220.1220D2A6C12C@llvm.org> References: <20101213230220.1220D2A6C12C@llvm.org> Message-ID: <240F7665-6B9C-485B-AE81-5D99D64C09B4@mac.com> Chris, This patch broke a number of loop tests of the buildbots. I've pulled SimplifyCFG back to r121694, which, from your commit messages, was the last bug-free revision. The test you added since then is still in TOT, but XFAIL'd. --Owen On Dec 13, 2010, at 3:02 PM, Chris Lattner wrote: > Author: lattner > Date: Mon Dec 13 17:02:19 2010 > New Revision: 121728 > > URL: http://llvm.org/viewvc/llvm-project?rev=121728&view=rev > Log: > temporarily disable part of my previous patch, which causes an iterator invalidation issue, causing a crash on some versions of perlbmk. > > Modified: > llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp > llvm/trunk/test/Transforms/SimplifyCFG/switch_create.ll > > Modified: llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp?rev=121728&r1=121727&r2=121728&view=diff > ============================================================================== > --- llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp (original) > +++ llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp Mon Dec 13 17:02:19 2010 > @@ -1515,7 +1515,7 @@ > AddPredecessorToBlock(FalseDest, PredBlock, BB); > PBI->setSuccessor(1, FalseDest); > } > - return SimplifyCFG(PBI->getParent()) | true; > + return SimplifyCFG(BB) | true; > } > return false; > } > > Modified: llvm/trunk/test/Transforms/SimplifyCFG/switch_create.ll > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimplifyCFG/switch_create.ll?rev=121728&r1=121727&r2=121728&view=diff > ============================================================================== > --- llvm/trunk/test/Transforms/SimplifyCFG/switch_create.ll (original) > +++ llvm/trunk/test/Transforms/SimplifyCFG/switch_create.ll Mon Dec 13 17:02:19 2010 > @@ -253,21 +253,21 @@ > ret i32 %conv46 > > ; CHECK: @test9 > -; CHECK: %cmp = icmp ult i8 %c, 33 > -; CHECK: br i1 %cmp, label %lor.end, label %switch.early.test > +; HECK: %cmp = icmp ult i8 %c, 33 > +; HECK: br i1 %cmp, label %lor.end, label %switch.early.test > > -; CHECK: switch.early.test: > -; CHECK: switch i8 %c, label %lor.rhs [ > -; CHECK: i8 46, label %lor.end > -; CHECK: i8 44, label %lor.end > -; CHECK: i8 58, label %lor.end > -; CHECK: i8 59, label %lor.end > -; CHECK: i8 60, label %lor.end > -; CHECK: i8 62, label %lor.end > -; CHECK: i8 34, label %lor.end > -; CHECK: i8 92, label %lor.end > -; CHECK: i8 39, label %lor.end > -; CHECK: ] > +; HECK: switch.early.test: > +; HECK: switch i8 %c, label %lor.rhs [ > +; HECK: i8 46, label %lor.end > +; HECK: i8 44, label %lor.end > +; HECK: i8 58, label %lor.end > +; HECK: i8 59, label %lor.end > +; HECK: i8 60, label %lor.end > +; HECK: i8 62, label %lor.end > +; HECK: i8 34, label %lor.end > +; HECK: i8 92, label %lor.end > +; HECK: i8 39, label %lor.end > +; HECK: ] > } > > define i32 @test10(i32 %mode, i1 %Cond) { > @@ -331,3 +331,24 @@ > ; CHECK: i32 4, label %return > ; CHECK: ] > } > + > +define void @test12() nounwind { > +entry: > + br label %bb49.us.us > + > +bb49.us.us: > + %A = icmp eq i32 undef, undef > + br i1 %A, label %bb55.us.us, label %malformed > + > +bb48.us.us: > + %B = icmp ugt i32 undef, undef > + br i1 %B, label %bb55.us.us, label %bb49.us.us > + > +bb55.us.us: > + br label %bb48.us.us > + > +malformed: > + ret void > +; CHECK: @test12 > + > +} > \ No newline at end of file > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20101213/a2bd6be6/attachment.html From sabre at nondot.org Mon Dec 13 18:11:23 2010 From: sabre at nondot.org (Chris Lattner) Date: Mon, 13 Dec 2010 16:11:23 -0800 Subject: [llvm-commits] [llvm] r121728 - in /llvm/trunk: lib/Transforms/Utils/SimplifyCFG.cpp test/Transforms/SimplifyCFG/switch_create.ll In-Reply-To: <240F7665-6B9C-485B-AE81-5D99D64C09B4@mac.com> References: <20101213230220.1220D2A6C12C@llvm.org> <240F7665-6B9C-485B-AE81-5D99D64C09B4@mac.com> Message-ID: <60606E52-FBB5-45B3-946B-6AA8C8BCE25B@nondot.org> On Dec 13, 2010, at 3:53 PM, Owen Anderson wrote: > Chris, > > This patch broke a number of loop tests of the buildbots. I've pulled SimplifyCFG back to r121694, which, from your commit messages, was the last bug-free revision. The test you added since then is still in TOT, but XFAIL'd. > Thanks Owen, sigh sorry for the breakage. -Chris From wendling at apple.com Mon Dec 13 18:24:08 2010 From: wendling at apple.com (Bill Wendling) Date: Mon, 13 Dec 2010 16:24:08 -0800 Subject: [llvm-commits] [llvm] r121732 - in /llvm/trunk: lib/MC/ELFObjectWriter.cpp test/CodeGen/ARM/2010-12-13-reloc-pic.ll In-Reply-To: <20101213231607.8D88F2A6C12C@llvm.org> References: <20101213231607.8D88F2A6C12C@llvm.org> Message-ID: On Dec 13, 2010, at 3:16 PM, Jason W Kim wrote: > Author: jasonwkim > Date: Mon Dec 13 17:16:07 2010 > New Revision: 121732 > > URL: http://llvm.org/viewvc/llvm-project?rev=121732&view=rev > Log: > First cut of ARM/MC/ELF PIC relocations. > Test has fixme, to move to .s -> .o test when AsmParser works better. > > > Added: 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=121732&view=auto > ============================================================================== > --- llvm/trunk/test/CodeGen/ARM/2010-12-13-reloc-pic.ll (added) > +++ llvm/trunk/test/CodeGen/ARM/2010-12-13-reloc-pic.ll Mon Dec 13 17:16:07 2010 > @@ -0,0 +1,100 @@ > +; RUN: llc %s -mtriple=armv7-linux-gnueabi -arm-use-movt -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, Hi Jason, Small point: could you put the "Fixme" in upper case? That's typically what people do and it makes it easy to search for with grep. -bw -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20101213/b1369c9f/attachment.html From resistor at mac.com Mon Dec 13 18:36:49 2010 From: resistor at mac.com (Owen Anderson) Date: Tue, 14 Dec 2010 00:36:49 -0000 Subject: [llvm-commits] [llvm] r121735 - in /llvm/trunk: lib/Target/ARM/ARMAsmBackend.cpp lib/Target/ARM/ARMAsmPrinter.cpp lib/Target/ARM/ARMCodeEmitter.cpp lib/Target/ARM/ARMFixupKinds.h lib/Target/ARM/ARMInstrThumb2.td lib/Target/ARM/ARMMCCodeEmitter.cpp utils/TableGen/EDEmitter.cpp Message-ID: <20101214003649.5DF1A2A6C12C@llvm.org> Author: resistor Date: Mon Dec 13 18:36:49 2010 New Revision: 121735 URL: http://llvm.org/viewvc/llvm-project?rev=121735&view=rev Log: Second attempt at make Thumb2 LEAs pseudos. This time, perform the lowering much later, which makes the entire process cleaner. Modified: llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp llvm/trunk/lib/Target/ARM/ARMFixupKinds.h llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp llvm/trunk/utils/TableGen/EDEmitter.cpp Modified: llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp?rev=121735&r1=121734&r2=121735&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp Mon Dec 13 18:36:49 2010 @@ -136,6 +136,25 @@ // Encode the immediate and shift the opcode into place. return ARM_AM::getSOImmVal(Value) | (opc << 21); } + + case ARM::fixup_t2_adr_pcrel_12: { + Value -= 4; + unsigned opc = 0; + if ((int64_t)Value < 0) { + Value = -Value; + opc = 5; + } + + uint32_t out = (opc << 21); + out |= (Value & 0x800) << 14; + out |= (Value & 0x700) << 4; + out |= (Value & 0x0FF); + + uint64_t swapped = (out & 0xFFFF0000) >> 16; + swapped |= (out & 0x0000FFFF) << 16; + return swapped; + } + case ARM::fixup_arm_branch: // These values don't encode the low two bits since they're always zero. // Offset by 8 just as above. @@ -356,6 +375,7 @@ case ARM::fixup_t2_condbranch: case ARM::fixup_t2_uncondbranch: case ARM::fixup_t2_pcrel_10: + case ARM::fixup_t2_adr_pcrel_12: case ARM::fixup_arm_thumb_bl: case ARM::fixup_arm_thumb_blx: return 4; Modified: llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp?rev=121735&r1=121734&r2=121735&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp Mon Dec 13 18:36:49 2010 @@ -734,6 +734,7 @@ } return; } + case ARM::t2LEApcrel: case ARM::LEApcrel: { // FIXME: Need to also handle globals and externals assert (MI->getOperand(1).isCPI()); @@ -741,7 +742,10 @@ MCSymbol *Sym = GetCPISymbol(LabelId); const MCExpr *SymbolExpr = MCSymbolRefExpr::Create(Sym, OutContext); MCInst TmpInst; - TmpInst.setOpcode(ARM::ADR); + if (MI->getOpcode() == ARM::LEApcrel) + TmpInst.setOpcode(ARM::ADR); + else + TmpInst.setOpcode(ARM::t2ADR); TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); TmpInst.addOperand(MCOperand::CreateExpr(SymbolExpr)); // Add predicate operands. @@ -750,13 +754,17 @@ OutStreamer.EmitInstruction(TmpInst); return; } + case ARM::t2LEApcrelJT: case ARM::LEApcrelJT: { unsigned JTI = MI->getOperand(1).getIndex(); unsigned Id = MI->getOperand(2).getImm(); MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, Id); const MCExpr *SymbolExpr = MCSymbolRefExpr::Create(JTISymbol, OutContext); MCInst TmpInst; - TmpInst.setOpcode(ARM::ADR); + if (MI->getOpcode() == ARM::LEApcrelJT) + TmpInst.setOpcode(ARM::ADR); + else + TmpInst.setOpcode(ARM::t2ADR); TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); TmpInst.addOperand(MCOperand::CreateExpr(SymbolExpr)); // Add predicate operands. Modified: llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp?rev=121735&r1=121734&r2=121735&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp Mon Dec 13 18:36:49 2010 @@ -213,6 +213,8 @@ const { return 0; } unsigned getImmMinusOneOpValue(const MachineInstr &MI, unsigned Op) const { return 0; } + unsigned getT2AdrLabelOpValue(const MachineInstr &MI, unsigned Op) + const { return 0; } unsigned getAddrMode6AddressOpValue(const MachineInstr &MI, unsigned Op) const { return 0; } unsigned getAddrMode6DupAddressOpValue(const MachineInstr &MI, unsigned Op) Modified: llvm/trunk/lib/Target/ARM/ARMFixupKinds.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMFixupKinds.h?rev=121735&r1=121734&r2=121735&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMFixupKinds.h (original) +++ llvm/trunk/lib/Target/ARM/ARMFixupKinds.h Mon Dec 13 18:36:49 2010 @@ -33,6 +33,9 @@ // fixup_arm_adr_pcrel_12 - 12-bit PC relative relocation for the ADR // instruction. fixup_arm_adr_pcrel_12, + // fixup_t2_adr_pcrel_12 - 12-bit PC relative relocation for the ADR + // instruction. + fixup_t2_adr_pcrel_12, // fixup_arm_branch - 24-bit PC relative relocation for direct branch // instructions. fixup_arm_branch, Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td?rev=121735&r1=121734&r2=121735&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td Mon Dec 13 18:36:49 2010 @@ -131,6 +131,12 @@ let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm); } +// ADR instruction labels. +def t2adrlabel : Operand { + let EncoderMethod = "getT2AdrLabelOpValue"; +} + + // t2addrmode_imm8 := reg +/- imm8 def t2addrmode_imm8 : Operand, ComplexPattern { @@ -1128,10 +1134,9 @@ // LEApcrel - Load a pc-relative address into a register without offending the // assembler. -let neverHasSideEffects = 1 in { -let isReMaterializable = 1 in -def t2LEApcrel : T2PCOneRegImm<(outs rGPR:$Rd), (ins i32imm:$label, pred:$p), IIC_iALUi, - "adr${p}.w\t$Rd, #$label", []> { +def t2ADR : T2PCOneRegImm<(outs rGPR:$Rd), + (ins t2adrlabel:$addr, pred:$p), + IIC_iALUi, "adr{$p}.w\t$Rd, #$addr", []> { let Inst{31-27} = 0b11110; let Inst{25-24} = 0b10; // Inst{23:21} = '11' (add = FALSE) or '00' (add = TRUE) @@ -1139,21 +1144,23 @@ let Inst{20} = 0; let Inst{19-16} = 0b1111; // Rn let Inst{15} = 0; - - + + bits<4> Rd; + bits<13> addr; + let Inst{11-8} = Rd; + let Inst{23} = addr{12}; + let Inst{21} = addr{12}; + let Inst{26} = addr{11}; + let Inst{14-12} = addr{10-8}; + let Inst{7-0} = addr{7-0}; } -} // neverHasSideEffects -def t2LEApcrelJT : T2PCOneRegImm<(outs rGPR:$Rd), + +let neverHasSideEffects = 1, isReMaterializable = 1 in +def t2LEApcrel : PseudoInst<(outs rGPR:$Rd), (ins i32imm:$label, pred:$p), + IIC_iALUi, []>; +def t2LEApcrelJT : PseudoInst<(outs rGPR:$Rd), (ins i32imm:$label, nohash_imm:$id, pred:$p), IIC_iALUi, - "adr${p}.w\t$Rd, #${label}_${id}", []> { - let Inst{31-27} = 0b11110; - let Inst{25-24} = 0b10; - // Inst{23:21} = '11' (add = FALSE) or '00' (add = TRUE) - let Inst{22} = 0; - let Inst{20} = 0; - let Inst{19-16} = 0b1111; // Rn - let Inst{15} = 0; -} + []>; // FIXME: None of these add/sub SP special instructions should be necessary Modified: llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp?rev=121735&r1=121734&r2=121735&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp Mon Dec 13 18:36:49 2010 @@ -56,6 +56,8 @@ { "fixup_t2_pcrel_10", 0, 32, MCFixupKindInfo::FKF_IsPCRel | MCFixupKindInfo::FKF_IsAligned}, { "fixup_arm_adr_pcrel_12", 1, 24, MCFixupKindInfo::FKF_IsPCRel }, +{ "fixup_t2_adr_pcrel_12", 0, 32, MCFixupKindInfo::FKF_IsPCRel | + MCFixupKindInfo::FKF_IsAligned}, { "fixup_arm_branch", 1, 24, MCFixupKindInfo::FKF_IsPCRel }, { "fixup_t2_condbranch", 0, 32, MCFixupKindInfo::FKF_IsPCRel }, { "fixup_t2_uncondbranch", 0, 32, MCFixupKindInfo::FKF_IsPCRel }, @@ -133,6 +135,9 @@ /// ADR label target. uint32_t getAdrLabelOpValue(const MCInst &MI, unsigned OpIdx, SmallVectorImpl &Fixups) const; + uint32_t getT2AdrLabelOpValue(const MCInst &MI, unsigned OpIdx, + SmallVectorImpl &Fixups) const; + /// getAddrModeImm12OpValue - Return encoding info for 'reg +/- imm12' /// operand. @@ -544,6 +549,16 @@ Fixups); } +/// getAdrLabelOpValue - Return encoding info for 12-bit immediate ADR label +/// target. +uint32_t ARMMCCodeEmitter:: +getT2AdrLabelOpValue(const MCInst &MI, unsigned OpIdx, + SmallVectorImpl &Fixups) const { + assert(MI.getOperand(OpIdx).isExpr() && "Unexpected adr target type!"); + return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_adr_pcrel_12, + Fixups); +} + /// getTAddrModeRegRegOpValue - Return encoding info for 'reg + reg' operand. uint32_t ARMMCCodeEmitter:: getTAddrModeRegRegOpValue(const MCInst &MI, unsigned OpIdx, Modified: llvm/trunk/utils/TableGen/EDEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/EDEmitter.cpp?rev=121735&r1=121734&r2=121735&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/EDEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/EDEmitter.cpp Mon Dec 13 18:36:49 2010 @@ -584,6 +584,7 @@ IMM("t_imm_s4"); IMM("pclabel"); IMM("adrlabel"); + IMM("t2adrlabel"); IMM("shift_imm"); IMM("neon_vcvt_imm32"); From stoklund at 2pi.dk Mon Dec 13 18:37:44 2010 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Tue, 14 Dec 2010 00:37:44 -0000 Subject: [llvm-commits] [llvm] r121736 - /llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp Message-ID: <20101214003744.CFCBE2A6C12C@llvm.org> Author: stoklund Date: Mon Dec 13 18:37:44 2010 New Revision: 121736 URL: http://llvm.org/viewvc/llvm-project?rev=121736&view=rev Log: Add stub for RAGreedy::trySplit. Modified: llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp Modified: llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp?rev=121736&r1=121735&r2=121736&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp (original) +++ llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp Mon Dec 13 18:37:44 2010 @@ -83,6 +83,9 @@ bool checkUncachedInterference(LiveInterval &, unsigned); bool reassignVReg(LiveInterval &InterferingVReg, unsigned OldPhysReg); bool reassignInterferences(LiveInterval &VirtReg, unsigned PhysReg); + + unsigned trySplit(LiveInterval&, AllocationOrder&, + SmallVectorImpl&); }; } // end anonymous namespace @@ -222,6 +225,15 @@ return reassignVReg(*Q.interferingVRegs()[0], PhysReg); } +/// trySplit - Try to split VirtReg or one of its interferences, making it +/// assignable. +/// @return Physreg when VirtReg may be assigned and/or new SplitVRegs. +unsigned RAGreedy::trySplit(LiveInterval &VirtReg, AllocationOrder &Order, + SmallVectorImpl&SplitVRegs) { + NamedRegionTimer T("Splitter", TimerGroupName, TimePassesIsEnabled); + return 0; +} + unsigned RAGreedy::selectOrSplit(LiveInterval &VirtReg, SmallVectorImpl &SplitVRegs) { // Populate a list of physical register spill candidates. @@ -266,6 +278,10 @@ PhysRegSpillCands.insert(PhysRegSpillCands.end(), ReassignCands.begin(), ReassignCands.end()); + unsigned PhysReg = trySplit(VirtReg, Order, SplitVRegs); + if (PhysReg || !SplitVRegs.empty()) + return PhysReg; + // Try to spill another interfering reg with less spill weight. NamedRegionTimer T("Spiller", TimerGroupName, TimePassesIsEnabled); // From stoklund at 2pi.dk Mon Dec 13 18:37:49 2010 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Tue, 14 Dec 2010 00:37:49 -0000 Subject: [llvm-commits] [llvm] r121737 - /llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp Message-ID: <20101214003749.B9CA32A6C12D@llvm.org> Author: stoklund Date: Mon Dec 13 18:37:49 2010 New Revision: 121737 URL: http://llvm.org/viewvc/llvm-project?rev=121737&view=rev Log: Try reassigning all virtual register interferences, not just those with lower spill weight. Filter out fixed registers instead. Add support for reassigning an interference that was assigned to an alias. Modified: llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp Modified: llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp?rev=121737&r1=121736&r2=121737&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp (original) +++ llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp Mon Dec 13 18:37:49 2010 @@ -80,10 +80,12 @@ static char ID; private: - bool checkUncachedInterference(LiveInterval &, unsigned); + bool checkUncachedInterference(LiveInterval&, unsigned); + LiveInterval *getSingleInterference(LiveInterval&, unsigned); bool reassignVReg(LiveInterval &InterferingVReg, unsigned OldPhysReg); bool reassignInterferences(LiveInterval &VirtReg, unsigned PhysReg); + unsigned tryReassign(LiveInterval&, AllocationOrder&); unsigned trySplit(LiveInterval&, AllocationOrder&, SmallVectorImpl&); }; @@ -163,6 +165,35 @@ return false; } +/// getSingleInterference - Return the single interfering virtual register +/// assigned to PhysReg. Return 0 if more than one virtual register is +/// interfering. +LiveInterval *RAGreedy::getSingleInterference(LiveInterval &VirtReg, + unsigned PhysReg) { + LiveInterval *Interference = 0; + + // Check direct interferences. + LiveIntervalUnion::Query &Q = query(VirtReg, PhysReg); + if (Q.checkInterference()) { + if (!Q.seenAllInterferences()) + return 0; + Q.collectInterferingVRegs(1); + Interference = Q.interferingVRegs().front(); + } + + // Check aliases. + for (const unsigned *AliasI = TRI->getAliasSet(PhysReg); *AliasI; ++AliasI) { + LiveIntervalUnion::Query &Q = query(VirtReg, *AliasI); + if (Q.checkInterference()) { + if (Interference || !Q.seenAllInterferences()) + return 0; + Q.collectInterferingVRegs(1); + Interference = Q.interferingVRegs().front(); + } + } + return Interference; +} + // Attempt to reassign this virtual register to a different physical register. // // FIXME: we are not yet caching these "second-level" interferences discovered @@ -173,23 +204,26 @@ // FIXME: This may result in a lot of alias queries. We could summarize alias // live intervals in their parent register's live union, but it's messy. bool RAGreedy::reassignVReg(LiveInterval &InterferingVReg, - unsigned OldPhysReg) { - assert(OldPhysReg == VRM->getPhys(InterferingVReg.reg) && + unsigned WantedPhysReg) { + assert(TargetRegisterInfo::isVirtualRegister(InterferingVReg.reg) && + "Can only reassign virtual registers"); + assert(TRI->regsOverlap(WantedPhysReg, VRM->getPhys(InterferingVReg.reg)) && "inconsistent phys reg assigment"); AllocationOrder Order(InterferingVReg.reg, *VRM, ReservedRegs); while (unsigned PhysReg = Order.next()) { - if (PhysReg == OldPhysReg) + // Don't reassign to a WantedPhysReg alias. + if (TRI->regsOverlap(PhysReg, WantedPhysReg)) continue; if (checkUncachedInterference(InterferingVReg, PhysReg)) continue; - DEBUG(dbgs() << "reassigning: " << InterferingVReg << " from " << - TRI->getName(OldPhysReg) << " to " << TRI->getName(PhysReg) << '\n'); - // Reassign the interfering virtual reg to this physical reg. - PhysReg2LiveUnion[OldPhysReg].extract(InterferingVReg); + unsigned OldAssign = VRM->getPhys(InterferingVReg.reg); + DEBUG(dbgs() << "reassigning: " << InterferingVReg << " from " << + TRI->getName(OldAssign) << " to " << TRI->getName(PhysReg) << '\n'); + PhysReg2LiveUnion[OldAssign].extract(InterferingVReg); VRM->clearVirt(InterferingVReg.reg); VRM->assignVirt2Phys(InterferingVReg.reg, PhysReg); PhysReg2LiveUnion[PhysReg].unify(InterferingVReg); @@ -199,30 +233,32 @@ return false; } -// Collect all virtual regs currently assigned to PhysReg that interfere with -// VirtReg. -// -// Currently, for simplicity, we only attempt to reassign a single interference -// within the same register class. +/// reassignInterferences - Reassign all interferences to different physical +/// registers such that Virtreg can be assigned to PhysReg. +/// Currently this only works with a single interference. +/// @param VirtReg Currently unassigned virtual register. +/// @param PhysReg Physical register to be cleared. +/// @return True on success, false if nothing was changed. bool RAGreedy::reassignInterferences(LiveInterval &VirtReg, unsigned PhysReg) { - LiveIntervalUnion::Query &Q = query(VirtReg, PhysReg); - - // Limit the interference search to one interference. - Q.collectInterferingVRegs(1); - assert(Q.interferingVRegs().size() == 1 && - "expected at least one interference"); - - // Do not attempt reassignment unless we find only a single interference. - if (!Q.seenAllInterferences()) + LiveInterval *InterferingVReg = getSingleInterference(VirtReg, PhysReg); + if (!InterferingVReg) return false; + if (TargetRegisterInfo::isPhysicalRegister(InterferingVReg->reg)) + return false; + return reassignVReg(*InterferingVReg, PhysReg); +} - // Don't allow any interferences on aliases. - for (const unsigned *AliasI = TRI->getAliasSet(PhysReg); *AliasI; ++AliasI) { - if (query(VirtReg, *AliasI).checkInterference()) - return false; - } - - return reassignVReg(*Q.interferingVRegs()[0], PhysReg); +/// tryReassign - Try to reassign interferences to different physregs. +/// @param VirtReg Currently unassigned virtual register. +/// @param Order Physregs to try. +/// @return Physreg to assign VirtReg, or 0. +unsigned RAGreedy::tryReassign(LiveInterval &VirtReg, AllocationOrder &Order) { + NamedRegionTimer T("Reassign", TimerGroupName, TimePassesIsEnabled); + Order.rewind(); + while (unsigned PhysReg = Order.next()) + if (reassignInterferences(VirtReg, PhysReg)) + return PhysReg; + return 0; } /// trySplit - Try to split VirtReg or one of its interferences, making it @@ -255,29 +291,15 @@ // The current VirtReg must either be spillable, or one of its interferences // must have less spill weight. - if (InterferingVirtReg->weight < VirtReg.weight ) { - // For simplicity, only consider reassigning registers in the same class. - if (InterfReg == PhysReg) - ReassignCands.push_back(PhysReg); - else - PhysRegSpillCands.push_back(PhysReg); - } + if (InterferingVirtReg->weight < VirtReg.weight ) + PhysRegSpillCands.push_back(PhysReg); } - // Try to reassign interfering physical register. Priority among - // PhysRegSpillCands does not matter yet, because the reassigned virtual - // registers will still be assigned to physical registers. - { - NamedRegionTimer T("Reassign", TimerGroupName, TimePassesIsEnabled); - for (SmallVectorImpl::iterator PhysRegI = ReassignCands.begin(), - PhysRegE = ReassignCands.end(); PhysRegI != PhysRegE; ++PhysRegI) - if (reassignInterferences(VirtReg, *PhysRegI)) - // Reassignment successfull. Allocate now to this PhysReg. - return *PhysRegI; - } - PhysRegSpillCands.insert(PhysRegSpillCands.end(), ReassignCands.begin(), - ReassignCands.end()); + // Try to reassign interferences. + if (unsigned PhysReg = tryReassign(VirtReg, Order)) + return PhysReg; + // Try splitting VirtReg or interferences. unsigned PhysReg = trySplit(VirtReg, Order, SplitVRegs); if (PhysReg || !SplitVRegs.empty()) return PhysReg; From stoklund at 2pi.dk Mon Dec 13 18:37:52 2010 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Tue, 14 Dec 2010 00:37:52 -0000 Subject: [llvm-commits] [llvm] r121738 - /llvm/trunk/include/llvm/ADT/IntervalMap.h Message-ID: <20101214003752.97B762A6C12C@llvm.org> Author: stoklund Date: Mon Dec 13 18:37:52 2010 New Revision: 121738 URL: http://llvm.org/viewvc/llvm-project?rev=121738&view=rev Log: Remove debugging code. Modified: llvm/trunk/include/llvm/ADT/IntervalMap.h Modified: llvm/trunk/include/llvm/ADT/IntervalMap.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/IntervalMap.h?rev=121738&r1=121737&r2=121738&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/IntervalMap.h (original) +++ llvm/trunk/include/llvm/ADT/IntervalMap.h Mon Dec 13 18:37:52 2010 @@ -105,9 +105,6 @@ #include "llvm/Support/RecyclingAllocator.h" #include -// FIXME: Remove debugging code. -#include "llvm/Support/raw_ostream.h" - namespace llvm { @@ -590,16 +587,6 @@ } unsigned insertFrom(unsigned &Pos, unsigned Size, KeyT a, KeyT b, ValT y); - -#ifndef NDEBUG - void dump(raw_ostream &OS, unsigned Size) { - OS << " N" << this << " [shape=record label=\"{ " << Size << '/' << N; - for (unsigned i = 0; i != Size; ++i) - OS << " | {" << start(i) << '-' << stop(i) << "|" << value(i) << '}'; - OS << "}\"];\n"; - } -#endif - }; /// insertFrom - Add mapping of [a;b] to y if possible, coalescing as much as @@ -743,19 +730,6 @@ subtree(i) = Node; stop(i) = Stop; } - -#ifndef NDEBUG - void dump(raw_ostream &OS, unsigned Size) { - OS << " N" << this << " [shape=record label=\"" << Size << '/' << N; - for (unsigned i = 0; i != Size; ++i) - OS << " | " << stop(i); - OS << "\"];\n"; - for (unsigned i = 0; i != Size; ++i) - OS << " N" << this << ":s" << i << " -> N" - << &subtree(i).template get() << ";\n"; - } -#endif - }; //===----------------------------------------------------------------------===// @@ -922,14 +896,6 @@ moveLeft(Level); ++path[Level].offset; } - -#ifndef NDEBUG - void dump() const { - for (unsigned l = 0, e = path.size(); l != e; ++l) - errs() << l << ": " << path[l].node << ' ' << path[l].size << ' ' - << path[l].offset << '\n'; - } -#endif }; } // namespace IntervalMapImpl @@ -1155,12 +1121,6 @@ I.find(x); return I; } - -#ifndef NDEBUG - raw_ostream *OS; - void dump(); - void dumpNode(IntervalMapImpl::NodeRef Node, unsigned Height); -#endif }; /// treeSafeLookup - Return the mapped value at x or NotFound, assuming a @@ -1304,32 +1264,6 @@ rootSize = 0; } -#ifndef NDEBUG -template -void IntervalMap:: -dumpNode(IntervalMapImpl::NodeRef Node, unsigned Height) { - if (Height) - Node.get().dump(*OS, Node.size()); - else - Node.get().dump(*OS, Node.size()); -} - -template -void IntervalMap:: -dump() { - std::string errors; - raw_fd_ostream ofs("tree.dot", errors); - OS = &ofs; - ofs << "digraph {\n"; - if (branched()) - rootBranch().dump(ofs, rootSize); - else - rootLeaf().dump(ofs, rootSize); - visitNodes(&IntervalMap::dumpNode); - ofs << "}\n"; -} -#endif - //===----------------------------------------------------------------------===// //--- IntervalMap::const_iterator ----// //===----------------------------------------------------------------------===// From stoklund at 2pi.dk Mon Dec 13 18:55:51 2010 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Tue, 14 Dec 2010 00:55:51 -0000 Subject: [llvm-commits] [llvm] r121740 - /llvm/trunk/docs/ProgrammersManual.html Message-ID: <20101214005551.AFB682A6C12C@llvm.org> Author: stoklund Date: Mon Dec 13 18:55:51 2010 New Revision: 121740 URL: http://llvm.org/viewvc/llvm-project?rev=121740&view=rev Log: Add IntervalMap to the Programmer's Manual. Modified: llvm/trunk/docs/ProgrammersManual.html Modified: llvm/trunk/docs/ProgrammersManual.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/ProgrammersManual.html?rev=121740&r1=121739&r2=121740&view=diff ============================================================================== --- llvm/trunk/docs/ProgrammersManual.html (original) +++ llvm/trunk/docs/ProgrammersManual.html Mon Dec 13 18:55:51 2010 @@ -84,6 +84,7 @@
  • "llvm/ADT/IndexedMap.h"
  • "llvm/ADT/DenseMap.h"
  • "llvm/ADT/ValueMap.h"
  • +
  • "llvm/ADT/IntervalMap.h"
  • <map>
  • Other Map-Like Container Options
  • @@ -1509,6 +1510,23 @@ + +
    + +

    IntervalMap is a compact map for small keys and values. It maps key +intervals instead of single keys, and it will automatically coalesce adjacent +intervals. When then map only contains a few intervals, they are stored in the +map object itself to avoid allocations.

    + +

    The IntervalMap iterators are quite big, so they should not be passed around +as STL iterators. The heavyweight iterators allow a smaller data structure.

    + +
    + + + From stoklund at 2pi.dk Mon Dec 13 18:58:47 2010 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Tue, 14 Dec 2010 00:58:47 -0000 Subject: [llvm-commits] [llvm] r121741 - /llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp Message-ID: <20101214005847.D3F102A6C12C@llvm.org> Author: stoklund Date: Mon Dec 13 18:58:47 2010 New Revision: 121741 URL: http://llvm.org/viewvc/llvm-project?rev=121741&view=rev Log: Remove unused vector. Modified: llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp Modified: llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp?rev=121741&r1=121740&r2=121741&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp (original) +++ llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp Mon Dec 13 18:58:47 2010 @@ -273,7 +273,7 @@ unsigned RAGreedy::selectOrSplit(LiveInterval &VirtReg, SmallVectorImpl &SplitVRegs) { // Populate a list of physical register spill candidates. - SmallVector PhysRegSpillCands, ReassignCands; + SmallVector PhysRegSpillCands; // Check for an available register in this class. AllocationOrder Order(VirtReg.reg, *VRM, ReservedRegs); From jason.w.kim.2009 at gmail.com Mon Dec 13 19:42:39 2010 From: jason.w.kim.2009 at gmail.com (Jason W Kim) Date: Tue, 14 Dec 2010 01:42:39 -0000 Subject: [llvm-commits] [llvm] r121743 - /llvm/trunk/test/CodeGen/ARM/2010-12-13-reloc-pic.ll Message-ID: <20101214014239.222A42A6C12C@llvm.org> Author: jasonwkim Date: Mon Dec 13 19:42:38 2010 New Revision: 121743 URL: http://llvm.org/viewvc/llvm-project?rev=121743&view=rev Log: fix fixme case typo :-) Modified: llvm/trunk/test/CodeGen/ARM/2010-12-13-reloc-pic.ll 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=121743&r1=121742&r2=121743&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 Dec 13 19:42:38 2010 @@ -1,7 +1,7 @@ ; RUN: llc %s -mtriple=armv7-linux-gnueabi -arm-use-movt -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, +;; FIXME: Reduce this test further, or even better, ;; redo as .s -> .o test once ARM AsmParser is working better ; ModuleID = 'large2.pnacl.bc' From aggarwa4 at illinois.edu Mon Dec 13 19:50:09 2010 From: aggarwa4 at illinois.edu (Arushi Aggarwal) Date: Tue, 14 Dec 2010 01:50:09 -0000 Subject: [llvm-commits] [poolalloc] r121744 - /poolalloc/trunk/test/dsa/callgraph/scc3.c Message-ID: <20101214015009.5EAAD2A6C12C@llvm.org> Author: aggarwa4 Date: Mon Dec 13 19:50:09 2010 New Revision: 121744 URL: http://llvm.org/viewvc/llvm-project?rev=121744&view=rev Log: Simplified test case for infinite looping in BU. Happens in sqlite3. Added: poolalloc/trunk/test/dsa/callgraph/scc3.c Added: poolalloc/trunk/test/dsa/callgraph/scc3.c URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/test/dsa/callgraph/scc3.c?rev=121744&view=auto ============================================================================== --- poolalloc/trunk/test/dsa/callgraph/scc3.c (added) +++ poolalloc/trunk/test/dsa/callgraph/scc3.c Mon Dec 13 19:50:09 2010 @@ -0,0 +1,40 @@ +// A, B, func are in an SCC +// C is called indirectly from A/B +// The indirect call site in C is resolved, once we process the SCC +// But since, we never process the SCC graph again, +// we never inline func into the SCC graph(of A, B, and func) at that +// call site. + +// when we inline the SCCGraph into D(due to call to A), the unresolved +// call site is also inlined. As it is complete and can be resolved +// we inline the SCC graph again, pulling in the unresolved call site +// again. This causes an infinte looping in BU. + +;XFAIL:* +;RUN: not + +typedef int* (*funcptr)(int *); + +static int* A(); + +static int* func(int * arg) { + A(); + return arg; +} + +static int* C(funcptr f, int *arg) { + (*f)(arg); +} + +static int *B() { + func(A()); + return C(func, A()); +} + +static int* A() { + return func(B()); +} + +static int* D() { + return A(); +} From evan.cheng at apple.com Mon Dec 13 21:22:07 2010 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 14 Dec 2010 03:22:07 -0000 Subject: [llvm-commits] [llvm] r121746 - in /llvm/trunk: lib/Target/ARM/ARMISelLowering.cpp test/CodeGen/ARM/bfi.ll Message-ID: <20101214032207.F060B2A6C12C@llvm.org> Author: evancheng Date: Mon Dec 13 21:22:07 2010 New Revision: 121746 URL: http://llvm.org/viewvc/llvm-project?rev=121746&view=rev Log: bfi A, (and B, C1), C2) -> bfi A, B, C2 iff C1 & C2 == C1. rdar://8458663 Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp llvm/trunk/test/CodeGen/ARM/bfi.ll Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=121746&r1=121745&r2=121746&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Mon Dec 13 21:22:07 2010 @@ -4809,6 +4809,25 @@ return SDValue(); } +/// PerformBFICombine - (bfi A, (and B, C1), C2) -> (bfi A, B, C2) iff +/// C1 & C2 == C1. +static SDValue PerformBFICombine(SDNode *N, + TargetLowering::DAGCombinerInfo &DCI) { + SDValue N1 = N->getOperand(1); + if (N1.getOpcode() == ISD::AND) { + ConstantSDNode *N11C = dyn_cast(N1.getOperand(1)); + if (!N11C) + return SDValue(); + unsigned Mask = cast(N->getOperand(2))->getZExtValue(); + unsigned Mask2 = N11C->getZExtValue(); + if ((Mask & Mask2) == Mask2) + return DCI.DAG.getNode(ARMISD::BFI, N->getDebugLoc(), N->getValueType(0), + N->getOperand(0), N1.getOperand(0), + N->getOperand(2)); + } + return SDValue(); +} + /// PerformVMOVRRDCombine - Target-specific dag combine xforms for /// ARMISD::VMOVRRD. static SDValue PerformVMOVRRDCombine(SDNode *N, @@ -5398,6 +5417,7 @@ case ISD::MUL: return PerformMULCombine(N, DCI, Subtarget); case ISD::OR: return PerformORCombine(N, DCI, Subtarget); case ISD::AND: return PerformANDCombine(N, DCI); + case ARMISD::BFI: return PerformBFICombine(N, DCI); case ARMISD::VMOVRRD: return PerformVMOVRRDCombine(N, DCI); case ARMISD::VMOVDRR: return PerformVMOVDRRCombine(N, DCI.DAG); case ISD::BUILD_VECTOR: return PerformBUILD_VECTORCombine(N, DCI.DAG); Modified: llvm/trunk/test/CodeGen/ARM/bfi.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/bfi.ll?rev=121746&r1=121745&r2=121746&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/bfi.ll (original) +++ llvm/trunk/test/CodeGen/ARM/bfi.ll Mon Dec 13 21:22:07 2010 @@ -49,3 +49,16 @@ %ins12 = or i32 %ins7, 3137 ret i32 %ins12 } + +; rdar://8458663 +define i32 @f5(i32 %a, i32 %b) nounwind { +entry: +; CHECK: f5: +; CHECK-NOT: bfc +; CHECK: bfi r0, r1, #20, #4 + %0 = and i32 %a, -15728641 + %1 = shl i32 %b, 20 + %2 = and i32 %1, 15728640 + %3 = or i32 %2, %0 + ret i32 %3 +} From isanbard at gmail.com Mon Dec 13 21:36:38 2010 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 14 Dec 2010 03:36:38 -0000 Subject: [llvm-commits] [llvm] r121747 - in /llvm/trunk: lib/Target/ARM/ARMAsmPrinter.cpp lib/Target/ARM/ARMCodeEmitter.cpp lib/Target/ARM/ARMISelDAGToDAG.cpp lib/Target/ARM/ARMInstrThumb.td lib/Target/ARM/ARMMCCodeEmitter.cpp lib/Target/ARM/AsmParser/ARMAsmParser.cpp lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp lib/Target/ARM/InstPrinter/ARMInstPrinter.h lib/Target/ARM/Thumb1RegisterInfo.cpp lib/Target/ARM/Thumb2SizeReduction.cpp utils/TableGen/EDEmitter.cpp Message-ID: <20101214033639.1C4662A6C12C@llvm.org> Author: void Date: Mon Dec 13 21:36:38 2010 New Revision: 121747 URL: http://llvm.org/viewvc/llvm-project?rev=121747&view=rev Log: The tLDR et al instructions were emitting either a reg/reg or reg/imm instruction based on the t_addrmode_s# mode and what it returned. There is some obvious badness to this. In particular, it's hard to do MC-encoding when the instruction may change out from underneath you after the t_addrmode_s# variable is finally resolved. The solution is to revert a long-ago change that merged the reg/reg and reg/imm versions. There is the addition of several new addressing modes. They no longer have extraneous operands associated with them. I.e., if it's reg/reg we don't have to have a dummy zero immediate tacked on to the SDNode. There are some obvious cleanups here, which will happen shortly. Modified: llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp llvm/trunk/lib/Target/ARM/ARMInstrThumb.td llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.h llvm/trunk/lib/Target/ARM/Thumb1RegisterInfo.cpp llvm/trunk/lib/Target/ARM/Thumb2SizeReduction.cpp llvm/trunk/utils/TableGen/EDEmitter.cpp Modified: llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp?rev=121747&r1=121746&r2=121747&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp Mon Dec 13 21:36:38 2010 @@ -1129,13 +1129,12 @@ } { MCInst TmpInst; - TmpInst.setOpcode(ARM::tSTR); + TmpInst.setOpcode(ARM::tSTRi); TmpInst.addOperand(MCOperand::CreateReg(ValReg)); TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); // The offset immediate is #4. The operand value is scaled by 4 for the // tSTR instruction. TmpInst.addOperand(MCOperand::CreateImm(1)); - TmpInst.addOperand(MCOperand::CreateReg(0)); // Predicate. TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); TmpInst.addOperand(MCOperand::CreateReg(0)); @@ -1312,13 +1311,12 @@ unsigned ScratchReg = MI->getOperand(1).getReg(); { MCInst TmpInst; - TmpInst.setOpcode(ARM::tLDR); + TmpInst.setOpcode(ARM::tLDRi); TmpInst.addOperand(MCOperand::CreateReg(ScratchReg)); TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); // The offset immediate is #8. The operand value is scaled by 4 for the - // tSTR instruction. + // tLDR instruction. TmpInst.addOperand(MCOperand::CreateImm(2)); - TmpInst.addOperand(MCOperand::CreateReg(0)); // Predicate. TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); TmpInst.addOperand(MCOperand::CreateReg(0)); @@ -1336,11 +1334,10 @@ } { MCInst TmpInst; - TmpInst.setOpcode(ARM::tLDR); + TmpInst.setOpcode(ARM::tLDRi); TmpInst.addOperand(MCOperand::CreateReg(ScratchReg)); TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); TmpInst.addOperand(MCOperand::CreateImm(1)); - TmpInst.addOperand(MCOperand::CreateReg(0)); // Predicate. TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); TmpInst.addOperand(MCOperand::CreateReg(0)); @@ -1348,10 +1345,9 @@ } { MCInst TmpInst; - TmpInst.setOpcode(ARM::tLDR); + TmpInst.setOpcode(ARM::tLDRr); TmpInst.addOperand(MCOperand::CreateReg(ARM::R7)); TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); - TmpInst.addOperand(MCOperand::CreateImm(0)); TmpInst.addOperand(MCOperand::CreateReg(0)); // Predicate. TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); Modified: llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp?rev=121747&r1=121746&r2=121747&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp Mon Dec 13 21:36:38 2010 @@ -193,7 +193,7 @@ const { return 0; } unsigned getSORegOpValue(const MachineInstr &MI, unsigned Op) const { return 0; } - unsigned getTAddrModeRegRegOpValue(const MachineInstr &MI, unsigned Op) + unsigned getThumbAddrModeRegRegOpValue(const MachineInstr &MI, unsigned Op) const { return 0; } unsigned getT2AddrModeImm12OpValue(const MachineInstr &MI, unsigned Op) const { return 0; } @@ -265,6 +265,8 @@ const { return 0; } uint32_t getAddrModeSOpValue(const MachineInstr &MI, unsigned Op) const { return 0; } + uint32_t getAddrModeISOpValue(const MachineInstr &MI, unsigned Op) + const { return 0; } uint32_t getAddrModePCOpValue(const MachineInstr &MI, unsigned Op) const { return 0; } uint32_t getAddrMode5OpValue(const MachineInstr &MI, unsigned Op) const { Modified: llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp?rev=121747&r1=121746&r2=121747&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp Mon Dec 13 21:36:38 2010 @@ -130,18 +130,24 @@ bool SelectAddrModePC(SDValue N, SDValue &Offset, SDValue &Label); + // Thumb Addressing Modes: bool SelectThumbAddrModeRR(SDValue N, SDValue &Base, SDValue &Offset); - bool SelectThumbAddrModeRI5(SDValue N, unsigned Scale, - SDValue &Base, SDValue &OffImm, - SDValue &Offset); - bool SelectThumbAddrModeS1(SDValue N, SDValue &Base, - SDValue &OffImm, SDValue &Offset); - bool SelectThumbAddrModeS2(SDValue N, SDValue &Base, - SDValue &OffImm, SDValue &Offset); - bool SelectThumbAddrModeS4(SDValue N, SDValue &Base, - SDValue &OffImm, SDValue &Offset); + bool SelectThumbAddrModeRI(SDValue N, SDValue &Base, SDValue &Offset, + unsigned Scale); + bool SelectThumbAddrModeRI5S1(SDValue N, SDValue &Base, SDValue &Offset); + bool SelectThumbAddrModeRI5S2(SDValue N, SDValue &Base, SDValue &Offset); + bool SelectThumbAddrModeRI5S4(SDValue N, SDValue &Base, SDValue &Offset); + bool SelectThumbAddrModeImm5S(SDValue N, unsigned Scale, SDValue &Base, + SDValue &OffImm); + bool SelectThumbAddrModeImm5S1(SDValue N, SDValue &Base, + SDValue &OffImm); + bool SelectThumbAddrModeImm5S2(SDValue N, SDValue &Base, + SDValue &OffImm); + bool SelectThumbAddrModeImm5S4(SDValue N, SDValue &Base, + SDValue &OffImm); bool SelectThumbAddrModeSP(SDValue N, SDValue &Base, SDValue &OffImm); + // Thumb 2 Addressing Modes: bool SelectT2ShifterOperandReg(SDValue N, SDValue &BaseReg, SDValue &Opc); bool SelectT2AddrModeImm12(SDValue N, SDValue &Base, SDValue &OffImm); @@ -872,9 +878,16 @@ MVT::i32); return true; } + return false; } + +//===----------------------------------------------------------------------===// +// Thumb Addressing Modes +//===----------------------------------------------------------------------===// + + bool ARMDAGToDAGISel::SelectThumbAddrModeRR(SDValue N, SDValue &Base, SDValue &Offset){ // FIXME dl should come from the parent load or store, not the address @@ -893,13 +906,13 @@ } bool -ARMDAGToDAGISel::SelectThumbAddrModeRI5(SDValue N, - unsigned Scale, SDValue &Base, - SDValue &OffImm, SDValue &Offset) { +ARMDAGToDAGISel::SelectThumbAddrModeRI(SDValue N, SDValue &Base, + SDValue &Offset, unsigned Scale) { if (Scale == 4) { SDValue TmpBase, TmpOffImm; if (SelectThumbAddrModeSP(N, TmpBase, TmpOffImm)) return false; // We want to select tLDRspi / tSTRspi instead. + if (N.getOpcode() == ARMISD::Wrapper && N.getOperand(0).getOpcode() == ISD::TargetConstantPool) return false; // We want to select tLDRpci instead. @@ -907,14 +920,13 @@ if (N.getOpcode() != ISD::ADD) { if (N.getOpcode() == ARMISD::Wrapper && - !(Subtarget->useMovt() && - N.getOperand(0).getOpcode() == ISD::TargetGlobalAddress)) { + (!Subtarget->useMovt() || + N.getOperand(0).getOpcode() != ISD::TargetGlobalAddress)) Base = N.getOperand(0); - } else + else Base = N; Offset = CurDAG->getRegister(0, MVT::i32); - OffImm = CurDAG->getTargetConstant(0, MVT::i32); return true; } @@ -925,6 +937,68 @@ (RHSR && RHSR->getReg() == ARM::SP)) { Base = N; Offset = CurDAG->getRegister(0, MVT::i32); + return true; + } + + if (ConstantSDNode *RHS = dyn_cast(N.getOperand(1))) { + int RHSC = (int)RHS->getZExtValue(); + + if ((RHSC & (Scale - 1)) == 0) { // The constant is implicitly multiplied. + RHSC /= Scale; + + if (RHSC >= 0 && RHSC < 32) + return false; + } + } + + Base = N.getOperand(0); + Offset = N.getOperand(1); + return true; +} + +bool +ARMDAGToDAGISel::SelectThumbAddrModeRI5S1(SDValue N, + SDValue &Base, + SDValue &Offset) { + return SelectThumbAddrModeRI(N, Base, Offset, 1); +} + +bool +ARMDAGToDAGISel::SelectThumbAddrModeRI5S2(SDValue N, + SDValue &Base, + SDValue &Offset) { + return SelectThumbAddrModeRI(N, Base, Offset, 2); +} + +bool +ARMDAGToDAGISel::SelectThumbAddrModeRI5S4(SDValue N, + SDValue &Base, + SDValue &Offset) { + return SelectThumbAddrModeRI(N, Base, Offset, 4); +} + +bool +ARMDAGToDAGISel::SelectThumbAddrModeImm5S(SDValue N, unsigned Scale, + SDValue &Base, SDValue &OffImm) { + if (Scale == 4) { + SDValue TmpBase, TmpOffImm; + if (SelectThumbAddrModeSP(N, TmpBase, TmpOffImm)) + return false; // We want to select tLDRspi / tSTRspi instead. + + if (N.getOpcode() == ARMISD::Wrapper && + N.getOperand(0).getOpcode() == ISD::TargetConstantPool) + return false; // We want to select tLDRpci instead. + } + + if (N.getOpcode() != ISD::ADD) { + if (N.getOpcode() == ARMISD::Wrapper && + !(Subtarget->useMovt() && + N.getOperand(0).getOpcode() == ISD::TargetGlobalAddress)) { + Base = N.getOperand(0); + } else { + Base = N; + } + OffImm = CurDAG->getTargetConstant(0, MVT::i32); return true; } @@ -932,11 +1006,12 @@ // If the RHS is + imm5 * scale, fold into addr mode. if (ConstantSDNode *RHS = dyn_cast(N.getOperand(1))) { int RHSC = (int)RHS->getZExtValue(); - if ((RHSC & (Scale-1)) == 0) { // The constant is implicitly multiplied. + + if ((RHSC & (Scale - 1)) == 0) { // The constant is implicitly multiplied. RHSC /= Scale; + if (RHSC >= 0 && RHSC < 32) { Base = N.getOperand(0); - Offset = CurDAG->getRegister(0, MVT::i32); OffImm = CurDAG->getTargetConstant(RHSC, MVT::i32); return true; } @@ -944,27 +1019,26 @@ } Base = N.getOperand(0); - Offset = N.getOperand(1); OffImm = CurDAG->getTargetConstant(0, MVT::i32); return true; } -bool ARMDAGToDAGISel::SelectThumbAddrModeS1(SDValue N, - SDValue &Base, SDValue &OffImm, - SDValue &Offset) { - return SelectThumbAddrModeRI5(N, 1, Base, OffImm, Offset); -} - -bool ARMDAGToDAGISel::SelectThumbAddrModeS2(SDValue N, - SDValue &Base, SDValue &OffImm, - SDValue &Offset) { - return SelectThumbAddrModeRI5(N, 2, Base, OffImm, Offset); -} - -bool ARMDAGToDAGISel::SelectThumbAddrModeS4(SDValue N, - SDValue &Base, SDValue &OffImm, - SDValue &Offset) { - return SelectThumbAddrModeRI5(N, 4, Base, OffImm, Offset); +bool +ARMDAGToDAGISel::SelectThumbAddrModeImm5S4(SDValue N, SDValue &Base, + SDValue &OffImm) { + return SelectThumbAddrModeImm5S(N, 4, Base, OffImm); +} + +bool +ARMDAGToDAGISel::SelectThumbAddrModeImm5S2(SDValue N, SDValue &Base, + SDValue &OffImm) { + return SelectThumbAddrModeImm5S(N, 2, Base, OffImm); +} + +bool +ARMDAGToDAGISel::SelectThumbAddrModeImm5S1(SDValue N, SDValue &Base, + SDValue &OffImm) { + return SelectThumbAddrModeImm5S(N, 1, Base, OffImm); } bool ARMDAGToDAGISel::SelectThumbAddrModeSP(SDValue N, @@ -1003,6 +1077,12 @@ return false; } + +//===----------------------------------------------------------------------===// +// Thumb 2 Addressing Modes +//===----------------------------------------------------------------------===// + + bool ARMDAGToDAGISel::SelectT2ShifterOperandReg(SDValue N, SDValue &BaseReg, SDValue &Opc) { if (DisableShifterOp) Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrThumb.td?rev=121747&r1=121746&r2=121747&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrThumb.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrThumb.td Mon Dec 13 21:36:38 2010 @@ -94,8 +94,13 @@ let EncoderMethod = "getThumbBLXTargetOpValue"; } -def MemModeThumbAsmOperand : AsmOperandClass { - let Name = "MemModeThumb"; +def MemModeRegThumbAsmOperand : AsmOperandClass { + let Name = "MemModeRegThumb"; + let SuperClasses = []; +} + +def MemModeImmThumbAsmOperand : AsmOperandClass { + let Name = "MemModeImmThumb"; let SuperClasses = []; } @@ -103,42 +108,64 @@ // def t_addrmode_rr : Operand, ComplexPattern { - let EncoderMethod = "getTAddrModeRegRegOpValue"; + let EncoderMethod = "getThumbAddrModeRegRegOpValue"; + let PrintMethod = "printThumbAddrModeRROperand"; + let MIOperandInfo = (ops tGPR:$base, tGPR:$offsreg); +} + +// t_addrmode_rrs := reg + reg +// +def t_addrmode_rrs1 : Operand, + ComplexPattern { + let EncoderMethod = "getThumbAddrModeRegRegOpValue"; let PrintMethod = "printThumbAddrModeRROperand"; let MIOperandInfo = (ops tGPR:$base, tGPR:$offsreg); + let ParserMatchClass = MemModeRegThumbAsmOperand; } -// t_addrmode_s4 := reg + reg -// reg + imm5 * 4 +def t_addrmode_rrs2 : Operand, + ComplexPattern { + let EncoderMethod = "getThumbAddrModeRegRegOpValue"; + let PrintMethod = "printThumbAddrModeRROperand"; + let MIOperandInfo = (ops tGPR:$base, tGPR:$offsreg); + let ParserMatchClass = MemModeRegThumbAsmOperand; +} +def t_addrmode_rrs4 : Operand, + ComplexPattern { + let EncoderMethod = "getThumbAddrModeRegRegOpValue"; + let PrintMethod = "printThumbAddrModeRROperand"; + let MIOperandInfo = (ops tGPR:$base, tGPR:$offsreg); + let ParserMatchClass = MemModeRegThumbAsmOperand; +} + +// t_addrmode_is4 := reg + imm5 * 4 // -def t_addrmode_s4 : Operand, - ComplexPattern { - let EncoderMethod = "getAddrModeSOpValue"; - let PrintMethod = "printThumbAddrModeS4Operand"; - let MIOperandInfo = (ops tGPR:$base, i32imm:$offsimm, tGPR:$offsreg); - let ParserMatchClass = MemModeThumbAsmOperand; +def t_addrmode_is4 : Operand, + ComplexPattern { + let EncoderMethod = "getAddrModeISOpValue"; + let PrintMethod = "printThumbAddrModeImm5S4Operand"; + let MIOperandInfo = (ops tGPR:$base, i32imm:$offsimm); + let ParserMatchClass = MemModeImmThumbAsmOperand; } -// t_addrmode_s2 := reg + reg -// reg + imm5 * 2 +// t_addrmode_is2 := reg + imm5 * 2 // -def t_addrmode_s2 : Operand, - ComplexPattern { - let EncoderMethod = "getAddrModeSOpValue"; - let PrintMethod = "printThumbAddrModeS2Operand"; - let MIOperandInfo = (ops tGPR:$base, i32imm:$offsimm, tGPR:$offsreg); - let ParserMatchClass = MemModeThumbAsmOperand; +def t_addrmode_is2 : Operand, + ComplexPattern { + let EncoderMethod = "getAddrModeISOpValue"; + let PrintMethod = "printThumbAddrModeImm5S2Operand"; + let MIOperandInfo = (ops tGPR:$base, i32imm:$offsimm); + let ParserMatchClass = MemModeImmThumbAsmOperand; } -// t_addrmode_s1 := reg + reg -// reg + imm5 +// t_addrmode_is1 := reg + imm5 // -def t_addrmode_s1 : Operand, - ComplexPattern { - let EncoderMethod = "getAddrModeSOpValue"; - let PrintMethod = "printThumbAddrModeS1Operand"; - let MIOperandInfo = (ops tGPR:$base, i32imm:$offsimm, tGPR:$offsreg); - let ParserMatchClass = MemModeThumbAsmOperand; +def t_addrmode_is1 : Operand, + ComplexPattern { + let EncoderMethod = "getAddrModeISOpValue"; + let PrintMethod = "printThumbAddrModeImm5S1Operand"; + let MIOperandInfo = (ops tGPR:$base, i32imm:$offsimm); + let ParserMatchClass = MemModeImmThumbAsmOperand; } // t_addrmode_sp := sp + imm8 * 4 @@ -148,14 +175,14 @@ let EncoderMethod = "getAddrModeThumbSPOpValue"; let PrintMethod = "printThumbAddrModeSPOperand"; let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm); - let ParserMatchClass = MemModeThumbAsmOperand; + let ParserMatchClass = MemModeImmThumbAsmOperand; } // t_addrmode_pc :=