Index: llvm/lib/Transforms/InstCombine/InstructionCombining.cpp =================================================================== --- llvm/lib/Transforms/InstCombine/InstructionCombining.cpp +++ llvm/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -3778,29 +3778,36 @@ if (Value *NI = pushFreezeToPreventPoisonFromPropagating(I)) return replaceInstUsesWith(I, NI); - if (match(Op0, m_Undef())) { - // If I is freeze(undef), check its uses and fold it to a fixed constant. - // - or: pick -1 - // - select's condition: if the true value is constant, choose it by making - // the condition true. - // - default: pick 0 + // If I is freeze(undef), check its uses and fold it to a fixed constant. + // - or: pick -1 + // - select's condition: if the true value is constant, choose it by making + // the condition true. + // - default: pick 0 + auto getUndefReplacement = [&I](Type *Ty) { Constant *BestValue = nullptr; - Constant *NullValue = Constant::getNullValue(I.getType()); + Constant *NullValue = Constant::getNullValue(Ty); for (const auto *U : I.users()) { Constant *C = NullValue; - if (match(U, m_Or(m_Value(), m_Value()))) - C = ConstantInt::getAllOnesValue(I.getType()); + C = ConstantInt::getAllOnesValue(Ty); else if (match(U, m_Select(m_Specific(&I), m_Constant(), m_Value()))) - C = ConstantInt::getTrue(I.getType()); + C = ConstantInt::getTrue(Ty); if (!BestValue) BestValue = C; else if (BestValue != C) BestValue = NullValue; } + return BestValue; + }; - return replaceInstUsesWith(I, BestValue); + if (match(Op0, m_Undef())) + return replaceInstUsesWith(I, getUndefReplacement(I.getType())); + + Constant *C; + if (match(Op0, m_Constant(C)) && C->containsUndefOrPoisonElement()) { + Constant *ReplaceC = getUndefReplacement(I.getType()->getScalarType()); + return replaceInstUsesWith(I, Constant::replaceUndefsWith(C, ReplaceC)); } // Replace all dominated uses of Op to freeze(Op). Index: llvm/test/Transforms/InstCombine/freeze-phi.ll =================================================================== --- llvm/test/Transforms/InstCombine/freeze-phi.ll +++ llvm/test/Transforms/InstCombine/freeze-phi.ll @@ -51,10 +51,9 @@ ; CHECK: A: ; CHECK-NEXT: br label [[C:%.*]] ; CHECK: B: -; CHECK-NEXT: [[PHI_FR:%.*]] = freeze <2 x i32> ; CHECK-NEXT: br label [[C]] ; CHECK: C: -; CHECK-NEXT: [[Y:%.*]] = phi <2 x i32> [ , [[A]] ], [ [[PHI_FR]], [[B]] ] +; CHECK-NEXT: [[Y:%.*]] = phi <2 x i32> [ , [[A]] ], [ , [[B]] ] ; CHECK-NEXT: ret <2 x i32> [[Y]] ; br i1 %cond, label %A, label %B Index: llvm/test/Transforms/InstCombine/freeze.ll =================================================================== --- llvm/test/Transforms/InstCombine/freeze.ll +++ llvm/test/Transforms/InstCombine/freeze.ll @@ -89,8 +89,7 @@ define <3 x i4> @partial_undef_vec() { ; CHECK-LABEL: @partial_undef_vec( -; CHECK-NEXT: [[F:%.*]] = freeze <3 x i4> -; CHECK-NEXT: ret <3 x i4> [[F]] +; CHECK-NEXT: ret <3 x i4> ; %f = freeze <3 x i4> ret <3 x i4> %f Index: llvm/test/Transforms/InstCombine/select.ll =================================================================== --- llvm/test/Transforms/InstCombine/select.ll +++ llvm/test/Transforms/InstCombine/select.ll @@ -2633,9 +2633,7 @@ define <2 x i8> @partial_cond_freeze_constant_true_val_vec(<2 x i8> %x) { ; CHECK-LABEL: @partial_cond_freeze_constant_true_val_vec( -; CHECK-NEXT: [[COND_FR:%.*]] = freeze <2 x i1> -; CHECK-NEXT: [[S:%.*]] = select <2 x i1> [[COND_FR]], <2 x i8> , <2 x i8> [[X:%.*]] -; CHECK-NEXT: ret <2 x i8> [[S]] +; CHECK-NEXT: ret <2 x i8> ; %cond.fr = freeze <2 x i1> %s = select <2 x i1> %cond.fr, <2 x i8> , <2 x i8> %x @@ -2644,9 +2642,8 @@ define <2 x i8> @partial_cond_freeze_constant_false_val_vec(<2 x i8> %x) { ; CHECK-LABEL: @partial_cond_freeze_constant_false_val_vec( -; CHECK-NEXT: [[COND_FR:%.*]] = freeze <2 x i1> -; CHECK-NEXT: [[S:%.*]] = select <2 x i1> [[COND_FR]], <2 x i8> [[X:%.*]], <2 x i8> -; CHECK-NEXT: ret <2 x i8> [[S]] +; CHECK-NEXT: [[S1:%.*]] = insertelement <2 x i8> [[X:%.*]], i8 2, i64 1 +; CHECK-NEXT: ret <2 x i8> [[S1]] ; %cond.fr = freeze <2 x i1> %s = select <2 x i1> %cond.fr, <2 x i8> %x, <2 x i8> @@ -2655,9 +2652,7 @@ define <2 x i8> @partial_cond_freeze_both_arms_constant_vec() { ; CHECK-LABEL: @partial_cond_freeze_both_arms_constant_vec( -; CHECK-NEXT: [[COND_FR:%.*]] = freeze <2 x i1> -; CHECK-NEXT: [[S:%.*]] = select <2 x i1> [[COND_FR]], <2 x i8> , <2 x i8> -; CHECK-NEXT: ret <2 x i8> [[S]] +; CHECK-NEXT: ret <2 x i8> ; %cond.fr = freeze <2 x i1> %s = select <2 x i1> %cond.fr, <2 x i8> , <2 x i8>