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 @@ -4014,8 +4014,17 @@ return BestValue; }; - if (match(Op0, m_Undef())) + if (match(Op0, m_Undef())) { + for (const auto *U : I.users()) { + // Don't fold freeze(undef/poison) if it's used has a vector operand in + // a shuffle. This may improve codegen for shuffles that allow + // unspecified inputs. + if (match(U, m_Shuffle(m_Value(), m_Specific(&I))) || + match(U, m_Shuffle(m_Specific(&I), m_Value()))) + return nullptr; + } return replaceInstUsesWith(I, getUndefReplacement(I.getType())); + } Constant *C; if (match(Op0, m_Constant(C)) && C->containsUndefOrPoisonElement()) { diff --git a/llvm/test/Transforms/InstCombine/shufflevector_freezepoison.ll b/llvm/test/Transforms/InstCombine/shufflevector_freezepoison.ll --- a/llvm/test/Transforms/InstCombine/shufflevector_freezepoison.ll +++ b/llvm/test/Transforms/InstCombine/shufflevector_freezepoison.ll @@ -4,7 +4,8 @@ define <4 x double> @shuffle_op0_freeze_poison(<2 x double> %a) { ; CHECK-LABEL: @shuffle_op0_freeze_poison( -; CHECK-NEXT: [[SHUFFLE:%.*]] = shufflevector <2 x double> zeroinitializer, <2 x double> [[A:%.*]], <4 x i32> +; CHECK-NEXT: [[B:%.*]] = freeze <2 x double> poison +; CHECK-NEXT: [[SHUFFLE:%.*]] = shufflevector <2 x double> [[B]], <2 x double> [[A:%.*]], <4 x i32> ; CHECK-NEXT: ret <4 x double> [[SHUFFLE]] ; %b = freeze <2 x double> poison @@ -14,7 +15,8 @@ define <4 x double> @shuffle_op1_freeze_poison(<2 x double> %a) { ; CHECK-LABEL: @shuffle_op1_freeze_poison( -; CHECK-NEXT: [[SHUFFLE:%.*]] = shufflevector <2 x double> [[A:%.*]], <2 x double> zeroinitializer, <4 x i32> +; CHECK-NEXT: [[B:%.*]] = freeze <2 x double> poison +; CHECK-NEXT: [[SHUFFLE:%.*]] = shufflevector <2 x double> [[A:%.*]], <2 x double> [[B]], <4 x i32> ; CHECK-NEXT: ret <4 x double> [[SHUFFLE]] ; %b = freeze <2 x double> poison @@ -24,8 +26,9 @@ define <4 x double> @shuffle_op0_freeze_poison_use(<2 x double> %a) { ; CHECK-LABEL: @shuffle_op0_freeze_poison_use( -; CHECK-NEXT: call void @use(<2 x double> zeroinitializer) -; CHECK-NEXT: [[SHUFFLE:%.*]] = shufflevector <2 x double> zeroinitializer, <2 x double> [[A:%.*]], <4 x i32> +; CHECK-NEXT: [[B:%.*]] = freeze <2 x double> poison +; CHECK-NEXT: call void @use(<2 x double> [[B]]) +; CHECK-NEXT: [[SHUFFLE:%.*]] = shufflevector <2 x double> [[B]], <2 x double> [[A:%.*]], <4 x i32> ; CHECK-NEXT: ret <4 x double> [[SHUFFLE]] ; %b = freeze <2 x double> poison @@ -36,8 +39,9 @@ define <4 x double> @shuffle_op1_freeze_poison_use(<2 x double> %a) { ; CHECK-LABEL: @shuffle_op1_freeze_poison_use( -; CHECK-NEXT: call void @use(<2 x double> zeroinitializer) -; CHECK-NEXT: [[SHUFFLE:%.*]] = shufflevector <2 x double> [[A:%.*]], <2 x double> zeroinitializer, <4 x i32> +; CHECK-NEXT: [[B:%.*]] = freeze <2 x double> poison +; CHECK-NEXT: call void @use(<2 x double> [[B]]) +; CHECK-NEXT: [[SHUFFLE:%.*]] = shufflevector <2 x double> [[A:%.*]], <2 x double> [[B]], <4 x i32> ; CHECK-NEXT: ret <4 x double> [[SHUFFLE]] ; %b = freeze <2 x double> poison @@ -48,8 +52,9 @@ define <4 x double> @shuffle_op0_freeze_undef(<2 x double> %a) { ; CHECK-LABEL: @shuffle_op0_freeze_undef( -; CHECK-NEXT: call void @use(<2 x double> zeroinitializer) -; CHECK-NEXT: [[SHUFFLE:%.*]] = shufflevector <2 x double> zeroinitializer, <2 x double> [[A:%.*]], <4 x i32> +; CHECK-NEXT: [[B:%.*]] = freeze <2 x double> undef +; CHECK-NEXT: call void @use(<2 x double> [[B]]) +; CHECK-NEXT: [[SHUFFLE:%.*]] = shufflevector <2 x double> [[B]], <2 x double> [[A:%.*]], <4 x i32> ; CHECK-NEXT: ret <4 x double> [[SHUFFLE]] ; %b = freeze <2 x double> undef @@ -60,8 +65,9 @@ define <4 x double> @shuffle_op1_freeze_undef(<2 x double> %a) { ; CHECK-LABEL: @shuffle_op1_freeze_undef( -; CHECK-NEXT: call void @use(<2 x double> zeroinitializer) -; CHECK-NEXT: [[SHUFFLE:%.*]] = shufflevector <2 x double> [[A:%.*]], <2 x double> zeroinitializer, <4 x i32> +; CHECK-NEXT: [[B:%.*]] = freeze <2 x double> undef +; CHECK-NEXT: call void @use(<2 x double> [[B]]) +; CHECK-NEXT: [[SHUFFLE:%.*]] = shufflevector <2 x double> [[A:%.*]], <2 x double> [[B]], <4 x i32> ; CHECK-NEXT: ret <4 x double> [[SHUFFLE]] ; %b = freeze <2 x double> undef