diff --git a/llvm/lib/Transforms/InstCombine/InstCombineInternal.h b/llvm/lib/Transforms/InstCombine/InstCombineInternal.h index 3f1bcea3727f5..11aed7754c264 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineInternal.h +++ b/llvm/lib/Transforms/InstCombine/InstCombineInternal.h @@ -167,6 +167,7 @@ class LLVM_LIBRARY_VISIBILITY InstCombinerImpl final Instruction *visitInsertValueInst(InsertValueInst &IV); Instruction *visitInsertElementInst(InsertElementInst &IE); Instruction *visitExtractElementInst(ExtractElementInst &EI); + Instruction *simplifyBinOpSplats(ShuffleVectorInst &SVI); Instruction *visitShuffleVectorInst(ShuffleVectorInst &SVI); Instruction *visitExtractValueInst(ExtractValueInst &EV); Instruction *visitLandingPadInst(LandingPadInst &LI); diff --git a/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp b/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp index d50918629ba5c..5964c96619a6c 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp @@ -2598,6 +2598,35 @@ static Instruction *foldIdentityPaddedShuffles(ShuffleVectorInst &Shuf) { return new ShuffleVectorInst(X, Y, NewMask); } +// Splatting the first element of the result of a BinOp, where any of the +// BinOp's operands are the result of a first element splat can be simplified to +// splatting the first element of the result of the BinOp +Instruction *InstCombinerImpl::simplifyBinOpSplats(ShuffleVectorInst &SVI) { + if (!match(SVI.getOperand(1), m_Undef()) || + !match(SVI.getShuffleMask(), m_ZeroMask())) + return nullptr; + + Value *Op0 = SVI.getOperand(0); + Value *X, *Y; + if (!match(Op0, m_BinOp(m_Shuffle(m_Value(X), m_Undef(), m_ZeroMask()), + m_Value(Y))) && + !match(Op0, m_BinOp(m_Value(X), + m_Shuffle(m_Value(Y), m_Undef(), m_ZeroMask())))) + return nullptr; + if (X->getType() != Y->getType()) + return nullptr; + + auto *BinOp = cast(Op0); + if (!isSafeToSpeculativelyExecute(BinOp)) + return nullptr; + + Value *NewBO = Builder.CreateBinOp(BinOp->getOpcode(), X, Y); + if (auto NewBOI = dyn_cast(NewBO)) + NewBOI->copyIRFlags(BinOp); + + return new ShuffleVectorInst(NewBO, SVI.getShuffleMask()); +} + Instruction *InstCombinerImpl::visitShuffleVectorInst(ShuffleVectorInst &SVI) { Value *LHS = SVI.getOperand(0); Value *RHS = SVI.getOperand(1); @@ -2606,7 +2635,9 @@ Instruction *InstCombinerImpl::visitShuffleVectorInst(ShuffleVectorInst &SVI) { SVI.getType(), ShufQuery)) return replaceInstUsesWith(SVI, V); - // Bail out for scalable vectors + if (Instruction *I = simplifyBinOpSplats(SVI)) + return I; + if (isa(LHS->getType())) return nullptr; diff --git a/llvm/test/Transforms/InstCombine/shuffle-binop.ll b/llvm/test/Transforms/InstCombine/shuffle-binop.ll index fe2d1af5a04f3..0be6a5bf9918c 100644 --- a/llvm/test/Transforms/InstCombine/shuffle-binop.ll +++ b/llvm/test/Transforms/InstCombine/shuffle-binop.ll @@ -50,13 +50,13 @@ define <4 x i8> @splat_binop_splat_x(<4 x i8> %x, <4 x i8> %y) { ; CHECK-LABEL: @splat_binop_splat_x( ; CHECK-NEXT: [[XSPLAT:%.*]] = shufflevector <4 x i8> [[X:%.*]], <4 x i8> poison, <4 x i32> zeroinitializer ; CHECK-NEXT: call void @use(<4 x i8> [[XSPLAT]]) -; CHECK-NEXT: [[B:%.*]] = add <4 x i8> [[XSPLAT]], [[Y:%.*]] -; CHECK-NEXT: [[BSPLAT:%.*]] = shufflevector <4 x i8> [[B]], <4 x i8> poison, <4 x i32> zeroinitializer +; CHECK-NEXT: [[TMP1:%.*]] = add nsw <4 x i8> [[X]], [[Y:%.*]] +; CHECK-NEXT: [[BSPLAT:%.*]] = shufflevector <4 x i8> [[TMP1]], <4 x i8> poison, <4 x i32> zeroinitializer ; CHECK-NEXT: ret <4 x i8> [[BSPLAT]] ; %xsplat = shufflevector <4 x i8> %x, <4 x i8> poison, <4 x i32> zeroinitializer call void @use(<4 x i8> %xsplat) - %b = add <4 x i8> %xsplat, %y + %b = add nsw <4 x i8> %xsplat, %y %bsplat = shufflevector <4 x i8> %b, <4 x i8> poison, <4 x i32> zeroinitializer ret <4 x i8> %bsplat } @@ -65,14 +65,14 @@ define <4 x i8> @splat_binop_splat_y(<4 x i8> %x, <4 x i8> %y) { ; CHECK-LABEL: @splat_binop_splat_y( ; CHECK-NEXT: [[YSPLAT:%.*]] = shufflevector <4 x i8> [[Y:%.*]], <4 x i8> poison, <4 x i32> zeroinitializer ; CHECK-NEXT: call void @use(<4 x i8> [[YSPLAT]]) -; CHECK-NEXT: [[B:%.*]] = sub <4 x i8> [[X:%.*]], [[YSPLAT]] -; CHECK-NEXT: [[BSPLAT:%.*]] = shufflevector <4 x i8> [[B]], <4 x i8> poison, <4 x i32> zeroinitializer +; CHECK-NEXT: [[TMP1:%.*]] = sub <4 x i8> [[X:%.*]], [[Y]] +; CHECK-NEXT: [[BSPLAT:%.*]] = shufflevector <4 x i8> [[TMP1]], <4 x i8> poison, <4 x i32> ; CHECK-NEXT: ret <4 x i8> [[BSPLAT]] ; %ysplat = shufflevector <4 x i8> %y, <4 x i8> poison, <4 x i32> zeroinitializer call void @use(<4 x i8> %ysplat) %b = sub <4 x i8> %x, %ysplat - %bsplat = shufflevector <4 x i8> %b, <4 x i8> poison, <4 x i32> zeroinitializer + %bsplat = shufflevector <4 x i8> %b, <4 x i8> poison, <4 x i32> ret <4 x i8> %bsplat } @@ -82,21 +82,40 @@ define <4 x i8> @splat_binop_splat_x_splat_y(<4 x i8> %x, <4 x i8> %y) { ; CHECK-NEXT: call void @use(<4 x i8> [[XSPLAT]]) ; CHECK-NEXT: [[YSPLAT:%.*]] = shufflevector <4 x i8> [[Y:%.*]], <4 x i8> poison, <4 x i32> zeroinitializer ; CHECK-NEXT: call void @use(<4 x i8> [[YSPLAT]]) -; CHECK-NEXT: [[B:%.*]] = mul <4 x i8> [[XSPLAT]], [[YSPLAT]] -; CHECK-NEXT: [[BSPLAT:%.*]] = shufflevector <4 x i8> [[B]], <4 x i8> poison, <4 x i32> zeroinitializer +; CHECK-NEXT: [[TMP1:%.*]] = mul nuw <4 x i8> [[Y]], [[X]] +; CHECK-NEXT: [[BSPLAT:%.*]] = shufflevector <4 x i8> [[TMP1]], <4 x i8> poison, <4 x i32> zeroinitializer ; CHECK-NEXT: ret <4 x i8> [[BSPLAT]] ; %xsplat = shufflevector <4 x i8> %x, <4 x i8> poison, <4 x i32> zeroinitializer call void @use(<4 x i8> %xsplat) %ysplat = shufflevector <4 x i8> %y, <4 x i8> poison, <4 x i32> zeroinitializer call void @use(<4 x i8> %ysplat) - %b = mul <4 x i8> %xsplat, %ysplat + %b = mul nuw <4 x i8> %xsplat, %ysplat %bsplat = shufflevector <4 x i8> %b, <4 x i8> poison, <4 x i32> zeroinitializer ret <4 x i8> %bsplat } -define @vscale_splat_binop_splat_x( %x, %y) { -; CHECK-LABEL: @vscale_splat_binop_splat_x( +define <4 x float> @splat_binop_splat_x_splat_y_fmath_flags(<4 x float> %x, <4 x float> %y) { +; CHECK-LABEL: @splat_binop_splat_x_splat_y_fmath_flags( +; CHECK-NEXT: [[XSPLAT:%.*]] = shufflevector <4 x float> [[X:%.*]], <4 x float> poison, <4 x i32> zeroinitializer +; CHECK-NEXT: call void @use(<4 x float> [[XSPLAT]]) +; CHECK-NEXT: [[YSPLAT:%.*]] = shufflevector <4 x float> [[Y:%.*]], <4 x float> poison, <4 x i32> zeroinitializer +; CHECK-NEXT: call void @use(<4 x float> [[YSPLAT]]) +; CHECK-NEXT: [[TMP1:%.*]] = fmul fast <4 x float> [[Y]], [[X]] +; CHECK-NEXT: [[BSPLAT:%.*]] = shufflevector <4 x float> [[TMP1]], <4 x float> poison, <4 x i32> zeroinitializer +; CHECK-NEXT: ret <4 x float> [[BSPLAT]] +; + %xsplat = shufflevector <4 x float> %x, <4 x float> poison, <4 x i32> zeroinitializer + call void @use(<4 x float> %xsplat) + %ysplat = shufflevector <4 x float> %y, <4 x float> poison, <4 x i32> zeroinitializer + call void @use(<4 x float> %ysplat) + %b = fmul fast <4 x float> %xsplat, %ysplat + %bsplat = shufflevector <4 x float> %b, <4 x float> poison, <4 x i32> zeroinitializer + ret <4 x float> %bsplat +} + +define @vscale_splat_udiv_splat_x( %x, %y) { +; CHECK-LABEL: @vscale_splat_udiv_splat_x( ; CHECK-NEXT: [[XSPLAT:%.*]] = shufflevector [[X:%.*]], poison, zeroinitializer ; CHECK-NEXT: [[B:%.*]] = udiv [[XSPLAT]], [[Y:%.*]] ; CHECK-NEXT: [[BSPLAT:%.*]] = shufflevector [[B]], poison, zeroinitializer @@ -108,6 +127,19 @@ define @vscale_splat_binop_splat_x( %x, %bsplat } +define @vscale_splat_urem_splat_x( %x, %y) { +; CHECK-LABEL: @vscale_splat_urem_splat_x( +; CHECK-NEXT: [[XSPLAT:%.*]] = shufflevector [[X:%.*]], poison, zeroinitializer +; CHECK-NEXT: [[B:%.*]] = urem [[XSPLAT]], [[Y:%.*]] +; CHECK-NEXT: [[BSPLAT:%.*]] = shufflevector [[B]], poison, zeroinitializer +; CHECK-NEXT: ret [[BSPLAT]] +; + %xsplat = shufflevector %x, poison, zeroinitializer + %b = urem %xsplat, %y + %bsplat = shufflevector %b, poison, zeroinitializer + ret %bsplat +} + define @vscale_splat_binop_splat_y( %x, %y) { ; CHECK-LABEL: @vscale_splat_binop_splat_y( ; CHECK-NEXT: [[YSPLAT:%.*]] = shufflevector [[Y:%.*]], poison, zeroinitializer @@ -140,8 +172,8 @@ define @vscale_splat_binop_splat_x_splat_y_calls( [[XSPLAT]]) ; CHECK-NEXT: [[YSPLAT:%.*]] = shufflevector [[Y:%.*]], poison, zeroinitializer ; CHECK-NEXT: call void @use_v( [[YSPLAT]]) -; CHECK-NEXT: [[B:%.*]] = lshr [[XSPLAT]], [[YSPLAT]] -; CHECK-NEXT: [[BSPLAT:%.*]] = shufflevector [[B]], poison, zeroinitializer +; CHECK-NEXT: [[TMP1:%.*]] = lshr [[X]], [[Y]] +; CHECK-NEXT: [[BSPLAT:%.*]] = shufflevector [[TMP1]], poison, zeroinitializer ; CHECK-NEXT: ret [[BSPLAT]] ; %xsplat = shufflevector %x, poison, zeroinitializer @@ -153,5 +185,22 @@ define @vscale_splat_binop_splat_x_splat_y_calls( %bsplat } +define <2 x double> @shuffle_op2_0th_element_mask(ptr %a, ptr %b) { + ;%0 = load <2 x double>, ptr @d, align 16 +; CHECK-LABEL: @shuffle_op2_0th_element_mask( +; CHECK-NEXT: [[TMP1:%.*]] = load <2 x double>, ptr [[A:%.*]], align 16 +; CHECK-NEXT: [[TMP2:%.*]] = load <2 x double>, ptr [[B:%.*]], align 16 +; CHECK-NEXT: [[TMP3:%.*]] = fsub <2 x double> [[TMP2]], [[TMP1]] +; CHECK-NEXT: [[SHUFFLE:%.*]] = shufflevector <2 x double> [[TMP3]], <2 x double> poison, <2 x i32> zeroinitializer +; CHECK-NEXT: ret <2 x double> [[SHUFFLE]] +; + %1 = load <2 x double>, ptr %a, align 16 + %2 = shufflevector <2 x double> %1, <2 x double> poison, <2 x i32> zeroinitializer + %3 = load <2 x double>, ptr %b, align 16 + %sub = fsub <2 x double> %3, %2 + %shuffle = shufflevector <2 x double> %sub, <2 x double> %sub, <2 x i32> + ret <2 x double> %shuffle +} + declare void @use(<4 x i8>) -declare void @use_v() \ No newline at end of file +declare void @use_v() diff --git a/llvm/test/Transforms/VectorCombine/AArch64/insert-shuffle-binop.ll b/llvm/test/Transforms/VectorCombine/AArch64/insert-shuffle-binop.ll deleted file mode 100644 index c75f53bc68583..0000000000000 --- a/llvm/test/Transforms/VectorCombine/AArch64/insert-shuffle-binop.ll +++ /dev/null @@ -1,216 +0,0 @@ -; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -; RUN: opt -passes='vector-combine' -S %s | FileCheck %s - -target triple = "aarch64-none-eabi" - -define @fadd_vscale_insertelt_a_shuffle_insert_b(float %0, float %1) { -; CHECK-LABEL: @fadd_vscale_insertelt_a_shuffle_insert_b( -; CHECK-NEXT: [[BROADCAST_SPLATINSERT:%.*]] = insertelement poison, float [[TMP0:%.*]], i64 0 -; CHECK-NEXT: [[BROADCAST_SPLAT:%.*]] = shufflevector [[BROADCAST_SPLATINSERT]], poison, zeroinitializer -; CHECK-NEXT: [[BROADCAST_SPLATINSERT2:%.*]] = insertelement poison, float [[TMP1:%.*]], i64 0 -; CHECK-NEXT: [[R:%.*]] = fadd fast [[BROADCAST_SPLATINSERT2]], [[BROADCAST_SPLAT]] -; CHECK-NEXT: [[TMP3:%.*]] = shufflevector [[R]], poison, zeroinitializer -; CHECK-NEXT: ret [[TMP3]] -; - %broadcast.splatinsert = insertelement poison, float %0, i64 0 - %broadcast.splat = shufflevector %broadcast.splatinsert, poison, zeroinitializer - %broadcast.splatinsert2 = insertelement poison, float %1, i64 0 - %r = fadd fast %broadcast.splatinsert2, %broadcast.splat - %3 = shufflevector %r, poison, zeroinitializer - ret %3 -} - -define <4 x float> @fadd_fixed_insertelt_a_shuffle_insert_b(float %0, float %1) { -; CHECK-LABEL: @fadd_fixed_insertelt_a_shuffle_insert_b( -; CHECK-NEXT: [[BROADCAST_SPLATINSERT:%.*]] = insertelement <4 x float> poison, float [[TMP0:%.*]], i64 0 -; CHECK-NEXT: [[BROADCAST_SPLAT:%.*]] = shufflevector <4 x float> [[BROADCAST_SPLATINSERT]], <4 x float> poison, <4 x i32> zeroinitializer -; CHECK-NEXT: [[BROADCAST_SPLATINSERT2:%.*]] = insertelement <4 x float> poison, float [[TMP1:%.*]], i64 0 -; CHECK-NEXT: [[R:%.*]] = fadd fast <4 x float> [[BROADCAST_SPLATINSERT2]], [[BROADCAST_SPLAT]] -; CHECK-NEXT: [[TMP3:%.*]] = shufflevector <4 x float> [[R]], <4 x float> poison, <4 x i32> zeroinitializer -; CHECK-NEXT: ret <4 x float> [[TMP3]] -; - %broadcast.splatinsert = insertelement <4 x float> poison, float %0, i64 0 - %broadcast.splat = shufflevector <4 x float> %broadcast.splatinsert, <4 x float> poison, <4 x i32> zeroinitializer - %broadcast.splatinsert2 = insertelement <4 x float> poison, float %1, i64 0 - %r = fadd fast <4 x float> %broadcast.splatinsert2, %broadcast.splat - %3 = shufflevector <4 x float> %r, <4 x float> poison, <4 x i32> zeroinitializer - ret <4 x float> %3 -} - -define @fsub_vscale_insertelt_a_shuffle_insert_b(float %0, float %1) { -; CHECK-LABEL: @fsub_vscale_insertelt_a_shuffle_insert_b( -; CHECK-NEXT: [[BROADCAST_SPLATINSERT:%.*]] = insertelement poison, float [[TMP0:%.*]], i64 0 -; CHECK-NEXT: [[BROADCAST_SPLAT:%.*]] = shufflevector [[BROADCAST_SPLATINSERT]], poison, zeroinitializer -; CHECK-NEXT: [[BROADCAST_SPLATINSERT2:%.*]] = insertelement poison, float [[TMP1:%.*]], i64 0 -; CHECK-NEXT: [[R:%.*]] = fsub fast [[BROADCAST_SPLATINSERT2]], [[BROADCAST_SPLAT]] -; CHECK-NEXT: [[TMP3:%.*]] = shufflevector [[R]], poison, zeroinitializer -; CHECK-NEXT: ret [[TMP3]] -; - %broadcast.splatinsert = insertelement poison, float %0, i64 0 - %broadcast.splat = shufflevector %broadcast.splatinsert, poison, zeroinitializer - %broadcast.splatinsert2 = insertelement poison, float %1, i64 0 - %r = fsub fast %broadcast.splatinsert2, %broadcast.splat - %3 = shufflevector %r, poison, zeroinitializer - ret %3 -} - -define <4 x float> @fsub_fixed_insertelt_a_shuffle_insert_b(float %0, float %1) { -; CHECK-LABEL: @fsub_fixed_insertelt_a_shuffle_insert_b( -; CHECK-NEXT: [[BROADCAST_SPLATINSERT:%.*]] = insertelement <4 x float> poison, float [[TMP0:%.*]], i64 0 -; CHECK-NEXT: [[BROADCAST_SPLAT:%.*]] = shufflevector <4 x float> [[BROADCAST_SPLATINSERT]], <4 x float> poison, <4 x i32> zeroinitializer -; CHECK-NEXT: [[BROADCAST_SPLATINSERT2:%.*]] = insertelement <4 x float> poison, float [[TMP1:%.*]], i64 0 -; CHECK-NEXT: [[R:%.*]] = fsub fast <4 x float> [[BROADCAST_SPLATINSERT2]], [[BROADCAST_SPLAT]] -; CHECK-NEXT: [[TMP3:%.*]] = shufflevector <4 x float> [[R]], <4 x float> poison, <4 x i32> zeroinitializer -; CHECK-NEXT: ret <4 x float> [[TMP3]] -; - %broadcast.splatinsert = insertelement <4 x float> poison, float %0, i64 0 - %broadcast.splat = shufflevector <4 x float> %broadcast.splatinsert, <4 x float> poison, <4 x i32> zeroinitializer - %broadcast.splatinsert2 = insertelement <4 x float> poison, float %1, i64 0 - %r = fsub fast <4 x float> %broadcast.splatinsert2, %broadcast.splat - %3 = shufflevector <4 x float> %r, <4 x float> poison, <4 x i32> zeroinitializer - ret <4 x float> %3 -} - -define @fadd_vscale_shuffle_insert_a_insert_b(float %0, float %1) { -; CHECK-LABEL: @fadd_vscale_shuffle_insert_a_insert_b( -; CHECK-NEXT: [[BROADCAST_SPLATINSERT:%.*]] = insertelement poison, float [[TMP0:%.*]], i64 0 -; CHECK-NEXT: [[BROADCAST_SPLAT:%.*]] = shufflevector [[BROADCAST_SPLATINSERT]], poison, zeroinitializer -; CHECK-NEXT: [[BROADCAST_SPLATINSERT2:%.*]] = insertelement poison, float [[TMP1:%.*]], i64 0 -; CHECK-NEXT: [[R:%.*]] = fadd fast [[BROADCAST_SPLAT]], [[BROADCAST_SPLATINSERT2]] -; CHECK-NEXT: [[TMP3:%.*]] = shufflevector [[R]], poison, zeroinitializer -; CHECK-NEXT: ret [[TMP3]] -; - %broadcast.splatinsert = insertelement poison, float %0, i64 0 - %broadcast.splat = shufflevector %broadcast.splatinsert, poison, zeroinitializer - %broadcast.splatinsert2 = insertelement poison, float %1, i64 0 - %r = fadd fast %broadcast.splat, %broadcast.splatinsert2 - %3 = shufflevector %r, poison, zeroinitializer - ret %3 -} - -define <4 x float> @fadd_fixed_shuffle_insert_a_insert_b(float %0, float %1) { -; CHECK-LABEL: @fadd_fixed_shuffle_insert_a_insert_b( -; CHECK-NEXT: [[BROADCAST_SPLATINSERT:%.*]] = insertelement <4 x float> poison, float [[TMP0:%.*]], i64 0 -; CHECK-NEXT: [[BROADCAST_SPLAT:%.*]] = shufflevector <4 x float> [[BROADCAST_SPLATINSERT]], <4 x float> poison, <4 x i32> zeroinitializer -; CHECK-NEXT: [[BROADCAST_SPLATINSERT2:%.*]] = insertelement <4 x float> poison, float [[TMP1:%.*]], i64 0 -; CHECK-NEXT: [[R:%.*]] = fadd fast <4 x float> [[BROADCAST_SPLAT]], [[BROADCAST_SPLATINSERT2]] -; CHECK-NEXT: [[TMP3:%.*]] = shufflevector <4 x float> [[R]], <4 x float> poison, <4 x i32> zeroinitializer -; CHECK-NEXT: ret <4 x float> [[TMP3]] -; - %broadcast.splatinsert = insertelement <4 x float> poison, float %0, i64 0 - %broadcast.splat = shufflevector <4 x float> %broadcast.splatinsert, <4 x float> poison, <4 x i32> zeroinitializer - %broadcast.splatinsert2 = insertelement <4 x float> poison, float %1, i64 0 - %r = fadd fast <4 x float> %broadcast.splat, %broadcast.splatinsert2 - %3 = shufflevector <4 x float> %r, <4 x float> poison, <4 x i32> zeroinitializer - ret <4 x float> %3 -} - -define @fsub_vscale_shuffle_insert_a_insert_b(float %0, float %1) { -; CHECK-LABEL: @fsub_vscale_shuffle_insert_a_insert_b( -; CHECK-NEXT: [[BROADCAST_SPLATINSERT:%.*]] = insertelement poison, float [[TMP0:%.*]], i64 0 -; CHECK-NEXT: [[BROADCAST_SPLAT:%.*]] = shufflevector [[BROADCAST_SPLATINSERT]], poison, zeroinitializer -; CHECK-NEXT: [[BROADCAST_SPLATINSERT2:%.*]] = insertelement poison, float [[TMP1:%.*]], i64 0 -; CHECK-NEXT: [[R:%.*]] = fsub fast [[BROADCAST_SPLAT]], [[BROADCAST_SPLATINSERT2]] -; CHECK-NEXT: [[TMP3:%.*]] = shufflevector [[R]], poison, zeroinitializer -; CHECK-NEXT: ret [[TMP3]] -; - %broadcast.splatinsert = insertelement poison, float %0, i64 0 - %broadcast.splat = shufflevector %broadcast.splatinsert, poison, zeroinitializer - %broadcast.splatinsert2 = insertelement poison, float %1, i64 0 - %r = fsub fast %broadcast.splat, %broadcast.splatinsert2 - %3 = shufflevector %r, poison, zeroinitializer - ret %3 -} - -define <4 x float> @fsub_fixed_shuffle_insert_a_insert_b(float %0, float %1) { -; CHECK-LABEL: @fsub_fixed_shuffle_insert_a_insert_b( -; CHECK-NEXT: [[BROADCAST_SPLATINSERT:%.*]] = insertelement <4 x float> poison, float [[TMP0:%.*]], i64 0 -; CHECK-NEXT: [[BROADCAST_SPLAT:%.*]] = shufflevector <4 x float> [[BROADCAST_SPLATINSERT]], <4 x float> poison, <4 x i32> zeroinitializer -; CHECK-NEXT: [[BROADCAST_SPLATINSERT2:%.*]] = insertelement <4 x float> poison, float [[TMP1:%.*]], i64 0 -; CHECK-NEXT: [[R:%.*]] = fsub fast <4 x float> [[BROADCAST_SPLAT]], [[BROADCAST_SPLATINSERT2]] -; CHECK-NEXT: [[TMP3:%.*]] = shufflevector <4 x float> [[R]], <4 x float> poison, <4 x i32> zeroinitializer -; CHECK-NEXT: ret <4 x float> [[TMP3]] -; - %broadcast.splatinsert = insertelement <4 x float> poison, float %0, i64 0 - %broadcast.splat = shufflevector <4 x float> %broadcast.splatinsert, <4 x float> poison, <4 x i32> zeroinitializer - %broadcast.splatinsert2 = insertelement <4 x float> poison, float %1, i64 0 - %r = fsub fast <4 x float> %broadcast.splat, %broadcast.splatinsert2 - %3 = shufflevector <4 x float> %r, <4 x float> poison, <4 x i32> zeroinitializer - ret <4 x float> %3 -} - -define @fadd_vscale_shuffle_insert_a_shuffle_insert_b(float %0, float %1) { -; CHECK-LABEL: @fadd_vscale_shuffle_insert_a_shuffle_insert_b( -; CHECK-NEXT: [[BROADCAST_SPLATINSERT:%.*]] = insertelement poison, float [[TMP0:%.*]], i64 0 -; CHECK-NEXT: [[BROADCAST_SPLAT:%.*]] = shufflevector [[BROADCAST_SPLATINSERT]], poison, zeroinitializer -; CHECK-NEXT: [[BROADCAST_SPLATINSERT2:%.*]] = insertelement poison, float [[TMP1:%.*]], i64 0 -; CHECK-NEXT: [[BROADCAST_SPLAT2:%.*]] = shufflevector [[BROADCAST_SPLATINSERT2]], poison, zeroinitializer -; CHECK-NEXT: [[R:%.*]] = fadd fast [[BROADCAST_SPLAT]], [[BROADCAST_SPLAT2]] -; CHECK-NEXT: [[TMP3:%.*]] = shufflevector [[R]], poison, zeroinitializer -; CHECK-NEXT: ret [[TMP3]] -; - %broadcast.splatinsert = insertelement poison, float %0, i64 0 - %broadcast.splat = shufflevector %broadcast.splatinsert, poison, zeroinitializer - %broadcast.splatinsert2 = insertelement poison, float %1, i64 0 - %broadcast.splat2 = shufflevector %broadcast.splatinsert2, poison, zeroinitializer - %r = fadd fast %broadcast.splat, %broadcast.splat2 - %3 = shufflevector %r, poison, zeroinitializer - ret %3 -} - -define <4 x float> @fadd_fixed_shuffle_insert_a_shuffle_insert_b(float %0, float %1) { -; CHECK-LABEL: @fadd_fixed_shuffle_insert_a_shuffle_insert_b( -; CHECK-NEXT: [[BROADCAST_SPLATINSERT:%.*]] = insertelement <4 x float> poison, float [[TMP0:%.*]], i64 0 -; CHECK-NEXT: [[BROADCAST_SPLAT:%.*]] = shufflevector <4 x float> [[BROADCAST_SPLATINSERT]], <4 x float> poison, <4 x i32> zeroinitializer -; CHECK-NEXT: [[BROADCAST_SPLATINSERT2:%.*]] = insertelement <4 x float> poison, float [[TMP1:%.*]], i64 0 -; CHECK-NEXT: [[BROADCAST_SPLAT2:%.*]] = shufflevector <4 x float> [[BROADCAST_SPLATINSERT2]], <4 x float> poison, <4 x i32> zeroinitializer -; CHECK-NEXT: [[R:%.*]] = fadd fast <4 x float> [[BROADCAST_SPLAT]], [[BROADCAST_SPLAT2]] -; CHECK-NEXT: [[TMP3:%.*]] = shufflevector <4 x float> [[R]], <4 x float> poison, <4 x i32> zeroinitializer -; CHECK-NEXT: ret <4 x float> [[TMP3]] -; - %broadcast.splatinsert = insertelement <4 x float> poison, float %0, i64 0 - %broadcast.splat = shufflevector <4 x float> %broadcast.splatinsert, <4 x float> poison, <4 x i32> zeroinitializer - %broadcast.splatinsert2 = insertelement <4 x float> poison, float %1, i64 0 - %broadcast.splat2 = shufflevector <4 x float> %broadcast.splatinsert2, <4 x float> poison, <4 x i32> zeroinitializer - %r = fadd fast <4 x float> %broadcast.splat, %broadcast.splat2 - %3 = shufflevector <4 x float> %r, <4 x float> poison, <4 x i32> zeroinitializer - ret <4 x float> %3 -} - -define @fsub_vscale_shuffle_insert_a_shuffle_insert_b(float %0, float %1) { -; CHECK-LABEL: @fsub_vscale_shuffle_insert_a_shuffle_insert_b( -; CHECK-NEXT: [[BROADCAST_SPLATINSERT:%.*]] = insertelement poison, float [[TMP0:%.*]], i64 0 -; CHECK-NEXT: [[BROADCAST_SPLAT:%.*]] = shufflevector [[BROADCAST_SPLATINSERT]], poison, zeroinitializer -; CHECK-NEXT: [[BROADCAST_SPLATINSERT2:%.*]] = insertelement poison, float [[TMP1:%.*]], i64 0 -; CHECK-NEXT: [[BROADCAST_SPLAT2:%.*]] = shufflevector [[BROADCAST_SPLATINSERT2]], poison, zeroinitializer -; CHECK-NEXT: [[R:%.*]] = fsub fast [[BROADCAST_SPLAT]], [[BROADCAST_SPLAT2]] -; CHECK-NEXT: [[TMP3:%.*]] = shufflevector [[R]], poison, zeroinitializer -; CHECK-NEXT: ret [[TMP3]] -; - %broadcast.splatinsert = insertelement poison, float %0, i64 0 - %broadcast.splat = shufflevector %broadcast.splatinsert, poison, zeroinitializer - %broadcast.splatinsert2 = insertelement poison, float %1, i64 0 - %broadcast.splat2 = shufflevector %broadcast.splatinsert2, poison, zeroinitializer - %r = fsub fast %broadcast.splat, %broadcast.splat2 - %3 = shufflevector %r, poison, zeroinitializer - ret %3 -} - -define <4 x float> @fsub_fixed_shuffle_insert_a_shuffle_insert_b(float %0, float %1) { -; CHECK-LABEL: @fsub_fixed_shuffle_insert_a_shuffle_insert_b( -; CHECK-NEXT: [[BROADCAST_SPLATINSERT:%.*]] = insertelement <4 x float> poison, float [[TMP0:%.*]], i64 0 -; CHECK-NEXT: [[BROADCAST_SPLAT:%.*]] = shufflevector <4 x float> [[BROADCAST_SPLATINSERT]], <4 x float> poison, <4 x i32> zeroinitializer -; CHECK-NEXT: [[BROADCAST_SPLATINSERT2:%.*]] = insertelement <4 x float> poison, float [[TMP1:%.*]], i64 0 -; CHECK-NEXT: [[BROADCAST_SPLAT2:%.*]] = shufflevector <4 x float> [[BROADCAST_SPLATINSERT2]], <4 x float> poison, <4 x i32> zeroinitializer -; CHECK-NEXT: [[R:%.*]] = fsub fast <4 x float> [[BROADCAST_SPLAT]], [[BROADCAST_SPLAT2]] -; CHECK-NEXT: [[TMP3:%.*]] = shufflevector <4 x float> [[R]], <4 x float> poison, <4 x i32> zeroinitializer -; CHECK-NEXT: ret <4 x float> [[TMP3]] -; - %broadcast.splatinsert = insertelement <4 x float> poison, float %0, i64 0 - %broadcast.splat = shufflevector <4 x float> %broadcast.splatinsert, <4 x float> poison, <4 x i32> zeroinitializer - %broadcast.splatinsert2 = insertelement <4 x float> poison, float %1, i64 0 - %broadcast.splat2 = shufflevector <4 x float> %broadcast.splatinsert2, <4 x float> poison, <4 x i32> zeroinitializer - %r = fsub fast <4 x float> %broadcast.splat, %broadcast.splat2 - %3 = shufflevector <4 x float> %r, <4 x float> poison, <4 x i32> zeroinitializer - ret <4 x float> %3 -}