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 @@ -2600,6 +2600,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 (!match(SVI.getOperand(1), m_Undef()) || + !match(SVI.getShuffleMask(), m_ZeroMask())) + return nullptr; + + Value *BinOp = SVI.getOperand(0); + Value *BinOpOp0, *BinOpOp1; + if (!match(BinOp, m_BinOp(m_Value(BinOpOp0), m_Value(BinOpOp1)))) + return nullptr; + + Value *X = nullptr, *Y = nullptr; + if (!match(BinOpOp0, m_Shuffle(m_Value(X), m_Undef(), m_ZeroMask()))) + Y = BinOpOp1; + if (!match(BinOpOp1, m_Shuffle(m_Value(Y), m_Undef(), m_ZeroMask()))) + X = BinOpOp0; + if (X == nullptr || Y == nullptr) + return nullptr; + + auto Opcode = (Instruction::BinaryOps)cast(BinOp)->getOpcode(); + Value *ScalarBinOp = Builder.CreateBinOp(Opcode, X, Y); + Value *Shuffle = + Builder.CreateShuffleVector(ScalarBinOp, SVI.getShuffleMask()); + return replaceInstUsesWith(SVI, Shuffle); +} + Instruction *InstCombinerImpl::visitShuffleVectorInst(ShuffleVectorInst &SVI) { Value *LHS = SVI.getOperand(0); Value *RHS = SVI.getOperand(1); @@ -2608,7 +2636,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/vscale-insert-shuffle-binop.ll b/llvm/test/Transforms/InstCombine/vscale-insert-shuffle-binop.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/InstCombine/vscale-insert-shuffle-binop.ll @@ -0,0 +1,82 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt -passes='instcombine' -S %s | FileCheck %s + +target triple = "aarch64-none-eabi" + +define <4 x i8> @splat_binop_splat_x(<4 x i8> %x, <4 x i8> %y) { +; CHECK-LABEL: @splat_binop_splat_x( +; CHECK-NEXT: [[TMP1:%.*]] = add <4 x i8> [[X:%.*]], [[Y:%.*]] +; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <4 x i8> [[TMP1]], <4 x i8> poison, <4 x i32> zeroinitializer +; CHECK-NEXT: ret <4 x i8> [[TMP2]] +; + %xsplat = shufflevector <4 x i8> %x, <4 x i8> poison, <4 x i32> zeroinitializer + %b = add <4 x i8> %xsplat, %y + %bsplat = shufflevector <4 x i8> %b, <4 x i8> poison, <4 x i32> zeroinitializer + ret <4 x i8> %bsplat +} + +define <4 x i8> @splat_binop_splat_y(<4 x i8> %x, <4 x i8> %y) { +; CHECK-LABEL: @splat_binop_splat_y( +; CHECK-NEXT: [[TMP1:%.*]] = add <4 x i8> [[Y:%.*]], [[X:%.*]] +; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <4 x i8> [[TMP1]], <4 x i8> poison, <4 x i32> zeroinitializer +; CHECK-NEXT: ret <4 x i8> [[TMP2]] +; + %ysplat = shufflevector <4 x i8> %y, <4 x i8> poison, <4 x i32> zeroinitializer + %b = add <4 x i8> %x, %ysplat + %bsplat = shufflevector <4 x i8> %b, <4 x i8> poison, <4 x i32> zeroinitializer + ret <4 x i8> %bsplat +} + +define <4 x i8> @splat_binop_splat_x_splat_y(<4 x i8> %x, <4 x i8> %y) { +; CHECK-LABEL: @splat_binop_splat_x_splat_y( +; CHECK-NEXT: [[TMP1:%.*]] = add <4 x i8> [[X:%.*]], [[Y:%.*]] +; CHECK-NEXT: [[B:%.*]] = shufflevector <4 x i8> [[TMP1]], <4 x i8> poison, <4 x i32> zeroinitializer +; CHECK-NEXT: ret <4 x i8> [[B]] +; + %xsplat = shufflevector <4 x i8> %x, <4 x i8> poison, <4 x i32> zeroinitializer + %ysplat = shufflevector <4 x i8> %y, <4 x i8> poison, <4 x i32> zeroinitializer + %b = add <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( +; CHECK-NEXT: [[TMP1:%.*]] = add [[X:%.*]], [[Y:%.*]] +; CHECK-NEXT: [[TMP2:%.*]] = shufflevector [[TMP1]], poison, zeroinitializer +; CHECK-NEXT: ret [[TMP2]] +; + %xsplat = shufflevector %x, poison, zeroinitializer + %b = add %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: [[TMP1:%.*]] = add [[Y:%.*]], [[X:%.*]] +; CHECK-NEXT: [[TMP2:%.*]] = shufflevector [[TMP1]], poison, zeroinitializer +; CHECK-NEXT: ret [[TMP2]] +; + %ysplat = shufflevector %y, poison, zeroinitializer + %b = add %x, %ysplat + %bsplat = shufflevector %b, poison, zeroinitializer + ret %bsplat +} + +define <4 x i8> @splat_binop_splat_call(<4 x i8> %x, <4 x i8> %y) { +; CHECK-LABEL: @splat_binop_splat_call( +; 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: [[TMP1:%.*]] = add <4 x i8> [[X]], [[Y:%.*]] +; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <4 x i8> [[TMP1]], <4 x i8> poison, <4 x i32> zeroinitializer +; CHECK-NEXT: ret <4 x i8> [[TMP2]] +; + %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 + %bsplat = shufflevector <4 x i8> %b, <4 x i8> poison, <4 x i32> zeroinitializer + ret <4 x i8> %bsplat +} + +declare void @use(<4 x i8>) 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 -}