|
50 | 50 | #include "llvm/IR/DebugLoc.h" |
51 | 51 | #include "llvm/IR/Dominators.h" |
52 | 52 | #include "llvm/IR/Function.h" |
53 | | -#include "llvm/IR/IRBuilder.h" |
54 | 53 | #include "llvm/IR/InstrTypes.h" |
55 | 54 | #include "llvm/IR/Instruction.h" |
56 | 55 | #include "llvm/IR/Instructions.h" |
@@ -2291,39 +2290,29 @@ bool GVNPass::processLoad(LoadInst *L) { |
2291 | 2290 | // Attempt to process masked loads which have loaded from |
2292 | 2291 | // masked stores with the same mask |
2293 | 2292 | bool GVNPass::processMaskedLoad(IntrinsicInst *I) { |
2294 | | - Value *Mask = I->getOperand(2); |
2295 | | - Value *Passthrough = I->getOperand(3); |
2296 | | - |
| 2293 | + if (!MD) |
| 2294 | + return false; |
2297 | 2295 | MemDepResult Dep = MD->getDependency(I); |
2298 | 2296 | Instruction *DepInst = Dep.getInst(); |
2299 | | - if (!DepInst || !Dep.isLocal()) |
| 2297 | + if (!DepInst || !Dep.isLocal() || !Dep.isDef()) |
2300 | 2298 | return false; |
2301 | 2299 |
|
| 2300 | + Value *Mask = I->getOperand(2); |
| 2301 | + Value *Passthrough = I->getOperand(3); |
2302 | 2302 | Value *StoreVal; |
2303 | | - if (!match(DepInst, |
2304 | | - m_Intrinsic<Intrinsic::masked_store>(m_Value(StoreVal), m_Value(), |
2305 | | - m_Value(), m_Specific(Mask)))) |
| 2303 | + if (!match(DepInst, m_MaskedStore(m_Value(StoreVal), m_Value(), m_Value(), |
| 2304 | + m_Specific(Mask)))) |
2306 | 2305 | return false; |
2307 | 2306 |
|
2308 | | - Value *OpToForward = nullptr; |
2309 | | - if (match(StoreVal, m_MaskedLoad(m_Value(), m_Value(), m_Specific(Mask), |
2310 | | - m_Specific(Passthrough)))) |
2311 | | - // For MaskedLoad->MaskedStore->MaskedLoad, the mask must be the same for |
2312 | | - // all three instructions. The Passthrough on the two loads must also be the |
2313 | | - // same. |
2314 | | - OpToForward = AvailableValue::get(StoreVal).getSimpleValue(); |
2315 | | - else if (match(StoreVal, m_Intrinsic<Intrinsic::masked_load>())) |
2316 | | - return false; |
2317 | | - else { |
2318 | | - // MaskedStore(Op, ptr, mask)->MaskedLoad(ptr, mask, passthrough) can be |
2319 | | - // replaced with MaskedStore(Op, ptr, mask)->select(mask, Op, passthrough) |
2320 | | - IRBuilder<> Builder(I); |
2321 | | - OpToForward = Builder.CreateSelect(Mask, StoreVal, Passthrough); |
2322 | | - } |
| 2307 | + // Remove the load but generate a select for the passthrough |
| 2308 | + Value *OpToForward = llvm::SelectInst::Create(Mask, StoreVal, Passthrough, "", |
| 2309 | + I->getIterator()); |
2323 | 2310 |
|
2324 | | - I->replaceAllUsesWith(OpToForward); |
2325 | 2311 | ICF->removeUsersOf(I); |
| 2312 | + I->replaceAllUsesWith(OpToForward); |
2326 | 2313 | salvageAndRemoveInstruction(I); |
| 2314 | + if (OpToForward->getType()->isPtrOrPtrVectorTy()) |
| 2315 | + MD->invalidateCachedPointerInfo(OpToForward); |
2327 | 2316 | ++NumGVNLoad; |
2328 | 2317 | return true; |
2329 | 2318 | } |
@@ -2775,10 +2764,9 @@ bool GVNPass::processInstruction(Instruction *I) { |
2775 | 2764 | return false; |
2776 | 2765 | } |
2777 | 2766 |
|
2778 | | - if (auto *II = dyn_cast<IntrinsicInst>(I)) |
2779 | | - if (II && II->getIntrinsicID() == Intrinsic::masked_load) |
2780 | | - if (processMaskedLoad(II)) |
2781 | | - return true; |
| 2767 | + if (match(I, m_Intrinsic<Intrinsic::masked_load>()) && |
| 2768 | + processMaskedLoad(cast<IntrinsicInst>(I))) |
| 2769 | + return true; |
2782 | 2770 |
|
2783 | 2771 | // For conditional branches, we can perform simple conditional propagation on |
2784 | 2772 | // the condition value itself. |
|
0 commit comments