diff --git a/llvm/lib/Transforms/InstCombine/InstCombineInternal.h b/llvm/lib/Transforms/InstCombine/InstCombineInternal.h --- a/llvm/lib/Transforms/InstCombine/InstCombineInternal.h +++ b/llvm/lib/Transforms/InstCombine/InstCombineInternal.h @@ -167,6 +167,7 @@ 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 --- a/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp @@ -2598,6 +2598,34 @@ 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 (!SVI.isZeroEltSplat()) + 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 +2634,9 @@ 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 --- a/llvm/test/Transforms/InstCombine/shuffle-binop.ll +++ b/llvm/test/Transforms/InstCombine/shuffle-binop.ll @@ -50,13 +50,13 @@ ; 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 @@ ; 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 @@ ; 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 @@ ret %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 @@ ; CHECK-NEXT: call void @use_v( [[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 @@ -154,4 +186,4 @@ } 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 --- 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 -}