Various crash reporting tools have a problem with the dwarf generated for
[oota-llvm.git] / lib / VMCore / AutoUpgrade.cpp
index 76eda7501e72b58810fb45e3dfb6dd650ed7a850..59424f9644b3dff8fc401f9388d5e641d46d50ce 100644 (file)
@@ -37,14 +37,25 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) {
   if (Name.size() <= 8 || !Name.startswith("llvm."))
     return false;
   Name = Name.substr(5); // Strip off "llvm."
-  
+
   switch (Name[0]) {
   default: break;
-  case 'm':
-    if (Name == "memory.barrier")
+  case 'c': {
+    if (Name.startswith("ctlz.") && F->arg_size() == 1) {
+      F->setName(Name + ".old");
+      NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::ctlz,
+                                        F->arg_begin()->getType());
+      return true;
+    }
+    if (Name.startswith("cttz.") && F->arg_size() == 1) {
+      F->setName(Name + ".old");
+      NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::cttz,
+                                        F->arg_begin()->getType());
       return true;
+    }
     break;
   }
+  }
 
   //  This may not belong here. This function is effectively being overloaded 
   //  to both detect an intrinsic which needs upgrading, and to provide the 
@@ -74,38 +85,26 @@ bool llvm::UpgradeGlobalVariable(GlobalVariable *GV) {
 // upgraded intrinsic. All argument and return casting must be provided in 
 // order to seamlessly integrate with existing context.
 void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
-  Function *F = CI->getCalledFunction();
+  assert(CI->getCalledFunction() && "Intrinsic call is not direct?");
+  if (!NewFn) return;
+
   LLVMContext &C = CI->getContext();
-  ImmutableCallSite CS(CI);
-
-  assert(F && "CallInst has no function associated with it.");
-
-  if (!NewFn) {
-    if (F->getName() == "llvm.memory.barrier") {
-      IRBuilder<> Builder(C);
-      Builder.SetInsertPoint(CI->getParent(), CI);
-
-      // Note that this conversion ignores the "device" bit; it was not really
-      // well-defined, and got abused because nobody paid enough attention to
-      // get it right. In practice, this probably doesn't matter; application
-      // code generally doesn't need anything stronger than
-      // SequentiallyConsistent (and realistically, SequentiallyConsistent
-      // is lowered to a strong enough barrier for almost anything).
-
-      if (cast<ConstantInt>(CI->getArgOperand(1))->getZExtValue())
-        Builder.CreateFence(SequentiallyConsistent);
-      else if (!cast<ConstantInt>(CI->getArgOperand(0))->getZExtValue())
-        Builder.CreateFence(Release);
-      else if (!cast<ConstantInt>(CI->getArgOperand(3))->getZExtValue())
-        Builder.CreateFence(Acquire);
-      else
-        Builder.CreateFence(AcquireRelease);
-
-      // Remove intrinsic.
-      CI->eraseFromParent();
-    } else {
-      llvm_unreachable("Unknown function for CallInst upgrade.");
-    }
+  IRBuilder<> Builder(C);
+  Builder.SetInsertPoint(CI->getParent(), CI);
+
+  switch (NewFn->getIntrinsicID()) {
+  default:
+    llvm_unreachable("Unknown function for CallInst upgrade.");
+
+  case Intrinsic::ctlz:
+  case Intrinsic::cttz:
+    assert(CI->getNumArgOperands() == 1 &&
+           "Mismatch between function args and call args");
+    StringRef Name = CI->getName();
+    CI->setName(Name + ".old");
+    CI->replaceAllUsesWith(Builder.CreateCall2(NewFn, CI->getArgOperand(0),
+                                               Builder.getFalse(), Name));
+    CI->eraseFromParent();
     return;
   }
 }