Possible bug in PassManager - Higher pass requires lower pass

Hello all,

I've noticed that whenever a ``higher'' pass requires a ``lower''
pass, an assert *always* fails in the pass manager. I believe the
correct behavior is to not schedule the lower pass, but instead run it
when the higher pass calls getAnalysis<>(). Consider, for instance,
this test case:

#include "llvm/Pass.h"
#include "llvm/Analysis/LoopPass.h"
using namespace llvm;
namespace bugs {
  // First, the ``lower pass''
  class LowerPass : public LoopPass {
    public:
      static char ID;
      LowerPass() : LoopPass(&ID) {}
      virtual ~LowerPass() {}
      virtual void getAnalysisUsage(AnalysisUsage &use) const {
        use.setPreservesAll();
      }
      virtual bool runOnLoop(Loop *l, LPPassManager &lpm) {
        return false;
      }
  };
  char LowerPass::ID = 0;
  RegisterPass<LowerPass> x("lower", "Lower Pass");

  // Next, the ``higher pass''
  class HigherPass : public FunctionPass {
    public:
      static char ID;
      HigherPass() : FunctionPass(&ID) {}
      virtual ~HigherPass() {}
      virtual void getAnalysisUsage(AnalysisUsage &use) const {
        use.addRequired<LowerPass>();
      }
      virtual bool runOnFunction(Function &fcn) {
        return false;
      }
  };
  char HigherPass::ID = 0;
  RegisterPass<HigherPass> y("higher", "Higher Pass");
}

I compile this to a shared object, and then run it:

$ opt foo.bc -o bar.bc -load libBug.so -higher
Unable to schedule 'Lower Pass' required by 'Higher Pass'
opt: /media/secure/home/nick/classes/liberty/llvm/llvm/lib/VMCore/PassManager.cpp:1077:
virtual void llvm::PMDataManager::addLowerLevelRequiredPass(llvm::Pass*,
llvm::Pass*): Assertion `0 && "Unable to schedule pass"' failed.
0 opt 0x08721883
1 opt 0x08721be0
2 opt 0xb7f7e420
3 libc.so.6 0xb7d3bfb9 abort + 265
4 libc.so.6 0xb7d33fbf __assert_fail + 271
5 opt 0x086ab6a0
llvm::PMDataManager::preserveHigherLevelAnalysis(llvm::Pass*) + 0
6 opt 0x086acfeb llvm::PMDataManager::add(llvm::Pass*, bool) + 815
7 opt 0x086ad39f
llvm::FunctionPass::assignPassManager(llvm::PMStack&,
llvm::PassManagerType) + 461
8 opt 0x086b6f83
llvm::PassManagerImpl::addTopLevelPass(llvm::Pass*) + 237
9 opt 0x086abfc5
llvm::PMTopLevelManager::schedulePass(llvm::Pass*) + 499
10 opt 0x086b70a6 llvm::PassManagerImpl::add(llvm::Pass*) + 30
11 opt 0x086abfe7 llvm::PassManager::add(llvm::Pass*) + 27
12 opt 0x083c9b0e (anonymous
namespace)::addPass(llvm::PassManager&, llvm::Pass*) + 32
13 opt 0x083c16ce main + 3236
14 libc.so.6 0xb7d26ea8 __libc_start_main + 200
15 opt 0x083b1f51 __gxx_personality_v0 + 353
Aborted

I observe this bug on the head revision of llvm. Your input would be
appreciated,