diff options
author | Nikita Popov <npopov@redhat.com> | 2024-04-26 12:00:26 +0900 |
---|---|---|
committer | Nikita Popov <npopov@redhat.com> | 2024-04-26 12:05:12 +0900 |
commit | d26002ac38ee1dea32053e7d12f1bb5dc420ac2d (patch) | |
tree | 680cbe9e2e766eec63dd9149850e5f3f28b047d1 /llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp | |
parent | c7f4b3e1bd5cab43d6f733a5107b2946c76bc0bb (diff) | |
download | llvm-d26002ac38ee1dea32053e7d12f1bb5dc420ac2d.zip llvm-d26002ac38ee1dea32053e7d12f1bb5dc420ac2d.tar.gz llvm-d26002ac38ee1dea32053e7d12f1bb5dc420ac2d.tar.bz2 |
[InstCombine] Fix use-after-free in OptimizePointerDifference()
EmitGEPOffset() may remove the old GEP, so be sure to cache the
inbounds flag beforehand.
Diffstat (limited to 'llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp')
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp | 9 |
1 files changed, 6 insertions, 3 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp index a3775fa..51ac773 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp @@ -2002,26 +2002,29 @@ Value *InstCombinerImpl::OptimizePointerDifference(Value *LHS, Value *RHS, return nullptr; // To avoid duplicating the offset arithmetic, rewrite the GEP to use the - // computed offset. + // computed offset. This may erase the original GEP, so be sure to cache the + // inbounds flag before emitting the offset. // TODO: We should probably do this even if there is only one GEP. bool RewriteGEPs = GEP2 != nullptr; // Emit the offset of the GEP and an intptr_t. + bool GEP1IsInBounds = GEP1->isInBounds(); Value *Result = EmitGEPOffset(GEP1, RewriteGEPs); // If this is a single inbounds GEP and the original sub was nuw, // then the final multiplication is also nuw. if (auto *I = dyn_cast<Instruction>(Result)) - if (IsNUW && !GEP2 && !Swapped && GEP1->isInBounds() && + if (IsNUW && !GEP2 && !Swapped && GEP1IsInBounds && I->getOpcode() == Instruction::Mul) I->setHasNoUnsignedWrap(); // If we have a 2nd GEP of the same base pointer, subtract the offsets. // If both GEPs are inbounds, then the subtract does not have signed overflow. if (GEP2) { + bool GEP2IsInBounds = GEP2->isInBounds(); Value *Offset = EmitGEPOffset(GEP2, RewriteGEPs); Result = Builder.CreateSub(Result, Offset, "gepdiff", /* NUW */ false, - GEP1->isInBounds() && GEP2->isInBounds()); + GEP1IsInBounds && GEP2IsInBounds); } // If we have p - gep(p, ...) then we have to negate the result. |