[llvm] r200322 - Fix pr14893.

Adrian Prantl via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 20 10:19:31 PDT 2015


> On Jan 28, 2014, at 8:56 AM, Rafael Espindola <rafael.espindola at gmail.com> wrote:
> 
> 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();

I was just investigating why SimplifyCFG is dropping DebugLocs on instructions and I was wondering: isn’t this the opposite of what the function is supposed to be doing, i.e., drop all metadata that is not in KnownODs?

-- adrian

> +
> +  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}
> 
> 
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits



More information about the llvm-commits mailing list