[llvm] r318477 - Current implementation of Value::replaceUsesExceptBlockAddr() uses UseList

Dmitry Mikulin via llvm-commits llvm-commits at lists.llvm.org
Thu Nov 16 16:30:25 PST 2017


Author: dmikulin
Date: Thu Nov 16 16:30:24 2017
New Revision: 318477

URL: http://llvm.org/viewvc/llvm-project?rev=318477&view=rev
Log:
Current implementation of Value::replaceUsesExceptBlockAddr() uses UseList
iterator to walk the list which keeps changing inside the loop. When the
UseList contains several uses with the same user, we end processing the same
user more than once, which leads to an assert.

With this fix, unique users are saved and processed later to avoid
processing duplicates.

Differential Revision: https://reviews.llvm.org/D39864

Added:
    llvm/trunk/test/Transforms/LowerTypeTests/blockaddress-2.ll
Modified:
    llvm/trunk/lib/IR/Value.cpp

Modified: llvm/trunk/lib/IR/Value.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Value.cpp?rev=318477&r1=318476&r2=318477&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Value.cpp (original)
+++ llvm/trunk/lib/IR/Value.cpp Thu Nov 16 16:30:24 2017
@@ -15,6 +15,7 @@
 #include "LLVMContextImpl.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SetVector.h"
 #include "llvm/IR/CallSite.h"
 #include "llvm/IR/Constant.h"
 #include "llvm/IR/Constants.h"
@@ -456,6 +457,7 @@ void Value::replaceUsesOutsideBlock(Valu
 }
 
 void Value::replaceUsesExceptBlockAddr(Value *New) {
+  SmallSetVector<Constant *, 4> Constants;
   use_iterator UI = use_begin(), E = use_end();
   for (; UI != E;) {
     Use &U = *UI;
@@ -468,13 +470,19 @@ void Value::replaceUsesExceptBlockAddr(V
     // constant because they are uniqued.
     if (auto *C = dyn_cast<Constant>(U.getUser())) {
       if (!isa<GlobalValue>(C)) {
-        C->handleOperandChange(this, New);
+        // Save unique users to avoid processing operand replacement
+        // more than once.
+        Constants.insert(C);
         continue;
       }
     }
 
     U.set(New);
   }
+
+  // Process operand replacement of saved constants.
+  for (auto *C : Constants)
+    C->handleOperandChange(this, New);
 }
 
 namespace {

Added: llvm/trunk/test/Transforms/LowerTypeTests/blockaddress-2.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LowerTypeTests/blockaddress-2.ll?rev=318477&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/LowerTypeTests/blockaddress-2.ll (added)
+++ llvm/trunk/test/Transforms/LowerTypeTests/blockaddress-2.ll Thu Nov 16 16:30:24 2017
@@ -0,0 +1,26 @@
+; RUN: opt -S %s -lowertypetests | FileCheck %s
+
+; CHECK: @badfileops = internal global %struct.f { void ()* @bad_f, void ()* @bad_f }
+; CHECK: @bad_f = internal alias void (), void ()* @.cfi.jumptable
+; CHECK: define internal void @bad_f.cfi() !type !0 {
+; CHECK-NEXT:  ret void
+
+target triple = "x86_64-unknown-linux"
+
+%struct.f = type { void ()*, void ()* }
+ at badfileops = internal global %struct.f { void ()* @bad_f, void ()* @bad_f }, align 8
+
+declare i1 @llvm.type.test(i8*, metadata)
+
+define internal void @bad_f() !type !1 {
+  ret void
+}
+
+define internal fastcc void @do_f() unnamed_addr !type !2 {
+  %1 = tail call i1 @llvm.type.test(i8* undef, metadata !"_ZTSFiP4fileP3uioP5ucrediP6threadE"), !nosanitize !3
+  ret void
+}
+
+!1 = !{i64 0, !"_ZTSFiP4fileP3uioP5ucrediP6threadE"}
+!2 = !{i64 0, !"_ZTSFiP6threadiP4fileP3uioliE"}
+!3 = !{}




More information about the llvm-commits mailing list