[llvm] r200322 - Fix pr14893.

Rafael Espindola rafael.espindola at gmail.com
Tue Jan 28 08:56:46 PST 2014


Author: rafael
Date: Tue Jan 28 10:56:46 2014
New Revision: 200322

URL: http://llvm.org/viewvc/llvm-project?rev=200322&view=rev
Log:
Fix pr14893.

When simplifycfg moves an instruction, it must drop metadata it doesn't know
is still valid with the preconditions changes. In particular, it must drop
the range and tbaa metadata.

The patch implements this with an utility function to drop all metadata not
in a white list.

Modified:
    llvm/trunk/include/llvm/IR/Instruction.h
    llvm/trunk/lib/IR/Metadata.cpp
    llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp
    llvm/trunk/test/Transforms/SimplifyCFG/basictest.ll

Modified: llvm/trunk/include/llvm/IR/Instruction.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Instruction.h?rev=200322&r1=200321&r2=200322&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/Instruction.h (original)
+++ llvm/trunk/include/llvm/IR/Instruction.h Tue Jan 28 10:56:46 2014
@@ -15,6 +15,7 @@
 #ifndef LLVM_IR_INSTRUCTION_H
 #define LLVM_IR_INSTRUCTION_H
 
+#include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/ilist_node.h"
 #include "llvm/IR/User.h"
 #include "llvm/Support/DebugLoc.h"
@@ -171,6 +172,21 @@ public:
   void setMetadata(unsigned KindID, MDNode *Node);
   void setMetadata(StringRef Kind, MDNode *Node);
 
+  /// \brief Drop unknown metadata.
+  /// Passes are required to drop metadata they don't understand. This is a
+  /// convenience method for passes to do so.
+  void dropUnknownMetadata(ArrayRef<unsigned> KnownIDs);
+  void dropUnknownMetadata() {
+    return dropUnknownMetadata(ArrayRef<unsigned>());
+  }
+  void dropUnknownMetadata(unsigned ID1) {
+    return dropUnknownMetadata(makeArrayRef(ID1));
+  }
+  void dropUnknownMetadata(unsigned ID1, unsigned ID2) {
+    unsigned IDs[] = {ID1, ID2};
+    return dropUnknownMetadata(IDs);
+  }
+
   /// setDebugLoc - Set the debug location information for this instruction.
   void setDebugLoc(const DebugLoc &Loc) { DbgLoc = Loc; }
 

Modified: llvm/trunk/lib/IR/Metadata.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Metadata.cpp?rev=200322&r1=200321&r2=200322&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Metadata.cpp (original)
+++ llvm/trunk/lib/IR/Metadata.cpp Tue Jan 28 10:56:46 2014
@@ -16,6 +16,7 @@
 #include "SymbolTableListTraitsImpl.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallSet.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/StringMap.h"
 #include "llvm/IR/Instruction.h"
@@ -583,6 +584,50 @@ MDNode *Instruction::getMetadataImpl(Str
   return getMetadataImpl(getContext().getMDKindID(Kind));
 }
 
+void Instruction::dropUnknownMetadata(ArrayRef<unsigned> KnownIDs) {
+  SmallSet<unsigned, 5> KnownSet;
+  KnownSet.insert(KnownIDs.begin(), KnownIDs.end());
+
+  // Drop debug if needed
+  if (KnownSet.erase(LLVMContext::MD_dbg))
+    DbgLoc = DebugLoc();
+
+  if (!hasMetadataHashEntry())
+    return; // Nothing to remove!
+
+  DenseMap<const Instruction *, LLVMContextImpl::MDMapTy> &MetadataStore =
+      getContext().pImpl->MetadataStore;
+
+  if (KnownSet.empty()) {
+    // Just drop our entry at the store.
+    MetadataStore.erase(this);
+    setHasMetadataHashEntry(false);
+    return;
+  }
+
+  LLVMContextImpl::MDMapTy &Info = MetadataStore[this];
+  unsigned I;
+  unsigned E;
+  // Walk the array and drop any metadata we don't know.
+  for (I = 0, E = Info.size(); I != E;) {
+    if (KnownSet.count(Info[I].first)) {
+      ++I;
+      continue;
+    }
+
+    Info[I] = Info.back();
+    Info.pop_back();
+    --E;
+  }
+  assert(E == Info.size());
+
+  if (E == 0) {
+    // Drop our entry at the store.
+    MetadataStore.erase(this);
+    setHasMetadataHashEntry(false);
+  }
+}
+
 /// setMetadata - Set the metadata of of the specified kind to the specified
 /// node.  This updates/replaces metadata if already present, or removes it if
 /// Node is null.

Modified: llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp?rev=200322&r1=200321&r2=200322&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp Tue Jan 28 10:56:46 2014
@@ -2154,6 +2154,14 @@ bool llvm::FoldBranchToCommonDest(Branch
     Instruction *NewBonus = 0;
     if (BonusInst) {
       NewBonus = BonusInst->clone();
+
+      // If we moved a load, we cannot any longer claim any knowledge about
+      // its potential value. The previous information might have been valid
+      // only given the branch precondition.
+      // For an analogous reason, we must also drop all the metadata whose
+      // semantics we don't understand.
+      NewBonus->dropUnknownMetadata(LLVMContext::MD_dbg);
+
       PredBlock->getInstList().insert(PBI, NewBonus);
       NewBonus->takeName(BonusInst);
       BonusInst->setName(BonusInst->getName()+".old");

Modified: llvm/trunk/test/Transforms/SimplifyCFG/basictest.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimplifyCFG/basictest.ll?rev=200322&r1=200321&r2=200322&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/SimplifyCFG/basictest.ll (original)
+++ llvm/trunk/test/Transforms/SimplifyCFG/basictest.ll Tue Jan 28 10:56:46 2014
@@ -41,3 +41,33 @@ return:
 ; CHECK-LABEL: @test5(
 ; CHECK-NEXT: ret void
 }
+
+
+; PR14893
+define i8 @test6f() {
+; CHECK-LABEL: @test6f
+; CHECK: alloca i8, align 1
+; CHECK-NEXT: call i8 @test6g
+; CHECK-NEXT: icmp eq i8 %tmp, 0
+; CHECK-NEXT: load i8* %r, align 1{{$}}
+
+bb0:
+  %r = alloca i8, align 1
+  %tmp = call i8 @test6g(i8* %r)
+  %tmp1 = icmp eq i8 %tmp, 0
+  br i1 %tmp1, label %bb2, label %bb1
+bb1:
+  %tmp3 = load i8* %r, align 1, !range !2, !tbaa !1
+  %tmp4 = icmp eq i8 %tmp3, 1
+  br i1 %tmp4, label %bb2, label %bb3
+bb2:
+  br label %bb3
+bb3:
+  %tmp6 = phi i8 [ 0, %bb2 ], [ 1, %bb1 ]
+  ret i8 %tmp6
+}
+declare i8 @test6g(i8*)
+
+!0 = metadata !{metadata !1, metadata !1, i64 0}
+!1 = metadata !{metadata !"foo"}
+!2 = metadata !{i8 0, i8 2}





More information about the llvm-commits mailing list