[llvm] r240866 - LowerBitSets: Ignore bitset entries that do not directly refer to a global.

Peter Collingbourne peter at pcc.me.uk
Fri Jun 26 17:17:51 PDT 2015


Author: pcc
Date: Fri Jun 26 19:17:51 2015
New Revision: 240866

URL: http://llvm.org/viewvc/llvm-project?rev=240866&view=rev
Log:
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.

Added:
    llvm/trunk/test/Transforms/LowerBitSets/nonglobal.ll
Modified:
    llvm/trunk/lib/Transforms/IPO/LowerBitSets.cpp

Modified: llvm/trunk/lib/Transforms/IPO/LowerBitSets.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/LowerBitSets.cpp?rev=240866&r1=240865&r2=240866&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/IPO/LowerBitSets.cpp (original)
+++ llvm/trunk/lib/Transforms/IPO/LowerBitSets.cpp Fri Jun 26 19:17:51 2015
@@ -271,8 +271,10 @@ BitSetInfo LowerBitSets::buildBitSet(
     for (MDNode *Op : BitSetNM->operands()) {
       if (Op->getOperand(0) != BitSet || !Op->getOperand(1))
         continue;
-      auto OpGlobal = cast<GlobalVariable>(
+      auto OpGlobal = dyn_cast<GlobalVariable>(
           cast<ConstantAsMetadata>(Op->getOperand(1))->getValue());
+      if (!OpGlobal)
+        continue;
       uint64_t Offset =
           cast<ConstantInt>(cast<ConstantAsMetadata>(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<GlobalVariable>(OpConstMD->getValue());
       if (!OpGlobal)
-        report_fatal_error("Bit set element must refer to global");
+        continue;
 
       auto OffsetConstMD = dyn_cast<ConstantAsMetadata>(Op->getOperand(2));
       if (!OffsetConstMD)
@@ -675,8 +677,10 @@ bool LowerBitSets::buildBitSets() {
         if (I == BitSetIndices.end())
           continue;
 
-        auto OpGlobal = cast<GlobalVariable>(
+        auto OpGlobal = dyn_cast<GlobalVariable>(
             cast<ConstantAsMetadata>(Op->getOperand(1))->getValue());
+        if (!OpGlobal)
+          continue;
         BitSetMembers[I->second].insert(GlobalIndices[OpGlobal]);
       }
     }

Added: llvm/trunk/test/Transforms/LowerBitSets/nonglobal.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LowerBitSets/nonglobal.ll?rev=240866&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/LowerBitSets/nonglobal.ll (added)
+++ llvm/trunk/test/Transforms/LowerBitSets/nonglobal.ll Fri Jun 26 19:17:51 2015
@@ -0,0 +1,19 @@
+; RUN: opt -S -lowerbitsets < %s | FileCheck %s
+
+target datalayout = "e-p:32:32"
+
+; CHECK-NOT: @b = alias
+ at a = constant i32 1
+ at 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
+}





More information about the llvm-commits mailing list