diff options
| author | Nikita Popov <npopov@redhat.com> | 2022-02-25 17:36:29 +0100 |
|---|---|---|
| committer | Nikita Popov <npopov@redhat.com> | 2022-03-04 11:39:11 +0100 |
| commit | d3a52089eb3e9d8b41dd8ca08d3d532dee78c4e8 (patch) | |
| tree | 4a9ac90c6865b9f604b8711507cb70f14cd991be /llvm/lib/Transforms/Scalar/MergeICmps.cpp | |
| parent | f9331c9a2c8746bc1a63d45c59019545e376b3e0 (diff) | |
Reapply [MergeICmps] Don't require GEP
Recommit without changes over 53abe3ff66a54117308352d379837c7d3229f8d6,
which addressed the cause of the reported crash.
-----
With opaque pointers, the zero-offset load will generally not use
a GEP. Allow a direct load without GEP, which is treated the same
way as a zero-offset GEP.
Diffstat (limited to 'llvm/lib/Transforms/Scalar/MergeICmps.cpp')
| -rw-r--r-- | llvm/lib/Transforms/Scalar/MergeICmps.cpp | 52 |
1 files changed, 32 insertions, 20 deletions
diff --git a/llvm/lib/Transforms/Scalar/MergeICmps.cpp b/llvm/lib/Transforms/Scalar/MergeICmps.cpp index 1c1026b097f8..ce01ae5b2692 100644 --- a/llvm/lib/Transforms/Scalar/MergeICmps.cpp +++ b/llvm/lib/Transforms/Scalar/MergeICmps.cpp @@ -144,31 +144,33 @@ BCEAtom visitICmpLoadOperand(Value *const Val, BaseIdentifier &BaseId) { LLVM_DEBUG(dbgs() << "volatile or atomic\n"); return {}; } - Value *const Addr = LoadI->getOperand(0); + Value *Addr = LoadI->getOperand(0); if (Addr->getType()->getPointerAddressSpace() != 0) { LLVM_DEBUG(dbgs() << "from non-zero AddressSpace\n"); return {}; } - auto *const GEP = dyn_cast<GetElementPtrInst>(Addr); - if (!GEP) - return {}; - LLVM_DEBUG(dbgs() << "GEP\n"); - if (GEP->isUsedOutsideOfBlock(LoadI->getParent())) { - LLVM_DEBUG(dbgs() << "used outside of block\n"); - return {}; - } - const auto &DL = GEP->getModule()->getDataLayout(); - if (!isDereferenceablePointer(GEP, LoadI->getType(), DL)) { + const auto &DL = LoadI->getModule()->getDataLayout(); + if (!isDereferenceablePointer(Addr, LoadI->getType(), DL)) { LLVM_DEBUG(dbgs() << "not dereferenceable\n"); // We need to make sure that we can do comparison in any order, so we // require memory to be unconditionnally dereferencable. return {}; } - APInt Offset = APInt(DL.getPointerTypeSizeInBits(GEP->getType()), 0); - if (!GEP->accumulateConstantOffset(DL, Offset)) - return {}; - return BCEAtom(GEP, LoadI, BaseId.getBaseId(GEP->getPointerOperand()), - Offset); + + APInt Offset = APInt(DL.getPointerTypeSizeInBits(Addr->getType()), 0); + Value *Base = Addr; + auto *GEP = dyn_cast<GetElementPtrInst>(Addr); + if (GEP) { + LLVM_DEBUG(dbgs() << "GEP\n"); + if (GEP->isUsedOutsideOfBlock(LoadI->getParent())) { + LLVM_DEBUG(dbgs() << "used outside of block\n"); + return {}; + } + if (!GEP->accumulateConstantOffset(DL, Offset)) + return {}; + Base = GEP->getPointerOperand(); + } + return BCEAtom(GEP, LoadI, BaseId.getBaseId(Base), Offset); } // A comparison between two BCE atoms, e.g. `a == o.a` in the example at the @@ -367,8 +369,11 @@ Optional<BCECmpBlock> visitCmpBlock(Value *const Val, BasicBlock *const Block, return None; BCECmpBlock::InstructionSet BlockInsts( - {Result->Lhs.GEP, Result->Rhs.GEP, Result->Lhs.LoadI, Result->Rhs.LoadI, - Result->CmpI, BranchI}); + {Result->Lhs.LoadI, Result->Rhs.LoadI, Result->CmpI, BranchI}); + if (Result->Lhs.GEP) + BlockInsts.insert(Result->Lhs.GEP); + if (Result->Rhs.GEP) + BlockInsts.insert(Result->Rhs.GEP); return BCECmpBlock(std::move(*Result), Block, BlockInsts); } @@ -603,8 +608,15 @@ static BasicBlock *mergeComparisons(ArrayRef<BCECmpBlock> Comparisons, NextCmpBlock->getParent(), InsertBefore); IRBuilder<> Builder(BB); // Add the GEPs from the first BCECmpBlock. - Value *const Lhs = Builder.Insert(FirstCmp.Lhs().GEP->clone()); - Value *const Rhs = Builder.Insert(FirstCmp.Rhs().GEP->clone()); + Value *Lhs, *Rhs; + if (FirstCmp.Lhs().GEP) + Lhs = Builder.Insert(FirstCmp.Lhs().GEP->clone()); + else + Lhs = FirstCmp.Lhs().LoadI->getPointerOperand(); + if (FirstCmp.Rhs().GEP) + Rhs = Builder.Insert(FirstCmp.Rhs().GEP->clone()); + else + Rhs = FirstCmp.Rhs().LoadI->getPointerOperand(); Value *IsEqual = nullptr; LLVM_DEBUG(dbgs() << "Merging " << Comparisons.size() << " comparisons -> " |
