[PATCH] D51936: Fix a use-after-RAUW bug in large GEP splitting

Krzysztof Pszeniczny via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 11 09:02:57 PDT 2018


amharc created this revision.
amharc added a reviewer: Prazek.
Herald added a reviewer: javed.absar.
Herald added subscribers: llvm-commits, hiraditya, kristof.beyls.

Large GEP splitting, introduced in https://reviews.llvm.org/rL332015, uses a `DenseMap<AssertingVH<Value>, ...>` instead of `ValueMap<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.


Repository:
  rL LLVM

https://reviews.llvm.org/D51936

Files:
  llvm/lib/CodeGen/CodeGenPrepare.cpp
  llvm/test/Transforms/CodeGenPrepare/AArch64/large-offset-gep.ll


Index: llvm/test/Transforms/CodeGenPrepare/AArch64/large-offset-gep.ll
===================================================================
--- llvm/test/Transforms/CodeGenPrepare/AArch64/large-offset-gep.ll
+++ llvm/test/Transforms/CodeGenPrepare/AArch64/large-offset-gep.ll
@@ -145,3 +145,31 @@
 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
+}
+
Index: llvm/lib/CodeGen/CodeGenPrepare.cpp
===================================================================
--- llvm/lib/CodeGen/CodeGenPrepare.cpp
+++ llvm/lib/CodeGen/CodeGenPrepare.cpp
@@ -278,8 +278,8 @@
     /// Keep track of GEPs accessing the same data structures such as structs or
     /// arrays that are candidates to be split later because of their large
     /// size.
-    DenseMap<
-        AssertingVH<Value>,
+    ValueMap<
+        Value*,
         SmallVector<std::pair<AssertingVH<GetElementPtrInst>, int64_t>, 32>>
         LargeOffsetGEPMap;
 
@@ -4979,7 +4979,7 @@
 // their offsets are smaller enough to fit into the addressing mode.
 bool CodeGenPrepare::splitLargeGEPOffsets() {
   bool Changed = false;
-  for (auto &Entry : LargeOffsetGEPMap) {
+  for (const auto &Entry : LargeOffsetGEPMap) {
     Value *OldBase = Entry.first;
     SmallVectorImpl<std::pair<AssertingVH<GetElementPtrInst>, int64_t>>
         &LargeOffsetGEPs = Entry.second;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D51936.164901.patch
Type: text/x-patch
Size: 2161 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180911/3354b56a/attachment.bin>


More information about the llvm-commits mailing list