Index: llvm/trunk/lib/IR/Value.cpp =================================================================== --- llvm/trunk/lib/IR/Value.cpp +++ llvm/trunk/lib/IR/Value.cpp @@ -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::replaceUsesExceptBlockAddr(Value *New) { + SmallSetVector Constants; use_iterator UI = use_begin(), E = use_end(); for (; UI != E;) { Use &U = *UI; @@ -468,13 +470,19 @@ // constant because they are uniqued. if (auto *C = dyn_cast(U.getUser())) { if (!isa(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 { Index: llvm/trunk/test/Transforms/LowerTypeTests/blockaddress-2.ll =================================================================== --- llvm/trunk/test/Transforms/LowerTypeTests/blockaddress-2.ll +++ llvm/trunk/test/Transforms/LowerTypeTests/blockaddress-2.ll @@ -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 ()* } +@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 = !{}