diff --git a/llvm/lib/IR/Instruction.cpp b/llvm/lib/IR/Instruction.cpp --- a/llvm/lib/IR/Instruction.cpp +++ b/llvm/lib/IR/Instruction.cpp @@ -213,9 +213,10 @@ } bool Instruction::hasPoisonGeneratingMetadata() const { - return hasMetadata(LLVMContext::MD_range) || - hasMetadata(LLVMContext::MD_nonnull) || - hasMetadata(LLVMContext::MD_align); + return (hasMetadata(LLVMContext::MD_range) || + hasMetadata(LLVMContext::MD_nonnull) || + hasMetadata(LLVMContext::MD_align)) && + !hasMetadata(LLVMContext::MD_noundef); } void Instruction::dropPoisonGeneratingMetadata() { diff --git a/llvm/test/Transforms/InstCombine/select-and-or.ll b/llvm/test/Transforms/InstCombine/select-and-or.ll --- a/llvm/test/Transforms/InstCombine/select-and-or.ll +++ b/llvm/test/Transforms/InstCombine/select-and-or.ll @@ -601,3 +601,20 @@ %r = select <2 x i1> %cond, <2 x i1> %a, <2 x i1> %b ret <2 x i1> %r } + +define i1 @poison_metadata(i32 noundef %a, i1 %b) { +; CHECK-LABEL: @poison_metadata( +; CHECK-NEXT: [[C:%.*]] = call i32 @llvm.ctpop.i32(i32 [[A:%.*]]), !range [[RNG0:![0-9]+]], !noundef !1 +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C]], 3 +; CHECK-NEXT: [[R:%.*]] = and i1 [[CMP]], [[B:%.*]] +; CHECK-NEXT: ret i1 [[R]] +; + %c = call i32 @llvm.ctpop.i32(i32 %a), !range !0, !noundef !1 + %cmp = icmp ugt i32 %c, 2 + %r = select i1 %b, i1 %cmp, i1 false + ret i1 %r +} + +!0 = !{i32 0, i32 4} +!1 = !{} +declare i32 @llvm.ctpop.i32(i32)