aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
diff options
context:
space:
mode:
authorNikita Popov <npopov@redhat.com>2024-04-26 12:00:26 +0900
committerNikita Popov <npopov@redhat.com>2024-04-26 12:05:12 +0900
commitd26002ac38ee1dea32053e7d12f1bb5dc420ac2d (patch)
tree680cbe9e2e766eec63dd9149850e5f3f28b047d1 /llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
parentc7f4b3e1bd5cab43d6f733a5107b2946c76bc0bb (diff)
downloadllvm-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.cpp9
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.