diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp --- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp @@ -2654,13 +2654,15 @@ auto *One = ConstantInt::getTrue(SelType); auto *Zero = ConstantInt::getFalse(SelType); + // We match the "full" 0 or 1 constant here to avoid a potential infinite + // loop with vectors that may have undefined/poison elements. // select a, false, b -> select !a, b, false - if (match(TrueVal, m_Zero())) { + if (match(TrueVal, m_Specific(Zero))) { Value *NotCond = Builder.CreateNot(CondVal, "not." + CondVal->getName()); return SelectInst::Create(NotCond, FalseVal, Zero); } // select a, b, true -> select !a, true, b - if (match(FalseVal, m_One())) { + if (match(FalseVal, m_Specific(One))) { Value *NotCond = Builder.CreateNot(CondVal, "not." + CondVal->getName()); return SelectInst::Create(NotCond, One, TrueVal); } diff --git a/llvm/test/Transforms/InstCombine/select-extractelement.ll b/llvm/test/Transforms/InstCombine/select-extractelement.ll --- a/llvm/test/Transforms/InstCombine/select-extractelement.ll +++ b/llvm/test/Transforms/InstCombine/select-extractelement.ll @@ -209,5 +209,28 @@ ret <4 x i32> %r } +; This would infinite loop because a select transform would create +; a complete -1 vector constant and demanded elements would change +; it back to partial undef. + +define i32 @inf_loop_partial_undef(<2 x i1> %a, <2 x i1> %b, <2 x i32> %x, <2 x i32> %y) { +; CHECK-LABEL: @inf_loop_partial_undef( +; CHECK-NEXT: [[T5:%.*]] = add nsw <2 x i32> [[Y:%.*]], +; CHECK-NEXT: [[T6:%.*]] = icmp sge <2 x i32> [[T5]], [[X:%.*]] +; CHECK-NEXT: [[AB:%.*]] = and <2 x i1> [[A:%.*]], [[B:%.*]] +; CHECK-NEXT: [[T7:%.*]] = select <2 x i1> [[AB]], <2 x i1> [[T6]], <2 x i1> +; CHECK-NEXT: [[P:%.*]] = select <2 x i1> [[T7]], <2 x i32> , <2 x i32> [[Y]] +; CHECK-NEXT: [[T11:%.*]] = extractelement <2 x i32> [[P]], i32 0 +; CHECK-NEXT: ret i32 [[T11]] +; + %t5 = add nsw <2 x i32> %y, + %t6 = icmp slt <2 x i32> %t5, %x + %ab = and <2 x i1> %a, %b + %t7 = select <2 x i1> %ab, <2 x i1> %t6, <2 x i1> + %t10 = xor <2 x i1> %t7, + %p = select <2 x i1> %t10, <2 x i32> zeroinitializer, <2 x i32> %y + %t11 = extractelement <2 x i32> %p, i32 0 + ret i32 %t11 +} attributes #0 = { nounwind ssp uwtable "less-precise-fpmad"="false" "frame-pointer"="all" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }