From bceafb7f249cc9286e54664bcfd08307b86c16b9 Mon Sep 17 00:00:00 2001 From: ManuelJBrito Date: Tue, 21 Feb 2023 21:58:27 +0000 Subject: [PATCH] [InstCombine] Don't fold freeze poison when it's used in shufflevector With this patch freeze undef/poison will no longer be folded into a constant if it's used as a vector operand in a shufflevector. Differential Revision: https://reviews.llvm.org/D143593 --- .../InstCombine/InstructionCombining.cpp | 19 +++++++- .../InstCombine/shufflevector_freezepoison.ll | 55 ++++++++++++++++++---- 2 files changed, 63 insertions(+), 11 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp index 2679e0a..2621a83 100644 --- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -3959,6 +3959,17 @@ bool InstCombinerImpl::freezeOtherUses(FreezeInst &FI) { return Changed; } +// Check if any direct or bitcast user of this value is a shuffle instruction. +static bool isUsedWithinShuffleVector(Value *V) { + for (auto *U : V->users()) { + if (isa(U)) + return true; + else if (match(U, m_BitCast(m_Specific(V))) && isUsedWithinShuffleVector(U)) + return true; + } + return false; +} + Instruction *InstCombinerImpl::visitFreeze(FreezeInst &I) { Value *Op0 = I.getOperand(0); @@ -4008,8 +4019,14 @@ Instruction *InstCombinerImpl::visitFreeze(FreezeInst &I) { return BestValue; }; - if (match(Op0, m_Undef())) + if (match(Op0, m_Undef())) { + // Don't fold freeze(undef/poison) if it's used as a vector operand in + // a shuffle. This may improve codegen for shuffles that allow + // unspecified inputs. + if (isUsedWithinShuffleVector(&I)) + 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 index 6a8a88e..9b7dc4b 100644 --- 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_op0_freeze_poison(<2 x double> %a) { 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_op1_freeze_poison(<2 x double> %a) { 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_op0_freeze_poison_use(<2 x double> %a) { 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_op1_freeze_poison_use(<2 x double> %a) { 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_op0_freeze_undef(<2 x double> %a) { 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 @@ -70,5 +76,34 @@ define <4 x double> @shuffle_op1_freeze_undef(<2 x double> %a) { ret <4 x double> %shuffle } +define <4 x double> @shuffle_bc1(<2 x double> %a) { +; CHECK-LABEL: @shuffle_bc1( +; CHECK-NEXT: [[B:%.*]] = freeze <4 x float> poison +; CHECK-NEXT: [[B1:%.*]] = bitcast <4 x float> [[B]] to <2 x double> +; CHECK-NEXT: [[SHUFFLE:%.*]] = shufflevector <2 x double> [[A:%.*]], <2 x double> [[B1]], <4 x i32> +; CHECK-NEXT: ret <4 x double> [[SHUFFLE]] +; + %b = freeze <4 x float> poison + %b1 = bitcast <4 x float> %b to <2 x double> + %shuffle = shufflevector <2 x double> %a, <2 x double> %b1, <4 x i32> + ret <4 x double> %shuffle +} + +define <8 x float> @shuffle_bc2(<4 x float> %a) { +; CHECK-LABEL: @shuffle_bc2( +; CHECK-NEXT: [[B:%.*]] = freeze <4 x float> poison +; CHECK-NEXT: [[B1:%.*]] = bitcast <4 x float> [[B]] to <2 x double> +; CHECK-NEXT: call void @use(<2 x double> [[B1]]) +; CHECK-NEXT: [[SHUFFLE:%.*]] = shufflevector <4 x float> [[A:%.*]], <4 x float> [[B]], <8 x i32> +; CHECK-NEXT: ret <8 x float> [[SHUFFLE]] +; + %b = freeze <4 x float> poison + %b1 = bitcast <4 x float> %b to <2 x double> + call void @use(<2 x double> %b1) + %b2 = bitcast <2 x double> %b1 to <4 x float> + %shuffle = shufflevector <4 x float> %a, <4 x float> %b2, <8 x i32> + ret <8 x float> %shuffle +} + declare void @use(<2 x double>) -- 2.7.4