llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-llvm-ir Author: John McIver (jmciver) <details> <summary>Changes</summary> The non-freeze poison argument to select can be one of the following: global, constant, and noundef arguments. Alive2 test validation: https://alive2.llvm.org/ce/z/jbtCS6 --- Full diff: https://github.com/llvm/llvm-project/pull/129776.diff 3 Files Affected: - (modified) llvm/include/llvm/IR/PatternMatch.h (+13) - (modified) llvm/lib/Transforms/InstCombine/InstructionCombining.cpp (+16-6) - (modified) llvm/test/Transforms/InstCombine/select.ll (+3-6) ``````````diff diff --git a/llvm/include/llvm/IR/PatternMatch.h b/llvm/include/llvm/IR/PatternMatch.h index b3eeb1d7ba88a..c66235f33cd9e 100644 --- a/llvm/include/llvm/IR/PatternMatch.h +++ b/llvm/include/llvm/IR/PatternMatch.h @@ -3124,6 +3124,19 @@ inline auto m_c_LogicalOp(const LHS &L, const RHS &R) { return m_LogicalOp<LHS, RHS, /*Commutable=*/true>(L, R); } +struct GuaranteedNotToBeUndefOrPoison_match { + template <typename ITy> bool match(ITy *V) { + if (auto *AsValue = dyn_cast<Value>(V)) + return isGuaranteedNotToBeUndefOrPoison(AsValue); + else + return false; + } +}; + +inline GuaranteedNotToBeUndefOrPoison_match m_guaranteedNotToBeUndefOrPoison() { + return GuaranteedNotToBeUndefOrPoison_match(); +} + } // end namespace PatternMatch } // end namespace llvm diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp index 4c14dcfb4d75f..6b9254692a857 100644 --- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -4813,15 +4813,22 @@ Instruction *InstCombinerImpl::visitFreeze(FreezeInst &I) { // TODO: This could use getBinopAbsorber() / getBinopIdentity() to avoid // duplicating logic for binops at least. auto getUndefReplacement = [&I](Type *Ty) { - Constant *BestValue = nullptr; - Constant *NullValue = Constant::getNullValue(Ty); + Value *BestValue = nullptr; + Value *NullValue = Constant::getNullValue(Ty); for (const auto *U : I.users()) { - Constant *C = NullValue; + Value *C = NullValue; if (match(U, m_Or(m_Value(), m_Value()))) C = ConstantInt::getAllOnesValue(Ty); else if (match(U, m_Select(m_Specific(&I), m_Constant(), m_Value()))) C = ConstantInt::getTrue(Ty); - + else if (I.hasOneUse() && + match(U, m_c_Select(m_Specific(&I), + m_guaranteedNotToBeUndefOrPoison()))) { + if (match(U->getOperand(1), m_Specific(&I))) + C = U->getOperand(2); + else + C = U->getOperand(1); + } if (!BestValue) BestValue = C; else if (BestValue != C) @@ -4842,8 +4849,11 @@ Instruction *InstCombinerImpl::visitFreeze(FreezeInst &I) { Constant *C; if (match(Op0, m_Constant(C)) && C->containsUndefOrPoisonElement()) { - Constant *ReplaceC = getUndefReplacement(I.getType()->getScalarType()); - return replaceInstUsesWith(I, Constant::replaceUndefsWith(C, ReplaceC)); + Value *Replace = getUndefReplacement(I.getType()->getScalarType()); + if (Constant *ReplaceC = dyn_cast<Constant>(Replace)) + return replaceInstUsesWith(I, Constant::replaceUndefsWith(C, ReplaceC)); + else + return replaceInstUsesWith(I, Replace); } // Replace uses of Op with freeze(Op). diff --git a/llvm/test/Transforms/InstCombine/select.ll b/llvm/test/Transforms/InstCombine/select.ll index cc25f4ce24d9a..789d98197d878 100644 --- a/llvm/test/Transforms/InstCombine/select.ll +++ b/llvm/test/Transforms/InstCombine/select.ll @@ -4904,8 +4904,7 @@ define i32 @src_simplify_2x_at_once_and(i32 %x, i32 %y) { define void @select_freeze_poison_parameter(ptr noundef %addr.src, ptr %addr.tgt, i1 %cond) { ; CHECK-LABEL: @select_freeze_poison_parameter( -; CHECK-NEXT: [[ADDR_SRC:%.*]] = select i1 [[COND:%.*]], ptr [[ADDR_SRC1:%.*]], ptr null -; CHECK-NEXT: store ptr [[ADDR_SRC]], ptr [[ADDR_TGT:%.*]], align 8 +; CHECK-NEXT: store ptr [[ADDR_SRC:%.*]], ptr [[ADDR_TGT:%.*]], align 8 ; CHECK-NEXT: ret void ; %freeze = freeze ptr poison @@ -4918,8 +4917,7 @@ define void @select_freeze_poison_parameter(ptr noundef %addr.src, ptr %addr.tgt define void @select_freeze_poison_global(ptr %addr.tgt, i1 %cond) { ; CHECK-LABEL: @select_freeze_poison_global( -; CHECK-NEXT: [[SELECT_ADDR:%.*]] = select i1 [[COND:%.*]], ptr @glb, ptr null -; CHECK-NEXT: store ptr [[SELECT_ADDR]], ptr [[ADDR_TGT:%.*]], align 8 +; CHECK-NEXT: store ptr @glb, ptr [[ADDR_TGT:%.*]], align 8 ; CHECK-NEXT: ret void ; %freeze = freeze ptr poison @@ -4930,8 +4928,7 @@ define void @select_freeze_poison_global(ptr %addr.tgt, i1 %cond) { define void @select_freeze_poison_constant(ptr %addr.tgt, i1 %cond) { ; CHECK-LABEL: @select_freeze_poison_constant( -; CHECK-NEXT: [[SELECT_ADDR:%.*]] = select i1 [[COND:%.*]], i32 72, i32 0 -; CHECK-NEXT: store i32 [[SELECT_ADDR]], ptr [[ADDR_TGT:%.*]], align 4 +; CHECK-NEXT: store i32 72, ptr [[ADDR_TGT:%.*]], align 4 ; CHECK-NEXT: ret void ; %freeze = freeze i32 poison `````````` </details> https://github.com/llvm/llvm-project/pull/129776 _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits