aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/CodeGenPrepare.cpp
diff options
context:
space:
mode:
authorKrzysztof Pszeniczny <krzysztof.pszeniczny@gmail.com>2018-10-19 19:02:16 +0000
committerKrzysztof Pszeniczny <krzysztof.pszeniczny@gmail.com>2018-10-19 19:02:16 +0000
commit2bfe759a8d7f4e544ac0f079d447f33c0b4dcf9c (patch)
tree67b55e22e6a7f0754d8f43626ed25679dddf4488 /llvm/lib/CodeGen/CodeGenPrepare.cpp
parentb3d203ff7f308cc5675f095654d0cda905bf95bf (diff)
downloadllvm-2bfe759a8d7f4e544ac0f079d447f33c0b4dcf9c.zip
llvm-2bfe759a8d7f4e544ac0f079d447f33c0b4dcf9c.tar.gz
llvm-2bfe759a8d7f4e544ac0f079d447f33c0b4dcf9c.tar.bz2
Fix a use-after-RAUW bug in large GEP splitting
Summary: Large GEP splitting, introduced in rL332015, uses a `DenseMap<AssertingVH<Value>, ...>`. This causes an assertion to fail (in debug builds) or undefined behaviour to occur (in release builds) when a value is RAUWed. This manifested itself in the 7zip benchmark from the llvm test suite built on ARM with `-fstrict-vtable-pointers` enabled while RAUWing invariant group launders and splits in CodeGenPrepare. This patch merges the large offsets of the argument and the result of an invariant.group strip/launder intrinsic before RAUWing. Reviewers: Prazek, javed.absar, haicheng, efriedma Reviewed By: Prazek, efriedma Subscribers: kristof.beyls, hiraditya, llvm-commits Differential Revision: https://reviews.llvm.org/D51936 llvm-svn: 344802
Diffstat (limited to 'llvm/lib/CodeGen/CodeGenPrepare.cpp')
-rw-r--r--llvm/lib/CodeGen/CodeGenPrepare.cpp17
1 files changed, 14 insertions, 3 deletions
diff --git a/llvm/lib/CodeGen/CodeGenPrepare.cpp b/llvm/lib/CodeGen/CodeGenPrepare.cpp
index dfbfae8..fa5cc4d 100644
--- a/llvm/lib/CodeGen/CodeGenPrepare.cpp
+++ b/llvm/lib/CodeGen/CodeGenPrepare.cpp
@@ -1721,11 +1721,22 @@ bool CodeGenPrepare::optimizeCallInst(CallInst *CI, bool &ModifiedDT) {
return true;
}
case Intrinsic::launder_invariant_group:
- case Intrinsic::strip_invariant_group:
- II->replaceAllUsesWith(II->getArgOperand(0));
+ case Intrinsic::strip_invariant_group: {
+ Value *ArgVal = II->getArgOperand(0);
+ auto it = LargeOffsetGEPMap.find(II);
+ if (it != LargeOffsetGEPMap.end()) {
+ // Merge entries in LargeOffsetGEPMap to reflect the RAUW.
+ // Make sure not to have to deal with iterator invalidation
+ // after possibly adding ArgVal to LargeOffsetGEPMap.
+ auto GEPs = std::move(it->second);
+ LargeOffsetGEPMap[ArgVal].append(GEPs.begin(), GEPs.end());
+ LargeOffsetGEPMap.erase(II);
+ }
+
+ II->replaceAllUsesWith(ArgVal);
II->eraseFromParent();
return true;
-
+ }
case Intrinsic::cttz:
case Intrinsic::ctlz:
// If counting zeros is expensive, try to avoid it.