diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp --- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -3529,30 +3529,39 @@ // Op1.fr = Freeze(Op1) // ... = Inst(Op1.fr, NonPoisonOps...) auto* OrigOp = OrigFI.getOperand(0); - if (auto *OrigOpInst = dyn_cast(OrigOp)) { - if (OrigOpInst->hasOneUse() && !canCreateUndefOrPoison(dyn_cast(OrigOp))) { - Optional MaybePoisonOperand; - for (Use &U : OrigOpInst->operands()) { - if (isGuaranteedNotToBeUndefOrPoison(U.get())) - continue; - if (!MaybePoisonOperand) - MaybePoisonOperand = &U; - else if(MaybePoisonOperand) - return nullptr; - } + auto *OrigOpInst = dyn_cast(OrigOp); - if (!MaybePoisonOperand.hasValue()) - return nullptr; + if (!OrigOpInst) + return nullptr; - auto *MaybePoisonUse = MaybePoisonOperand.getValue(); - auto *FrozenMaybePoisonOperand = new FreezeInst(MaybePoisonUse->get(), MaybePoisonUse->getUser()->getName() + ".fr"); + if (!OrigOpInst->hasOneUse() || + canCreateUndefOrPoison(dyn_cast(OrigOp))) + return nullptr; - replaceUse(*MaybePoisonUse, FrozenMaybePoisonOperand); - FrozenMaybePoisonOperand->insertBefore(OrigOpInst); - return OrigOp; - } + // If operand is guaranteed not to be poison, there is no need to add freeze + // to the operand. So we first find the operand that is not guranteed to be + // poison. + Use *MaybePoisonOperand; + for (Use &U : OrigOpInst->operands()) { + if (isGuaranteedNotToBeUndefOrPoison(U.get())) + continue; + if (!MaybePoisonOperand) + MaybePoisonOperand = &U; + else + return nullptr; } - return nullptr; + + // If all operands are guaranteed to be non-poison, we can drop freeze. + if (!MaybePoisonOperand) + return OrigOp; + + auto *FrozenMaybePoisonOperand = + new FreezeInst(MaybePoisonOperand->get(), + MaybePoisonOperand->getUser()->getName() + ".fr"); + + replaceUse(*MaybePoisonOperand, FrozenMaybePoisonOperand); + FrozenMaybePoisonOperand->insertBefore(OrigOpInst); + return OrigOp; } Instruction *InstCombinerImpl::visitFreeze(FreezeInst &I) {