diff options
Diffstat (limited to 'llvm/lib/Target/PowerPC/PPCVSXSwapRemoval.cpp')
| -rw-r--r-- | llvm/lib/Target/PowerPC/PPCVSXSwapRemoval.cpp | 30 |
1 files changed, 27 insertions, 3 deletions
diff --git a/llvm/lib/Target/PowerPC/PPCVSXSwapRemoval.cpp b/llvm/lib/Target/PowerPC/PPCVSXSwapRemoval.cpp index c3729da0b07b..ff251f55afff 100644 --- a/llvm/lib/Target/PowerPC/PPCVSXSwapRemoval.cpp +++ b/llvm/lib/Target/PowerPC/PPCVSXSwapRemoval.cpp @@ -254,10 +254,11 @@ bool PPCVSXSwapRemoval::gatherVectorInstructions() { if (!MO.isReg()) continue; Register Reg = MO.getReg(); - if (isAnyVecReg(Reg, Partial)) { + // All operands need to be checked because there are instructions that + // operate on a partial register and produce a full register (such as + // XXPERMDIs). + if (isAnyVecReg(Reg, Partial)) RelevantInstr = true; - break; - } } if (!RelevantInstr) @@ -689,6 +690,29 @@ void PPCVSXSwapRemoval::recordUnoptimizableWebs() { LLVM_DEBUG(UseMI.dump()); LLVM_DEBUG(dbgs() << "\n"); } + + // It is possible that the load feeds a swap and that swap feeds a + // store. In such a case, the code is actually trying to store a swapped + // vector. We must reject such webs. + if (SwapVector[UseIdx].IsSwap && !SwapVector[UseIdx].IsLoad && + !SwapVector[UseIdx].IsStore) { + Register SwapDefReg = UseMI.getOperand(0).getReg(); + for (MachineInstr &UseOfUseMI : + MRI->use_nodbg_instructions(SwapDefReg)) { + int UseOfUseIdx = SwapMap[&UseOfUseMI]; + if (SwapVector[UseOfUseIdx].IsStore) { + SwapVector[Repr].WebRejected = 1; + LLVM_DEBUG( + dbgs() << format( + "Web %d rejected for load/swap feeding a store\n", Repr)); + LLVM_DEBUG(dbgs() << " def " << EntryIdx << ": "); + LLVM_DEBUG(MI->dump()); + LLVM_DEBUG(dbgs() << " use " << UseIdx << ": "); + LLVM_DEBUG(UseMI.dump()); + LLVM_DEBUG(dbgs() << "\n"); + } + } + } } // Reject webs that contain swapping stores that are fed by something |
