Example #1
0
void IndVarSimplify::EliminateIVComparisons() {
  // Look for ICmp users.
  for (IVUsers::iterator I = IU->begin(), E = IU->end(); I != E; ++I) {
    IVStrideUse &UI = *I;
    ICmpInst *ICmp = dyn_cast<ICmpInst>(UI.getUser());
    if (!ICmp) continue;

    bool Swapped = UI.getOperandValToReplace() == ICmp->getOperand(1);
    ICmpInst::Predicate Pred = ICmp->getPredicate();
    if (Swapped) Pred = ICmpInst::getSwappedPredicate(Pred);

    // Get the SCEVs for the ICmp operands.
    const SCEV *S = IU->getReplacementExpr(UI);
    const SCEV *X = SE->getSCEV(ICmp->getOperand(!Swapped));

    // Simplify unnecessary loops away.
    const Loop *ICmpLoop = LI->getLoopFor(ICmp->getParent());
    S = SE->getSCEVAtScope(S, ICmpLoop);
    X = SE->getSCEVAtScope(X, ICmpLoop);

    // If the condition is always true or always false, replace it with
    // a constant value.
    if (SE->isKnownPredicate(Pred, S, X))
      ICmp->replaceAllUsesWith(ConstantInt::getTrue(ICmp->getContext()));
    else if (SE->isKnownPredicate(ICmpInst::getInversePredicate(Pred), S, X))
      ICmp->replaceAllUsesWith(ConstantInt::getFalse(ICmp->getContext()));
    else
      continue;

    DEBUG(dbgs() << "INDVARS: Eliminated comparison: " << *ICmp << '\n');
    DeadInsts.push_back(ICmp);
  }
}
Example #2
0
    bool visitICmpInst(ICmpInst& inst) {
        // errs() << "got icmp instruction!  " << inst << '\n';

        bool changed = false;
        if (inst.getPredicate() == CmpInst::ICMP_EQ) {
            assert(inst.getNumOperands() == 2);

            if (inst.getOperand(1) == processing) {
                inst.swapOperands();
                changed = true;
                any_changes = true;
            }
            assert(dyn_cast<Instruction>(inst.getOperand(0)) == processing);
            Value* other = inst.getOperand(1);
            if (isa<ConstantPointerNull>(other)) {
                if (VERBOSITY("opt") >= 2) {
                    errs() << inst << '\n';
                    errs() << "replacing with false!\n";
                }

                Value* new_value = ConstantInt::getFalse(other->getContext());
                inst.replaceAllUsesWith(new_value);
                inst.eraseFromParent();
                changed = true;
                any_changes = true;
            }
        }
        return changed;
    }
Example #3
0
bool AMDGPUCodeGenPrepare::promoteUniformOpToI32(ICmpInst &I) const {
  assert(needsPromotionToI32(I.getOperand(0)->getType()) &&
         "I does not need promotion to i32");

  IRBuilder<> Builder(&I);
  Builder.SetCurrentDebugLocation(I.getDebugLoc());

  Type *I32Ty = getI32Ty(Builder, I.getOperand(0)->getType());
  Value *ExtOp0 = nullptr;
  Value *ExtOp1 = nullptr;
  Value *NewICmp  = nullptr;

  if (I.isSigned()) {
    ExtOp0 = Builder.CreateSExt(I.getOperand(0), I32Ty);
    ExtOp1 = Builder.CreateSExt(I.getOperand(1), I32Ty);
  } else {
    ExtOp0 = Builder.CreateZExt(I.getOperand(0), I32Ty);
    ExtOp1 = Builder.CreateZExt(I.getOperand(1), I32Ty);
  }
  NewICmp = Builder.CreateICmp(I.getPredicate(), ExtOp0, ExtOp1);

  I.replaceAllUsesWith(NewICmp);
  I.eraseFromParent();

  return true;
}
Example #4
0
void IndVarSimplify::EliminateIVComparisons() {
  SmallVector<WeakVH, 16> DeadInsts;

  // Look for ICmp users.
  for (IVUsers::iterator I = IU->begin(), E = IU->end(); I != E; ++I) {
    IVStrideUse &UI = *I;
    ICmpInst *ICmp = dyn_cast<ICmpInst>(UI.getUser());
    if (!ICmp) continue;

    bool Swapped = UI.getOperandValToReplace() == ICmp->getOperand(1);
    ICmpInst::Predicate Pred = ICmp->getPredicate();
    if (Swapped) Pred = ICmpInst::getSwappedPredicate(Pred);

    // Get the SCEVs for the ICmp operands.
    const SCEV *S = IU->getReplacementExpr(UI);
    const SCEV *X = SE->getSCEV(ICmp->getOperand(!Swapped));

    // Simplify unnecessary loops away.
    const Loop *ICmpLoop = LI->getLoopFor(ICmp->getParent());
    S = SE->getSCEVAtScope(S, ICmpLoop);
    X = SE->getSCEVAtScope(X, ICmpLoop);

    // If the condition is always true or always false, replace it with
    // a constant value.
    if (SE->isKnownPredicate(Pred, S, X))
      ICmp->replaceAllUsesWith(ConstantInt::getTrue(ICmp->getContext()));
    else if (SE->isKnownPredicate(ICmpInst::getInversePredicate(Pred), S, X))
      ICmp->replaceAllUsesWith(ConstantInt::getFalse(ICmp->getContext()));
    else
      continue;

    DEBUG(dbgs() << "INDVARS: Eliminated comparison: " << *ICmp << '\n');
    DeadInsts.push_back(ICmp);
  }

  // Now that we're done iterating through lists, clean up any instructions
  // which are now dead.
  while (!DeadInsts.empty())
    if (Instruction *Inst =
        dyn_cast_or_null<Instruction>(&*DeadInsts.pop_back_val()))
      RecursivelyDeleteTriviallyDeadInstructions(Inst);
}
Example #5
0
bool GambasPass::runOnFunction(Function &F){
	IRBuilder<> Builder(F.getContext());
	
	bool changed = false;
	for(Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) {
		for(BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ){
			ICmpInst* ICI = dyn_cast<ICmpInst>(I);
			CallInst* CI = dyn_cast<CallInst>(I++);
			
			if (ICI && ICI->hasMetadata() && ICI->getMetadata("unref_slt") && dyn_cast<LoadInst>(ICI->getOperand(0))){
				ICI->replaceAllUsesWith(ConstantInt::get(ICI->getType(), false));
				ICI->eraseFromParent();
				changed = true;
				continue;
			}
			
			if (!CI)
				continue;
			
			Function* callee = CI->getCalledFunction();
			if (callee == NULL || !callee->isDeclaration())
				continue;
			
			StringRef name = callee->getName();
			if (name == "JR_release_variant" || name == "JR_borrow_variant"){
				ConstantInt* vtype_int = dyn_cast<ConstantInt>(CI->getArgOperand(0));
				if (!vtype_int)
					continue;
				
				uint64_t vtype = vtype_int->getZExtValue();
				if (TYPE_is_string(vtype) || TYPE_is_object(vtype))
					continue;
				
				CI->eraseFromParent();
				changed = true;
			} else if (name == FUNCTION_NAME(__finite)){
				ConstantFP* op = dyn_cast<ConstantFP>(CI->getArgOperand(0));
				if (!op)
					continue;
				
				int val = __finite(op->getValueAPF().convertToDouble());
				Constant* res = ConstantInt::get(CI->getType(), val);
				CI->replaceAllUsesWith(res);
				CI->eraseFromParent();
				changed = true;
			} else if (name == FUNCTION_NAME(__isnan)){
				ConstantFP* op = dyn_cast<ConstantFP>(CI->getArgOperand(0));
				if (!op)
					continue;
				
				int val = __isnan(op->getValueAPF().convertToDouble());
				Constant* res = ConstantInt::get(CI->getType(), val);
				CI->replaceAllUsesWith(res);
				CI->eraseFromParent();
				changed = true;
			} else if (name == FUNCTION_NAME(__isinf)){
				ConstantFP* op = dyn_cast<ConstantFP>(CI->getArgOperand(0));
				if (!op)
					continue;
				
				int val = __isinf(op->getValueAPF().convertToDouble());
				Constant* res = ConstantInt::get(CI->getType(), val);
				CI->replaceAllUsesWith(res);
				CI->eraseFromParent();
				changed = true;
			}
		}
	}
	return changed;
}
bool AtomicExpandLoadLinked::expandAtomicCmpXchg(AtomicCmpXchgInst *CI) {
  AtomicOrdering SuccessOrder = CI->getSuccessOrdering();
  AtomicOrdering FailureOrder = CI->getFailureOrdering();
  Value *Addr = CI->getPointerOperand();
  BasicBlock *BB = CI->getParent();
  Function *F = BB->getParent();
  LLVMContext &Ctx = F->getContext();

  // Given: cmpxchg some_op iN* %addr, iN %desired, iN %new success_ord fail_ord
  //
  // The full expansion we produce is:
  //     [...]
  //     fence?
  // cmpxchg.start:
  //     %loaded = @load.linked(%addr)
  //     %should_store = icmp eq %loaded, %desired
  //     br i1 %should_store, label %cmpxchg.trystore,
  //                          label %cmpxchg.end/%cmpxchg.barrier
  // cmpxchg.trystore:
  //     %stored = @store_conditional(%new, %addr)
  //     %try_again = icmp i32 ne %stored, 0
  //     br i1 %try_again, label %loop, label %cmpxchg.end
  // cmpxchg.barrier:
  //     fence?
  //     br label %cmpxchg.end
  // cmpxchg.end:
  //     [...]
  BasicBlock *ExitBB = BB->splitBasicBlock(CI, "cmpxchg.end");
  auto BarrierBB = BasicBlock::Create(Ctx, "cmpxchg.barrier", F, ExitBB);
  auto TryStoreBB = BasicBlock::Create(Ctx, "cmpxchg.trystore", F, BarrierBB);
  auto LoopBB = BasicBlock::Create(Ctx, "cmpxchg.start", F, TryStoreBB);

  // This grabs the DebugLoc from CI
  IRBuilder<> Builder(CI);

  // The split call above "helpfully" added a branch at the end of BB (to the
  // wrong place), but we might want a fence too. It's easiest to just remove
  // the branch entirely.
  std::prev(BB->end())->eraseFromParent();
  Builder.SetInsertPoint(BB);
  AtomicOrdering MemOpOrder = insertLeadingFence(Builder, SuccessOrder);
  Builder.CreateBr(LoopBB);

  // Start the main loop block now that we've taken care of the preliminaries.
  Builder.SetInsertPoint(LoopBB);
  Value *Loaded = TLI->emitLoadLinked(Builder, Addr, MemOpOrder);
  Value *ShouldStore =
      Builder.CreateICmpEQ(Loaded, CI->getCompareOperand(), "should_store");

  // If the the cmpxchg doesn't actually need any ordering when it fails, we can
  // jump straight past that fence instruction (if it exists).
  BasicBlock *FailureBB = FailureOrder == Monotonic ? ExitBB : BarrierBB;
  Builder.CreateCondBr(ShouldStore, TryStoreBB, FailureBB);

  Builder.SetInsertPoint(TryStoreBB);
  Value *StoreSuccess = TLI->emitStoreConditional(
      Builder, CI->getNewValOperand(), Addr, MemOpOrder);
  Value *TryAgain = Builder.CreateICmpNE(
      StoreSuccess, ConstantInt::get(Type::getInt32Ty(Ctx), 0), "success");
  Builder.CreateCondBr(TryAgain, LoopBB, BarrierBB);

  // Make sure later instructions don't get reordered with a fence if necessary.
  Builder.SetInsertPoint(BarrierBB);
  insertTrailingFence(Builder, SuccessOrder);
  Builder.CreateBr(ExitBB);

  // Finally, we have control-flow based knowledge of whether the cmpxchg
  // succeeded or not. We expose this to later passes by converting any
  // subsequent "icmp eq/ne %loaded, %oldval" into a use of an appropriate PHI.

  // Setup the builder so we can create any PHIs we need.
  Builder.SetInsertPoint(FailureBB, FailureBB->begin());
  BasicBlock *SuccessBB = FailureOrder == Monotonic ? BarrierBB : TryStoreBB;
  PHINode *Success = 0, *Failure = 0;

  // Look for any users of the cmpxchg that are just comparing the loaded value
  // against the desired one, and replace them with the CFG-derived version.
  for (auto User : CI->users()) {
    ICmpInst *ICmp = dyn_cast<ICmpInst>(User);
    if (!ICmp)
      continue;

    // Because we know ICmp uses CI, we only need one operand to be the old
    // value.
    if (ICmp->getOperand(0) != CI->getCompareOperand() &&
        ICmp->getOperand(1) != CI->getCompareOperand())
      continue;

    if (ICmp->getPredicate() == CmpInst::ICMP_EQ) {
      if (!Success) {
        Success = Builder.CreatePHI(Type::getInt1Ty(Ctx), 2);
        Success->addIncoming(ConstantInt::getTrue(Ctx), SuccessBB);
        Success->addIncoming(ConstantInt::getFalse(Ctx), LoopBB);
      }
      ICmp->replaceAllUsesWith(Success);
    } else if (ICmp->getPredicate() == CmpInst::ICMP_NE) {
      if (!Failure) {
        Failure = Builder.CreatePHI(Type::getInt1Ty(Ctx), 2);
        Failure->addIncoming(ConstantInt::getFalse(Ctx), SuccessBB);
        Failure->addIncoming(ConstantInt::getTrue(Ctx), LoopBB);
      }
      ICmp->replaceAllUsesWith(Failure);
    }
  }

  CI->replaceAllUsesWith(Loaded);
  CI->eraseFromParent();

  return true;
}