[llvm] r344802 - Fix a use-after-RAUW bug in large GEP splitting
Krzysztof Pszeniczny via llvm-commits
llvm-commits at lists.llvm.org
Fri Oct 19 12:02:16 PDT 2018
Author: kpszeniczny
Date: Fri Oct 19 12:02:16 2018
New Revision: 344802
URL: http://llvm.org/viewvc/llvm-project?rev=344802&view=rev
Log:
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
Modified:
llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp
llvm/trunk/test/Transforms/CodeGenPrepare/AArch64/large-offset-gep.ll
Modified: llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp?rev=344802&r1=344801&r2=344802&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp (original)
+++ llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp Fri Oct 19 12:02:16 2018
@@ -1721,11 +1721,22 @@ bool CodeGenPrepare::optimizeCallInst(Ca
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.
Modified: llvm/trunk/test/Transforms/CodeGenPrepare/AArch64/large-offset-gep.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/CodeGenPrepare/AArch64/large-offset-gep.ll?rev=344802&r1=344801&r2=344802&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/CodeGenPrepare/AArch64/large-offset-gep.ll (original)
+++ llvm/trunk/test/Transforms/CodeGenPrepare/AArch64/large-offset-gep.ll Fri Oct 19 12:02:16 2018
@@ -145,3 +145,31 @@ while_body:
while_end:
ret void
}
+
+declare i8* @llvm.strip.invariant.group.p0i8(i8*)
+
+define void @test_invariant_group(i32) {
+; CHECK-LABEL: test_invariant_group
+ br i1 undef, label %8, label %7
+
+; <label>:2: ; preds = %8, %2
+ br i1 undef, label %2, label %7
+
+; <label>:3: ; preds = %8
+ %4 = getelementptr inbounds i8, i8* %9, i32 40000
+ %5 = bitcast i8* %4 to i64*
+ br i1 undef, label %7, label %6
+
+; <label>:6: ; preds = %3
+ store i64 1, i64* %5, align 8
+ br label %7
+
+; <label>:7: ; preds = %6, %3, %2, %1
+ ret void
+
+; <label>:8: ; preds = %1
+ %9 = call i8* @llvm.strip.invariant.group.p0i8(i8* nonnull undef)
+ %10 = icmp eq i32 %0, 0
+ br i1 %10, label %3, label %2
+}
+
More information about the llvm-commits
mailing list