From ba4c8b50043a33eefac3d150d82e4fd5dfeba7dd Mon Sep 17 00:00:00 2001 From: Peter Collingbourne Date: Sat, 27 Jun 2015 00:17:51 +0000 Subject: [PATCH] LowerBitSets: Ignore bitset entries that do not directly refer to a global. It is possible for a global to be substituted with another global of a different type or a different kind (i.e. an alias) at IR link time. One example of this scenario is when a Microsoft ABI vtable is substituted with an alias referring to a larger vtable containing an RTTI reference. This will cause the global to be RAUW'd with a possibly bitcasted reference to the other global. This will of course also affect any references to the global in bitset metadata. The right way to handle such metadata is simply to ignore it. This is sound because the linked module should contain another copy of the bitset entries as applied to the new global. llvm-svn: 240866 --- llvm/lib/Transforms/IPO/LowerBitSets.cpp | 10 +++++++--- llvm/test/Transforms/LowerBitSets/nonglobal.ll | 19 +++++++++++++++++++ 2 files changed, 26 insertions(+), 3 deletions(-) create mode 100644 llvm/test/Transforms/LowerBitSets/nonglobal.ll diff --git a/llvm/lib/Transforms/IPO/LowerBitSets.cpp b/llvm/lib/Transforms/IPO/LowerBitSets.cpp index bffeebb..c6795c6 100644 --- a/llvm/lib/Transforms/IPO/LowerBitSets.cpp +++ b/llvm/lib/Transforms/IPO/LowerBitSets.cpp @@ -271,8 +271,10 @@ BitSetInfo LowerBitSets::buildBitSet( for (MDNode *Op : BitSetNM->operands()) { if (Op->getOperand(0) != BitSet || !Op->getOperand(1)) continue; - auto OpGlobal = cast( + auto OpGlobal = dyn_cast( cast(Op->getOperand(1))->getValue()); + if (!OpGlobal) + continue; uint64_t Offset = cast(cast(Op->getOperand(2)) ->getValue())->getZExtValue(); @@ -621,7 +623,7 @@ bool LowerBitSets::buildBitSets() { report_fatal_error("Bit set element must be a constant"); auto OpGlobal = dyn_cast(OpConstMD->getValue()); if (!OpGlobal) - report_fatal_error("Bit set element must refer to global"); + continue; auto OffsetConstMD = dyn_cast(Op->getOperand(2)); if (!OffsetConstMD) @@ -675,8 +677,10 @@ bool LowerBitSets::buildBitSets() { if (I == BitSetIndices.end()) continue; - auto OpGlobal = cast( + auto OpGlobal = dyn_cast( cast(Op->getOperand(1))->getValue()); + if (!OpGlobal) + continue; BitSetMembers[I->second].insert(GlobalIndices[OpGlobal]); } } diff --git a/llvm/test/Transforms/LowerBitSets/nonglobal.ll b/llvm/test/Transforms/LowerBitSets/nonglobal.ll new file mode 100644 index 0000000..7591e31 --- /dev/null +++ b/llvm/test/Transforms/LowerBitSets/nonglobal.ll @@ -0,0 +1,19 @@ +; RUN: opt -S -lowerbitsets < %s | FileCheck %s + +target datalayout = "e-p:32:32" + +; CHECK-NOT: @b = alias +@a = constant i32 1 +@b = constant [2 x i32] [i32 2, i32 3] + +!0 = !{!"bitset1", i32* @a, i32 0} +!1 = !{!"bitset1", i32* bitcast ([2 x i32]* @b to i32*), i32 0} + +!llvm.bitsets = !{ !0, !1 } + +declare i1 @llvm.bitset.test(i8* %ptr, metadata %bitset) nounwind readnone + +define i1 @foo(i8* %p) { + %x = call i1 @llvm.bitset.test(i8* %p, metadata !"bitset1") + ret i1 %x +} -- 2.7.4