[VectorCombine] scalarizeBinop - support an all-constant src vector operand

scalarizeBinop currently folds

  vec_bo((inselt VecC0, V0, Index), (inselt VecC1, V1, Index))
  ->
  inselt(vec_bo(VecC0, VecC1), scl_bo(V0,V1), Index)

This patch extends this to account for cases where one of the vec_bo operands is already all-constant and performs similar cost checks to determine if the scalar binop with a constant still makes sense:

  vec_bo((inselt VecC0, V0, Index), VecC1)
  ->
  inselt(vec_bo(VecC0, VecC1), scl_bo(V0,extractelt(V1,Index)), Index)

Fixes PR42174

Differential Revision: https://reviews.llvm.org/D80885
This commit is contained in:
Simon Pilgrim 2020-06-09 18:36:14 +01:00
parent bc38793852
commit 5dc4e7c2b9
3 changed files with 202 additions and 160 deletions

View File

@ -313,23 +313,48 @@ static bool foldBitcastShuf(Instruction &I, const TargetTransformInfo &TTI) {
/// Match a vector binop instruction with inserted scalar operands and convert
/// to scalar binop followed by insertelement.
static bool scalarizeBinop(Instruction &I, const TargetTransformInfo &TTI) {
Instruction *Ins0, *Ins1;
if (!match(&I, m_BinOp(m_Instruction(Ins0), m_Instruction(Ins1))))
Value *Ins0, *Ins1;
if (!match(&I, m_BinOp(m_Value(Ins0), m_Value(Ins1))))
return false;
// Match against one or both scalar values being inserted into constant
// vectors:
// vec_bo VecC0, (inselt VecC1, V1, Index)
// vec_bo (inselt VecC0, V0, Index), VecC1
// vec_bo (inselt VecC0, V0, Index), (inselt VecC1, V1, Index)
// TODO: Deal with mismatched index constants and variable indexes?
Constant *VecC0, *VecC1;
Value *V0, *V1;
uint64_t Index;
Constant *VecC0 = nullptr, *VecC1 = nullptr;
Value *V0 = nullptr, *V1 = nullptr;
uint64_t Index0 = 0, Index1 = 0;
if (!match(Ins0, m_InsertElt(m_Constant(VecC0), m_Value(V0),
m_ConstantInt(Index))) ||
!match(Ins1, m_InsertElt(m_Constant(VecC1), m_Value(V1),
m_SpecificInt(Index))))
m_ConstantInt(Index0))) &&
!match(Ins0, m_Constant(VecC0)))
return false;
if (!match(Ins1, m_InsertElt(m_Constant(VecC1), m_Value(V1),
m_ConstantInt(Index1))) &&
!match(Ins1, m_Constant(VecC1)))
return false;
Type *ScalarTy = V0->getType();
bool IsConst0 = !V0;
bool IsConst1 = !V1;
if (IsConst0 && IsConst1)
return false;
if (!IsConst0 && !IsConst1 && Index0 != Index1)
return false;
// Bail for single insertion if it is a load.
// TODO: Handle this once getVectorInstrCost can cost for load/stores.
auto *I0 = dyn_cast_or_null<Instruction>(V0);
auto *I1 = dyn_cast_or_null<Instruction>(V1);
if ((IsConst0 && I1 && I1->mayReadFromMemory()) ||
(IsConst1 && I0 && I0->mayReadFromMemory()))
return false;
uint64_t Index = IsConst0 ? Index1 : Index0;
Type *ScalarTy = IsConst0 ? V1->getType() : V0->getType();
Type *VecTy = I.getType();
assert(VecTy->isVectorTy() && ScalarTy == V1->getType() &&
assert(VecTy->isVectorTy() &&
(IsConst0 || IsConst1 || V0->getType() == V1->getType()) &&
(ScalarTy->isIntegerTy() || ScalarTy->isFloatingPointTy()) &&
"Unexpected types for insert into binop");
@ -341,10 +366,11 @@ static bool scalarizeBinop(Instruction &I, const TargetTransformInfo &TTI) {
// both sequences.
int InsertCost =
TTI.getVectorInstrCost(Instruction::InsertElement, VecTy, Index);
int OldCost = InsertCost + InsertCost + VectorOpCost;
int OldCost = (IsConst0 ? 0 : InsertCost) + (IsConst1 ? 0 : InsertCost) +
VectorOpCost;
int NewCost = ScalarOpCost + InsertCost +
!Ins0->hasOneUse() * InsertCost +
!Ins1->hasOneUse() * InsertCost;
(IsConst0 ? 0 : !Ins0->hasOneUse() * InsertCost) +
(IsConst1 ? 0 : !Ins1->hasOneUse() * InsertCost);
// We want to scalarize unless the vector variant actually has lower cost.
if (OldCost < NewCost)
@ -354,6 +380,13 @@ static bool scalarizeBinop(Instruction &I, const TargetTransformInfo &TTI) {
// inselt NewVecC, (scalar_bo V0, V1), Index
++NumScalarBO;
IRBuilder<> Builder(&I);
// For constant cases, extract the scalar element, this should constant fold.
if (IsConst0)
V0 = ConstantExpr::getExtractElement(VecC0, Builder.getInt64(Index));
if (IsConst1)
V1 = ConstantExpr::getExtractElement(VecC1, Builder.getInt64(Index));
Value *Scalar = Builder.CreateBinOp(Opcode, V0, V1, I.getName() + ".scalar");
// All IR flags are safe to back-propagate. There is no potential for extra

View File

@ -12,31 +12,24 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
define <4 x i32> @square(<4 x i32> %num, i32 %y, i32 %x, i32 %h, i32 %k, i32 %w, i32 %p, i32 %j, i32 %u) {
; CHECK-LABEL: @square(
; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[K:%.*]], 2
; CHECK-NEXT: [[SPLATINSERT:%.*]] = insertelement <4 x i32> undef, i32 [[DIV]], i32 0
; CHECK-NEXT: [[MUL:%.*]] = mul nsw i32 [[P:%.*]], 6234
; CHECK-NEXT: [[SPLATINSERT2:%.*]] = insertelement <4 x i32> undef, i32 [[MUL]], i32 0
; CHECK-NEXT: [[MUL5:%.*]] = mul nsw i32 [[H:%.*]], 75
; CHECK-NEXT: [[SPLATINSERT6:%.*]] = insertelement <4 x i32> undef, i32 [[MUL5]], i32 0
; CHECK-NEXT: [[DIV9:%.*]] = sdiv i32 [[J:%.*]], 3452
; CHECK-NEXT: [[SPLATINSERT10:%.*]] = insertelement <4 x i32> undef, i32 [[DIV9]], i32 0
; CHECK-NEXT: [[MUL13:%.*]] = mul nsw i32 [[W:%.*]], 53
; CHECK-NEXT: [[SPLATINSERT14:%.*]] = insertelement <4 x i32> undef, i32 [[MUL13]], i32 0
; CHECK-NEXT: [[DIV17:%.*]] = sdiv i32 [[X:%.*]], 820
; CHECK-NEXT: [[SPLATINSERT18:%.*]] = insertelement <4 x i32> undef, i32 [[DIV17]], i32 0
; CHECK-NEXT: [[MUL21:%.*]] = shl nsw i32 [[U:%.*]], 2
; CHECK-NEXT: [[SPLATINSERT22:%.*]] = insertelement <4 x i32> undef, i32 [[MUL21]], i32 0
; CHECK-NEXT: [[SPLATINSERT25:%.*]] = insertelement <4 x i32> undef, i32 [[Y:%.*]], i32 0
; CHECK-NEXT: [[TMP1:%.*]] = add <4 x i32> [[SPLATINSERT25]], <i32 1, i32 undef, i32 undef, i32 undef>
; CHECK-NEXT: [[TMP2:%.*]] = add <4 x i32> [[TMP1]], [[SPLATINSERT18]]
; CHECK-NEXT: [[TMP3:%.*]] = add <4 x i32> [[TMP2]], [[SPLATINSERT6]]
; CHECK-NEXT: [[TMP4:%.*]] = add <4 x i32> [[TMP3]], [[SPLATINSERT]]
; CHECK-NEXT: [[TMP5:%.*]] = add <4 x i32> [[TMP4]], [[SPLATINSERT14]]
; CHECK-NEXT: [[TMP6:%.*]] = add <4 x i32> [[TMP5]], [[SPLATINSERT2]]
; CHECK-NEXT: [[TMP7:%.*]] = add <4 x i32> [[TMP6]], [[SPLATINSERT10]]
; CHECK-NEXT: [[TMP8:%.*]] = add <4 x i32> [[TMP7]], [[SPLATINSERT22]]
; CHECK-NEXT: [[TMP9:%.*]] = add <4 x i32> [[TMP8]], <i32 317425, i32 undef, i32 undef, i32 undef>
; CHECK-NEXT: [[TMP10:%.*]] = shufflevector <4 x i32> [[TMP9]], <4 x i32> undef, <4 x i32> zeroinitializer
; CHECK-NEXT: [[ADD29:%.*]] = add <4 x i32> [[TMP10]], [[NUM:%.*]]
; CHECK-NEXT: [[DOTSCALAR:%.*]] = add i32 [[Y:%.*]], 1
; CHECK-NEXT: [[DOTSCALAR1:%.*]] = add i32 [[DOTSCALAR]], [[DIV17]]
; CHECK-NEXT: [[DOTSCALAR2:%.*]] = add i32 [[DOTSCALAR1]], [[MUL5]]
; CHECK-NEXT: [[DOTSCALAR3:%.*]] = add i32 [[DOTSCALAR2]], [[DIV]]
; CHECK-NEXT: [[DOTSCALAR4:%.*]] = add i32 [[DOTSCALAR3]], [[MUL13]]
; CHECK-NEXT: [[DOTSCALAR5:%.*]] = add i32 [[DOTSCALAR4]], [[MUL]]
; CHECK-NEXT: [[DOTSCALAR6:%.*]] = add i32 [[DOTSCALAR5]], [[DIV9]]
; CHECK-NEXT: [[DOTSCALAR7:%.*]] = add i32 [[DOTSCALAR6]], [[MUL21]]
; CHECK-NEXT: [[DOTSCALAR8:%.*]] = add i32 [[DOTSCALAR7]], 317425
; CHECK-NEXT: [[TMP1:%.*]] = insertelement <4 x i32> undef, i32 [[DOTSCALAR8]], i64 0
; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> undef, <4 x i32> zeroinitializer
; CHECK-NEXT: [[ADD29:%.*]] = add <4 x i32> [[TMP2]], [[NUM:%.*]]
; CHECK-NEXT: ret <4 x i32> [[ADD29]]
;
%add = add <4 x i32> %num, <i32 1, i32 1, i32 1, i32 1>

View File

@ -4,8 +4,8 @@
define <2 x i64> @add_constant(i64 %x) {
; CHECK-LABEL: @add_constant(
; CHECK-NEXT: [[INS:%.*]] = insertelement <2 x i64> undef, i64 [[X:%.*]], i32 0
; CHECK-NEXT: [[BO:%.*]] = add <2 x i64> [[INS]], <i64 42, i64 undef>
; CHECK-NEXT: [[BO_SCALAR:%.*]] = add i64 [[X:%.*]], 42
; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x i64> undef, i64 [[BO_SCALAR]], i64 0
; CHECK-NEXT: ret <2 x i64> [[BO]]
;
%ins = insertelement <2 x i64> undef, i64 %x, i32 0
@ -15,8 +15,8 @@ define <2 x i64> @add_constant(i64 %x) {
define <2 x i64> @add_constant_not_undef_lane(i64 %x) {
; CHECK-LABEL: @add_constant_not_undef_lane(
; CHECK-NEXT: [[INS:%.*]] = insertelement <2 x i64> undef, i64 [[X:%.*]], i32 0
; CHECK-NEXT: [[BO:%.*]] = add <2 x i64> [[INS]], <i64 42, i64 -42>
; CHECK-NEXT: [[BO_SCALAR:%.*]] = add i64 [[X:%.*]], 42
; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x i64> undef, i64 [[BO_SCALAR]], i64 0
; CHECK-NEXT: ret <2 x i64> [[BO]]
;
%ins = insertelement <2 x i64> undef, i64 %x, i32 0
@ -41,8 +41,8 @@ define <2 x i64> @add_constant_load(i64* %p) {
define <4 x i32> @sub_constant_op0(i32 %x) {
; CHECK-LABEL: @sub_constant_op0(
; CHECK-NEXT: [[INS:%.*]] = insertelement <4 x i32> undef, i32 [[X:%.*]], i32 1
; CHECK-NEXT: [[BO:%.*]] = sub nuw nsw <4 x i32> <i32 undef, i32 -42, i32 undef, i32 undef>, [[INS]]
; CHECK-NEXT: [[BO_SCALAR:%.*]] = sub nuw nsw i32 -42, [[X:%.*]]
; CHECK-NEXT: [[BO:%.*]] = insertelement <4 x i32> undef, i32 [[BO_SCALAR]], i64 1
; CHECK-NEXT: ret <4 x i32> [[BO]]
;
%ins = insertelement <4 x i32> undef, i32 %x, i32 1
@ -52,8 +52,8 @@ define <4 x i32> @sub_constant_op0(i32 %x) {
define <4 x i32> @sub_constant_op0_not_undef_lane(i32 %x) {
; CHECK-LABEL: @sub_constant_op0_not_undef_lane(
; CHECK-NEXT: [[INS:%.*]] = insertelement <4 x i32> undef, i32 [[X:%.*]], i32 1
; CHECK-NEXT: [[BO:%.*]] = sub nuw <4 x i32> <i32 1, i32 42, i32 42, i32 -42>, [[INS]]
; CHECK-NEXT: [[BO_SCALAR:%.*]] = sub nuw i32 42, [[X:%.*]]
; CHECK-NEXT: [[BO:%.*]] = insertelement <4 x i32> undef, i32 [[BO_SCALAR]], i64 1
; CHECK-NEXT: ret <4 x i32> [[BO]]
;
%ins = insertelement <4 x i32> undef, i32 %x, i32 1
@ -63,8 +63,8 @@ define <4 x i32> @sub_constant_op0_not_undef_lane(i32 %x) {
define <8 x i16> @sub_constant_op1(i16 %x) {
; CHECK-LABEL: @sub_constant_op1(
; CHECK-NEXT: [[INS:%.*]] = insertelement <8 x i16> undef, i16 [[X:%.*]], i32 0
; CHECK-NEXT: [[BO:%.*]] = sub nuw <8 x i16> [[INS]], <i16 42, i16 undef, i16 undef, i16 undef, i16 undef, i16 undef, i16 undef, i16 undef>
; CHECK-NEXT: [[BO_SCALAR:%.*]] = sub nuw i16 [[X:%.*]], 42
; CHECK-NEXT: [[BO:%.*]] = insertelement <8 x i16> undef, i16 [[BO_SCALAR]], i64 0
; CHECK-NEXT: ret <8 x i16> [[BO]]
;
%ins = insertelement <8 x i16> undef, i16 %x, i32 0
@ -74,8 +74,8 @@ define <8 x i16> @sub_constant_op1(i16 %x) {
define <8 x i16> @sub_constant_op1_not_undef_lane(i16 %x) {
; CHECK-LABEL: @sub_constant_op1_not_undef_lane(
; CHECK-NEXT: [[INS:%.*]] = insertelement <8 x i16> undef, i16 [[X:%.*]], i32 0
; CHECK-NEXT: [[BO:%.*]] = sub nuw <8 x i16> [[INS]], <i16 42, i16 -42, i16 0, i16 1, i16 -2, i16 3, i16 -4, i16 5>
; CHECK-NEXT: [[BO_SCALAR:%.*]] = sub nuw i16 [[X:%.*]], 42
; CHECK-NEXT: [[BO:%.*]] = insertelement <8 x i16> undef, i16 [[BO_SCALAR]], i64 0
; CHECK-NEXT: ret <8 x i16> [[BO]]
;
%ins = insertelement <8 x i16> undef, i16 %x, i32 0
@ -85,8 +85,8 @@ define <8 x i16> @sub_constant_op1_not_undef_lane(i16 %x) {
define <16 x i8> @mul_constant(i8 %x) {
; CHECK-LABEL: @mul_constant(
; CHECK-NEXT: [[INS:%.*]] = insertelement <16 x i8> undef, i8 [[X:%.*]], i32 2
; CHECK-NEXT: [[BO:%.*]] = mul <16 x i8> [[INS]], <i8 undef, i8 undef, i8 -42, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef>
; CHECK-NEXT: [[BO_SCALAR:%.*]] = mul i8 [[X:%.*]], -42
; CHECK-NEXT: [[BO:%.*]] = insertelement <16 x i8> <i8 undef, i8 undef, i8 0, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef>, i8 [[BO_SCALAR]], i64 2
; CHECK-NEXT: ret <16 x i8> [[BO]]
;
%ins = insertelement <16 x i8> undef, i8 %x, i32 2
@ -96,8 +96,8 @@ define <16 x i8> @mul_constant(i8 %x) {
define <3 x i64> @mul_constant_not_undef_lane(i64 %x) {
; CHECK-LABEL: @mul_constant_not_undef_lane(
; CHECK-NEXT: [[INS:%.*]] = insertelement <3 x i64> undef, i64 [[X:%.*]], i32 2
; CHECK-NEXT: [[BO:%.*]] = mul <3 x i64> [[INS]], <i64 42, i64 undef, i64 -42>
; CHECK-NEXT: [[BO_SCALAR:%.*]] = mul i64 [[X:%.*]], -42
; CHECK-NEXT: [[BO:%.*]] = insertelement <3 x i64> <i64 0, i64 undef, i64 0>, i64 [[BO_SCALAR]], i64 2
; CHECK-NEXT: ret <3 x i64> [[BO]]
;
%ins = insertelement <3 x i64> undef, i64 %x, i32 2
@ -106,12 +106,20 @@ define <3 x i64> @mul_constant_not_undef_lane(i64 %x) {
}
define <16 x i8> @mul_constant_multiuse(i8 %a0, <16 x i8> %a1) {
; CHECK-LABEL: @mul_constant_multiuse(
; CHECK-NEXT: [[INS:%.*]] = insertelement <16 x i8> <i8 undef, i8 1, i8 2, i8 3, i8 4, i8 5, i8 6, i8 7, i8 8, i8 9, i8 10, i8 11, i8 12, i8 13, i8 14, i8 15>, i8 [[A0:%.*]], i32 0
; CHECK-NEXT: [[MUL:%.*]] = mul <16 x i8> [[INS]], <i8 3, i8 7, i8 9, i8 11, i8 13, i8 15, i8 17, i8 19, i8 21, i8 23, i8 25, i8 27, i8 29, i8 31, i8 33, i8 35>
; CHECK-NEXT: [[AND:%.*]] = and <16 x i8> [[INS]], [[A1:%.*]]
; CHECK-NEXT: [[XOR:%.*]] = xor <16 x i8> [[AND]], [[MUL]]
; CHECK-NEXT: ret <16 x i8> [[XOR]]
; SSE-LABEL: @mul_constant_multiuse(
; SSE-NEXT: [[INS:%.*]] = insertelement <16 x i8> <i8 undef, i8 1, i8 2, i8 3, i8 4, i8 5, i8 6, i8 7, i8 8, i8 9, i8 10, i8 11, i8 12, i8 13, i8 14, i8 15>, i8 [[A0:%.*]], i32 0
; SSE-NEXT: [[MUL:%.*]] = mul <16 x i8> [[INS]], <i8 3, i8 7, i8 9, i8 11, i8 13, i8 15, i8 17, i8 19, i8 21, i8 23, i8 25, i8 27, i8 29, i8 31, i8 33, i8 35>
; SSE-NEXT: [[AND:%.*]] = and <16 x i8> [[INS]], [[A1:%.*]]
; SSE-NEXT: [[XOR:%.*]] = xor <16 x i8> [[AND]], [[MUL]]
; SSE-NEXT: ret <16 x i8> [[XOR]]
;
; AVX-LABEL: @mul_constant_multiuse(
; AVX-NEXT: [[INS:%.*]] = insertelement <16 x i8> <i8 undef, i8 1, i8 2, i8 3, i8 4, i8 5, i8 6, i8 7, i8 8, i8 9, i8 10, i8 11, i8 12, i8 13, i8 14, i8 15>, i8 [[A0:%.*]], i32 0
; AVX-NEXT: [[MUL_SCALAR:%.*]] = mul i8 [[A0]], 3
; AVX-NEXT: [[MUL:%.*]] = insertelement <16 x i8> <i8 undef, i8 7, i8 18, i8 33, i8 52, i8 75, i8 102, i8 -123, i8 -88, i8 -49, i8 -6, i8 41, i8 92, i8 -109, i8 -50, i8 13>, i8 [[MUL_SCALAR]], i64 0
; AVX-NEXT: [[AND:%.*]] = and <16 x i8> [[INS]], [[A1:%.*]]
; AVX-NEXT: [[XOR:%.*]] = xor <16 x i8> [[AND]], [[MUL]]
; AVX-NEXT: ret <16 x i8> [[XOR]]
;
%ins = insertelement <16 x i8> <i8 undef, i8 1, i8 2, i8 3, i8 4, i8 5, i8 6, i8 7, i8 8, i8 9, i8 10, i8 11, i8 12, i8 13, i8 14, i8 15>, i8 %a0, i32 0
%mul = mul <16 x i8> %ins, <i8 3, i8 7, i8 9, i8 11, i8 13, i8 15, i8 17, i8 19, i8 21, i8 23, i8 25, i8 27, i8 29, i8 31, i8 33, i8 35>
@ -122,8 +130,8 @@ define <16 x i8> @mul_constant_multiuse(i8 %a0, <16 x i8> %a1) {
define <2 x i64> @shl_constant_op0(i64 %x) {
; CHECK-LABEL: @shl_constant_op0(
; CHECK-NEXT: [[INS:%.*]] = insertelement <2 x i64> undef, i64 [[X:%.*]], i32 1
; CHECK-NEXT: [[BO:%.*]] = shl <2 x i64> <i64 undef, i64 2>, [[INS]]
; CHECK-NEXT: [[BO_SCALAR:%.*]] = shl i64 2, [[X:%.*]]
; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x i64> undef, i64 [[BO_SCALAR]], i64 1
; CHECK-NEXT: ret <2 x i64> [[BO]]
;
%ins = insertelement <2 x i64> undef, i64 %x, i32 1
@ -133,8 +141,8 @@ define <2 x i64> @shl_constant_op0(i64 %x) {
define <2 x i64> @shl_constant_op0_not_undef_lane(i64 %x) {
; CHECK-LABEL: @shl_constant_op0_not_undef_lane(
; CHECK-NEXT: [[INS:%.*]] = insertelement <2 x i64> undef, i64 [[X:%.*]], i32 1
; CHECK-NEXT: [[BO:%.*]] = shl <2 x i64> <i64 5, i64 2>, [[INS]]
; CHECK-NEXT: [[BO_SCALAR:%.*]] = shl i64 2, [[X:%.*]]
; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x i64> undef, i64 [[BO_SCALAR]], i64 1
; CHECK-NEXT: ret <2 x i64> [[BO]]
;
%ins = insertelement <2 x i64> undef, i64 %x, i32 1
@ -156,12 +164,20 @@ define <2 x i64> @shl_constant_op0_load(i64* %p) {
}
define <4 x i32> @shl_constant_op0_multiuse(i32 %a0, <4 x i32> %a1) {
; CHECK-LABEL: @shl_constant_op0_multiuse(
; CHECK-NEXT: [[INS:%.*]] = insertelement <4 x i32> <i32 undef, i32 1, i32 2, i32 3>, i32 [[A0:%.*]], i32 0
; CHECK-NEXT: [[MUL:%.*]] = shl <4 x i32> [[INS]], <i32 3, i32 4, i32 5, i32 6>
; CHECK-NEXT: [[AND:%.*]] = and <4 x i32> [[INS]], [[A1:%.*]]
; CHECK-NEXT: [[XOR:%.*]] = xor <4 x i32> [[AND]], [[MUL]]
; CHECK-NEXT: ret <4 x i32> [[XOR]]
; SSE-LABEL: @shl_constant_op0_multiuse(
; SSE-NEXT: [[INS:%.*]] = insertelement <4 x i32> <i32 undef, i32 1, i32 2, i32 3>, i32 [[A0:%.*]], i32 0
; SSE-NEXT: [[MUL_SCALAR:%.*]] = shl i32 [[A0]], 3
; SSE-NEXT: [[MUL:%.*]] = insertelement <4 x i32> <i32 0, i32 16, i32 64, i32 192>, i32 [[MUL_SCALAR]], i64 0
; SSE-NEXT: [[AND:%.*]] = and <4 x i32> [[INS]], [[A1:%.*]]
; SSE-NEXT: [[XOR:%.*]] = xor <4 x i32> [[AND]], [[MUL]]
; SSE-NEXT: ret <4 x i32> [[XOR]]
;
; AVX-LABEL: @shl_constant_op0_multiuse(
; AVX-NEXT: [[INS:%.*]] = insertelement <4 x i32> <i32 undef, i32 1, i32 2, i32 3>, i32 [[A0:%.*]], i32 0
; AVX-NEXT: [[MUL:%.*]] = shl <4 x i32> [[INS]], <i32 3, i32 4, i32 5, i32 6>
; AVX-NEXT: [[AND:%.*]] = and <4 x i32> [[INS]], [[A1:%.*]]
; AVX-NEXT: [[XOR:%.*]] = xor <4 x i32> [[AND]], [[MUL]]
; AVX-NEXT: ret <4 x i32> [[XOR]]
;
%ins = insertelement <4 x i32> <i32 undef, i32 1, i32 2, i32 3>, i32 %a0, i32 0
%mul = shl <4 x i32> %ins, <i32 3, i32 4, i32 5, i32 6>
@ -172,8 +188,8 @@ define <4 x i32> @shl_constant_op0_multiuse(i32 %a0, <4 x i32> %a1) {
define <2 x i64> @shl_constant_op1(i64 %x) {
; CHECK-LABEL: @shl_constant_op1(
; CHECK-NEXT: [[INS:%.*]] = insertelement <2 x i64> undef, i64 [[X:%.*]], i32 0
; CHECK-NEXT: [[BO:%.*]] = shl nuw <2 x i64> [[INS]], <i64 5, i64 undef>
; CHECK-NEXT: [[BO_SCALAR:%.*]] = shl nuw i64 [[X:%.*]], 5
; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x i64> <i64 0, i64 undef>, i64 [[BO_SCALAR]], i64 0
; CHECK-NEXT: ret <2 x i64> [[BO]]
;
%ins = insertelement <2 x i64> undef, i64 %x, i32 0
@ -183,8 +199,8 @@ define <2 x i64> @shl_constant_op1(i64 %x) {
define <2 x i64> @shl_constant_op1_not_undef_lane(i64 %x) {
; CHECK-LABEL: @shl_constant_op1_not_undef_lane(
; CHECK-NEXT: [[INS:%.*]] = insertelement <2 x i64> undef, i64 [[X:%.*]], i32 0
; CHECK-NEXT: [[BO:%.*]] = shl nuw <2 x i64> [[INS]], <i64 5, i64 2>
; CHECK-NEXT: [[BO_SCALAR:%.*]] = shl nuw i64 [[X:%.*]], 5
; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x i64> zeroinitializer, i64 [[BO_SCALAR]], i64 0
; CHECK-NEXT: ret <2 x i64> [[BO]]
;
%ins = insertelement <2 x i64> undef, i64 %x, i32 0
@ -207,8 +223,8 @@ define <2 x i64> @shl_constant_op1_load(i64* %p) {
define <2 x i64> @ashr_constant_op0(i64 %x) {
; CHECK-LABEL: @ashr_constant_op0(
; CHECK-NEXT: [[INS:%.*]] = insertelement <2 x i64> undef, i64 [[X:%.*]], i32 1
; CHECK-NEXT: [[BO:%.*]] = ashr exact <2 x i64> <i64 undef, i64 2>, [[INS]]
; CHECK-NEXT: [[BO_SCALAR:%.*]] = ashr exact i64 2, [[X:%.*]]
; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x i64> undef, i64 [[BO_SCALAR]], i64 1
; CHECK-NEXT: ret <2 x i64> [[BO]]
;
%ins = insertelement <2 x i64> undef, i64 %x, i32 1
@ -218,8 +234,8 @@ define <2 x i64> @ashr_constant_op0(i64 %x) {
define <2 x i64> @ashr_constant_op0_not_undef_lane(i64 %x) {
; CHECK-LABEL: @ashr_constant_op0_not_undef_lane(
; CHECK-NEXT: [[INS:%.*]] = insertelement <2 x i64> undef, i64 [[X:%.*]], i32 1
; CHECK-NEXT: [[BO:%.*]] = ashr exact <2 x i64> <i64 5, i64 2>, [[INS]]
; CHECK-NEXT: [[BO_SCALAR:%.*]] = ashr exact i64 2, [[X:%.*]]
; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x i64> undef, i64 [[BO_SCALAR]], i64 1
; CHECK-NEXT: ret <2 x i64> [[BO]]
;
%ins = insertelement <2 x i64> undef, i64 %x, i32 1
@ -229,8 +245,8 @@ define <2 x i64> @ashr_constant_op0_not_undef_lane(i64 %x) {
define <2 x i64> @ashr_constant_op1(i64 %x) {
; CHECK-LABEL: @ashr_constant_op1(
; CHECK-NEXT: [[INS:%.*]] = insertelement <2 x i64> undef, i64 [[X:%.*]], i32 0
; CHECK-NEXT: [[BO:%.*]] = ashr <2 x i64> [[INS]], <i64 5, i64 undef>
; CHECK-NEXT: [[BO_SCALAR:%.*]] = ashr i64 [[X:%.*]], 5
; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x i64> <i64 0, i64 undef>, i64 [[BO_SCALAR]], i64 0
; CHECK-NEXT: ret <2 x i64> [[BO]]
;
%ins = insertelement <2 x i64> undef, i64 %x, i32 0
@ -240,8 +256,8 @@ define <2 x i64> @ashr_constant_op1(i64 %x) {
define <2 x i64> @ashr_constant_op1_not_undef_lane(i64 %x) {
; CHECK-LABEL: @ashr_constant_op1_not_undef_lane(
; CHECK-NEXT: [[INS:%.*]] = insertelement <2 x i64> undef, i64 [[X:%.*]], i32 0
; CHECK-NEXT: [[BO:%.*]] = ashr <2 x i64> [[INS]], <i64 5, i64 2>
; CHECK-NEXT: [[BO_SCALAR:%.*]] = ashr i64 [[X:%.*]], 5
; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x i64> zeroinitializer, i64 [[BO_SCALAR]], i64 0
; CHECK-NEXT: ret <2 x i64> [[BO]]
;
%ins = insertelement <2 x i64> undef, i64 %x, i32 0
@ -251,8 +267,8 @@ define <2 x i64> @ashr_constant_op1_not_undef_lane(i64 %x) {
define <2 x i64> @lshr_constant_op0(i64 %x) {
; CHECK-LABEL: @lshr_constant_op0(
; CHECK-NEXT: [[INS:%.*]] = insertelement <2 x i64> undef, i64 [[X:%.*]], i32 0
; CHECK-NEXT: [[BO:%.*]] = lshr <2 x i64> <i64 5, i64 undef>, [[INS]]
; CHECK-NEXT: [[BO_SCALAR:%.*]] = lshr i64 5, [[X:%.*]]
; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x i64> undef, i64 [[BO_SCALAR]], i64 0
; CHECK-NEXT: ret <2 x i64> [[BO]]
;
%ins = insertelement <2 x i64> undef, i64 %x, i32 0
@ -262,8 +278,8 @@ define <2 x i64> @lshr_constant_op0(i64 %x) {
define <2 x i64> @lshr_constant_op0_not_undef_lane(i64 %x) {
; CHECK-LABEL: @lshr_constant_op0_not_undef_lane(
; CHECK-NEXT: [[INS:%.*]] = insertelement <2 x i64> undef, i64 [[X:%.*]], i32 0
; CHECK-NEXT: [[BO:%.*]] = lshr <2 x i64> <i64 5, i64 2>, [[INS]]
; CHECK-NEXT: [[BO_SCALAR:%.*]] = lshr i64 5, [[X:%.*]]
; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x i64> undef, i64 [[BO_SCALAR]], i64 0
; CHECK-NEXT: ret <2 x i64> [[BO]]
;
%ins = insertelement <2 x i64> undef, i64 %x, i32 0
@ -273,8 +289,8 @@ define <2 x i64> @lshr_constant_op0_not_undef_lane(i64 %x) {
define <2 x i64> @lshr_constant_op1(i64 %x) {
; CHECK-LABEL: @lshr_constant_op1(
; CHECK-NEXT: [[INS:%.*]] = insertelement <2 x i64> undef, i64 [[X:%.*]], i32 1
; CHECK-NEXT: [[BO:%.*]] = lshr exact <2 x i64> [[INS]], <i64 undef, i64 2>
; CHECK-NEXT: [[BO_SCALAR:%.*]] = lshr exact i64 [[X:%.*]], 2
; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x i64> <i64 undef, i64 0>, i64 [[BO_SCALAR]], i64 1
; CHECK-NEXT: ret <2 x i64> [[BO]]
;
%ins = insertelement <2 x i64> undef, i64 %x, i32 1
@ -284,8 +300,8 @@ define <2 x i64> @lshr_constant_op1(i64 %x) {
define <2 x i64> @lshr_constant_op1_not_undef_lane(i64 %x) {
; CHECK-LABEL: @lshr_constant_op1_not_undef_lane(
; CHECK-NEXT: [[INS:%.*]] = insertelement <2 x i64> undef, i64 [[X:%.*]], i32 1
; CHECK-NEXT: [[BO:%.*]] = lshr exact <2 x i64> [[INS]], <i64 5, i64 2>
; CHECK-NEXT: [[BO_SCALAR:%.*]] = lshr exact i64 [[X:%.*]], 2
; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x i64> zeroinitializer, i64 [[BO_SCALAR]], i64 1
; CHECK-NEXT: ret <2 x i64> [[BO]]
;
%ins = insertelement <2 x i64> undef, i64 %x, i32 1
@ -295,8 +311,8 @@ define <2 x i64> @lshr_constant_op1_not_undef_lane(i64 %x) {
define <2 x i64> @urem_constant_op0(i64 %x) {
; CHECK-LABEL: @urem_constant_op0(
; CHECK-NEXT: [[INS:%.*]] = insertelement <2 x i64> undef, i64 [[X:%.*]], i32 0
; CHECK-NEXT: [[BO:%.*]] = urem <2 x i64> <i64 5, i64 undef>, [[INS]]
; CHECK-NEXT: [[BO_SCALAR:%.*]] = urem i64 5, [[X:%.*]]
; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x i64> undef, i64 [[BO_SCALAR]], i64 0
; CHECK-NEXT: ret <2 x i64> [[BO]]
;
%ins = insertelement <2 x i64> undef, i64 %x, i32 0
@ -306,8 +322,8 @@ define <2 x i64> @urem_constant_op0(i64 %x) {
define <2 x i64> @urem_constant_op0_not_undef_lane(i64 %x) {
; CHECK-LABEL: @urem_constant_op0_not_undef_lane(
; CHECK-NEXT: [[INS:%.*]] = insertelement <2 x i64> undef, i64 [[X:%.*]], i32 0
; CHECK-NEXT: [[BO:%.*]] = urem <2 x i64> <i64 5, i64 2>, [[INS]]
; CHECK-NEXT: [[BO_SCALAR:%.*]] = urem i64 5, [[X:%.*]]
; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x i64> undef, i64 [[BO_SCALAR]], i64 0
; CHECK-NEXT: ret <2 x i64> [[BO]]
;
%ins = insertelement <2 x i64> undef, i64 %x, i32 0
@ -317,8 +333,8 @@ define <2 x i64> @urem_constant_op0_not_undef_lane(i64 %x) {
define <2 x i64> @urem_constant_op1(i64 %x) {
; CHECK-LABEL: @urem_constant_op1(
; CHECK-NEXT: [[INS:%.*]] = insertelement <2 x i64> undef, i64 [[X:%.*]], i32 1
; CHECK-NEXT: [[BO:%.*]] = urem <2 x i64> [[INS]], <i64 undef, i64 2>
; CHECK-NEXT: [[BO_SCALAR:%.*]] = urem i64 [[X:%.*]], 2
; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x i64> <i64 undef, i64 0>, i64 [[BO_SCALAR]], i64 1
; CHECK-NEXT: ret <2 x i64> [[BO]]
;
%ins = insertelement <2 x i64> undef, i64 %x, i32 1
@ -328,8 +344,8 @@ define <2 x i64> @urem_constant_op1(i64 %x) {
define <2 x i64> @urem_constant_op1_not_undef_lane(i64 %x) {
; CHECK-LABEL: @urem_constant_op1_not_undef_lane(
; CHECK-NEXT: [[INS:%.*]] = insertelement <2 x i64> undef, i64 [[X:%.*]], i32 1
; CHECK-NEXT: [[BO:%.*]] = urem <2 x i64> [[INS]], <i64 5, i64 2>
; CHECK-NEXT: [[BO_SCALAR:%.*]] = urem i64 [[X:%.*]], 2
; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x i64> zeroinitializer, i64 [[BO_SCALAR]], i64 1
; CHECK-NEXT: ret <2 x i64> [[BO]]
;
%ins = insertelement <2 x i64> undef, i64 %x, i32 1
@ -339,8 +355,8 @@ define <2 x i64> @urem_constant_op1_not_undef_lane(i64 %x) {
define <2 x i64> @srem_constant_op0(i64 %x) {
; CHECK-LABEL: @srem_constant_op0(
; CHECK-NEXT: [[INS:%.*]] = insertelement <2 x i64> undef, i64 [[X:%.*]], i32 0
; CHECK-NEXT: [[BO:%.*]] = srem <2 x i64> <i64 5, i64 undef>, [[INS]]
; CHECK-NEXT: [[BO_SCALAR:%.*]] = srem i64 5, [[X:%.*]]
; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x i64> undef, i64 [[BO_SCALAR]], i64 0
; CHECK-NEXT: ret <2 x i64> [[BO]]
;
%ins = insertelement <2 x i64> undef, i64 %x, i32 0
@ -350,8 +366,8 @@ define <2 x i64> @srem_constant_op0(i64 %x) {
define <2 x i64> @srem_constant_op0_not_undef_lane(i64 %x) {
; CHECK-LABEL: @srem_constant_op0_not_undef_lane(
; CHECK-NEXT: [[INS:%.*]] = insertelement <2 x i64> undef, i64 [[X:%.*]], i32 0
; CHECK-NEXT: [[BO:%.*]] = srem <2 x i64> <i64 5, i64 2>, [[INS]]
; CHECK-NEXT: [[BO_SCALAR:%.*]] = srem i64 5, [[X:%.*]]
; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x i64> undef, i64 [[BO_SCALAR]], i64 0
; CHECK-NEXT: ret <2 x i64> [[BO]]
;
%ins = insertelement <2 x i64> undef, i64 %x, i32 0
@ -361,8 +377,8 @@ define <2 x i64> @srem_constant_op0_not_undef_lane(i64 %x) {
define <2 x i64> @srem_constant_op1(i64 %x) {
; CHECK-LABEL: @srem_constant_op1(
; CHECK-NEXT: [[INS:%.*]] = insertelement <2 x i64> undef, i64 [[X:%.*]], i32 1
; CHECK-NEXT: [[BO:%.*]] = srem <2 x i64> [[INS]], <i64 undef, i64 2>
; CHECK-NEXT: [[BO_SCALAR:%.*]] = srem i64 [[X:%.*]], 2
; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x i64> <i64 undef, i64 0>, i64 [[BO_SCALAR]], i64 1
; CHECK-NEXT: ret <2 x i64> [[BO]]
;
%ins = insertelement <2 x i64> undef, i64 %x, i32 1
@ -372,8 +388,8 @@ define <2 x i64> @srem_constant_op1(i64 %x) {
define <2 x i64> @srem_constant_op1_not_undef_lane(i64 %x) {
; CHECK-LABEL: @srem_constant_op1_not_undef_lane(
; CHECK-NEXT: [[INS:%.*]] = insertelement <2 x i64> undef, i64 [[X:%.*]], i32 1
; CHECK-NEXT: [[BO:%.*]] = srem <2 x i64> [[INS]], <i64 5, i64 2>
; CHECK-NEXT: [[BO_SCALAR:%.*]] = srem i64 [[X:%.*]], 2
; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x i64> zeroinitializer, i64 [[BO_SCALAR]], i64 1
; CHECK-NEXT: ret <2 x i64> [[BO]]
;
%ins = insertelement <2 x i64> undef, i64 %x, i32 1
@ -383,8 +399,8 @@ define <2 x i64> @srem_constant_op1_not_undef_lane(i64 %x) {
define <2 x i64> @udiv_constant_op0(i64 %x) {
; CHECK-LABEL: @udiv_constant_op0(
; CHECK-NEXT: [[INS:%.*]] = insertelement <2 x i64> undef, i64 [[X:%.*]], i32 0
; CHECK-NEXT: [[BO:%.*]] = udiv exact <2 x i64> <i64 5, i64 undef>, [[INS]]
; CHECK-NEXT: [[BO_SCALAR:%.*]] = udiv exact i64 5, [[X:%.*]]
; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x i64> undef, i64 [[BO_SCALAR]], i64 0
; CHECK-NEXT: ret <2 x i64> [[BO]]
;
%ins = insertelement <2 x i64> undef, i64 %x, i32 0
@ -394,8 +410,8 @@ define <2 x i64> @udiv_constant_op0(i64 %x) {
define <2 x i64> @udiv_constant_op0_not_undef_lane(i64 %x) {
; CHECK-LABEL: @udiv_constant_op0_not_undef_lane(
; CHECK-NEXT: [[INS:%.*]] = insertelement <2 x i64> undef, i64 [[X:%.*]], i32 0
; CHECK-NEXT: [[BO:%.*]] = udiv exact <2 x i64> <i64 5, i64 2>, [[INS]]
; CHECK-NEXT: [[BO_SCALAR:%.*]] = udiv exact i64 5, [[X:%.*]]
; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x i64> undef, i64 [[BO_SCALAR]], i64 0
; CHECK-NEXT: ret <2 x i64> [[BO]]
;
%ins = insertelement <2 x i64> undef, i64 %x, i32 0
@ -405,8 +421,8 @@ define <2 x i64> @udiv_constant_op0_not_undef_lane(i64 %x) {
define <2 x i64> @udiv_constant_op1(i64 %x) {
; CHECK-LABEL: @udiv_constant_op1(
; CHECK-NEXT: [[INS:%.*]] = insertelement <2 x i64> undef, i64 [[X:%.*]], i32 1
; CHECK-NEXT: [[BO:%.*]] = udiv <2 x i64> [[INS]], <i64 undef, i64 2>
; CHECK-NEXT: [[BO_SCALAR:%.*]] = udiv i64 [[X:%.*]], 2
; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x i64> <i64 undef, i64 0>, i64 [[BO_SCALAR]], i64 1
; CHECK-NEXT: ret <2 x i64> [[BO]]
;
%ins = insertelement <2 x i64> undef, i64 %x, i32 1
@ -416,8 +432,8 @@ define <2 x i64> @udiv_constant_op1(i64 %x) {
define <2 x i64> @udiv_constant_op1_not_undef_lane(i64 %x) {
; CHECK-LABEL: @udiv_constant_op1_not_undef_lane(
; CHECK-NEXT: [[INS:%.*]] = insertelement <2 x i64> undef, i64 [[X:%.*]], i32 1
; CHECK-NEXT: [[BO:%.*]] = udiv <2 x i64> [[INS]], <i64 5, i64 2>
; CHECK-NEXT: [[BO_SCALAR:%.*]] = udiv i64 [[X:%.*]], 2
; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x i64> zeroinitializer, i64 [[BO_SCALAR]], i64 1
; CHECK-NEXT: ret <2 x i64> [[BO]]
;
%ins = insertelement <2 x i64> undef, i64 %x, i32 1
@ -427,8 +443,8 @@ define <2 x i64> @udiv_constant_op1_not_undef_lane(i64 %x) {
define <2 x i64> @sdiv_constant_op0(i64 %x) {
; CHECK-LABEL: @sdiv_constant_op0(
; CHECK-NEXT: [[INS:%.*]] = insertelement <2 x i64> undef, i64 [[X:%.*]], i32 0
; CHECK-NEXT: [[BO:%.*]] = sdiv <2 x i64> <i64 5, i64 undef>, [[INS]]
; CHECK-NEXT: [[BO_SCALAR:%.*]] = sdiv i64 5, [[X:%.*]]
; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x i64> undef, i64 [[BO_SCALAR]], i64 0
; CHECK-NEXT: ret <2 x i64> [[BO]]
;
%ins = insertelement <2 x i64> undef, i64 %x, i32 0
@ -438,8 +454,8 @@ define <2 x i64> @sdiv_constant_op0(i64 %x) {
define <2 x i64> @sdiv_constant_op0_not_undef_lane(i64 %x) {
; CHECK-LABEL: @sdiv_constant_op0_not_undef_lane(
; CHECK-NEXT: [[INS:%.*]] = insertelement <2 x i64> undef, i64 [[X:%.*]], i32 0
; CHECK-NEXT: [[BO:%.*]] = sdiv <2 x i64> <i64 5, i64 2>, [[INS]]
; CHECK-NEXT: [[BO_SCALAR:%.*]] = sdiv i64 5, [[X:%.*]]
; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x i64> undef, i64 [[BO_SCALAR]], i64 0
; CHECK-NEXT: ret <2 x i64> [[BO]]
;
%ins = insertelement <2 x i64> undef, i64 %x, i32 0
@ -449,8 +465,8 @@ define <2 x i64> @sdiv_constant_op0_not_undef_lane(i64 %x) {
define <2 x i64> @sdiv_constant_op1(i64 %x) {
; CHECK-LABEL: @sdiv_constant_op1(
; CHECK-NEXT: [[INS:%.*]] = insertelement <2 x i64> undef, i64 [[X:%.*]], i32 1
; CHECK-NEXT: [[BO:%.*]] = sdiv exact <2 x i64> [[INS]], <i64 undef, i64 2>
; CHECK-NEXT: [[BO_SCALAR:%.*]] = sdiv exact i64 [[X:%.*]], 2
; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x i64> <i64 undef, i64 0>, i64 [[BO_SCALAR]], i64 1
; CHECK-NEXT: ret <2 x i64> [[BO]]
;
%ins = insertelement <2 x i64> undef, i64 %x, i32 1
@ -460,8 +476,8 @@ define <2 x i64> @sdiv_constant_op1(i64 %x) {
define <2 x i64> @sdiv_constant_op1_not_undef_lane(i64 %x) {
; CHECK-LABEL: @sdiv_constant_op1_not_undef_lane(
; CHECK-NEXT: [[INS:%.*]] = insertelement <2 x i64> undef, i64 [[X:%.*]], i32 1
; CHECK-NEXT: [[BO:%.*]] = sdiv exact <2 x i64> [[INS]], <i64 5, i64 2>
; CHECK-NEXT: [[BO_SCALAR:%.*]] = sdiv exact i64 [[X:%.*]], 2
; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x i64> zeroinitializer, i64 [[BO_SCALAR]], i64 1
; CHECK-NEXT: ret <2 x i64> [[BO]]
;
%ins = insertelement <2 x i64> undef, i64 %x, i32 1
@ -471,8 +487,8 @@ define <2 x i64> @sdiv_constant_op1_not_undef_lane(i64 %x) {
define <2 x i64> @and_constant(i64 %x) {
; CHECK-LABEL: @and_constant(
; CHECK-NEXT: [[INS:%.*]] = insertelement <2 x i64> undef, i64 [[X:%.*]], i32 0
; CHECK-NEXT: [[BO:%.*]] = and <2 x i64> [[INS]], <i64 42, i64 undef>
; CHECK-NEXT: [[BO_SCALAR:%.*]] = and i64 [[X:%.*]], 42
; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x i64> <i64 0, i64 undef>, i64 [[BO_SCALAR]], i64 0
; CHECK-NEXT: ret <2 x i64> [[BO]]
;
%ins = insertelement <2 x i64> undef, i64 %x, i32 0
@ -482,8 +498,8 @@ define <2 x i64> @and_constant(i64 %x) {
define <2 x i64> @and_constant_not_undef_lane(i64 %x) {
; CHECK-LABEL: @and_constant_not_undef_lane(
; CHECK-NEXT: [[INS:%.*]] = insertelement <2 x i64> undef, i64 [[X:%.*]], i32 0
; CHECK-NEXT: [[BO:%.*]] = and <2 x i64> [[INS]], <i64 42, i64 -42>
; CHECK-NEXT: [[BO_SCALAR:%.*]] = and i64 [[X:%.*]], 42
; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x i64> zeroinitializer, i64 [[BO_SCALAR]], i64 0
; CHECK-NEXT: ret <2 x i64> [[BO]]
;
%ins = insertelement <2 x i64> undef, i64 %x, i32 0
@ -493,8 +509,8 @@ define <2 x i64> @and_constant_not_undef_lane(i64 %x) {
define <2 x i64> @or_constant(i64 %x) {
; CHECK-LABEL: @or_constant(
; CHECK-NEXT: [[INS:%.*]] = insertelement <2 x i64> undef, i64 [[X:%.*]], i32 1
; CHECK-NEXT: [[BO:%.*]] = or <2 x i64> [[INS]], <i64 undef, i64 -42>
; CHECK-NEXT: [[BO_SCALAR:%.*]] = or i64 [[X:%.*]], -42
; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x i64> <i64 undef, i64 -1>, i64 [[BO_SCALAR]], i64 1
; CHECK-NEXT: ret <2 x i64> [[BO]]
;
%ins = insertelement <2 x i64> undef, i64 %x, i32 1
@ -504,8 +520,8 @@ define <2 x i64> @or_constant(i64 %x) {
define <2 x i64> @or_constant_not_undef_lane(i64 %x) {
; CHECK-LABEL: @or_constant_not_undef_lane(
; CHECK-NEXT: [[INS:%.*]] = insertelement <2 x i64> undef, i64 [[X:%.*]], i32 1
; CHECK-NEXT: [[BO:%.*]] = or <2 x i64> [[INS]], <i64 42, i64 -42>
; CHECK-NEXT: [[BO_SCALAR:%.*]] = or i64 [[X:%.*]], -42
; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x i64> <i64 -1, i64 -1>, i64 [[BO_SCALAR]], i64 1
; CHECK-NEXT: ret <2 x i64> [[BO]]
;
%ins = insertelement <2 x i64> undef, i64 %x, i32 1
@ -515,8 +531,8 @@ define <2 x i64> @or_constant_not_undef_lane(i64 %x) {
define <2 x i64> @xor_constant(i64 %x) {
; CHECK-LABEL: @xor_constant(
; CHECK-NEXT: [[INS:%.*]] = insertelement <2 x i64> undef, i64 [[X:%.*]], i32 0
; CHECK-NEXT: [[BO:%.*]] = xor <2 x i64> [[INS]], <i64 42, i64 undef>
; CHECK-NEXT: [[BO_SCALAR:%.*]] = xor i64 [[X:%.*]], 42
; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x i64> <i64 undef, i64 0>, i64 [[BO_SCALAR]], i64 0
; CHECK-NEXT: ret <2 x i64> [[BO]]
;
%ins = insertelement <2 x i64> undef, i64 %x, i32 0
@ -526,8 +542,8 @@ define <2 x i64> @xor_constant(i64 %x) {
define <2 x i64> @xor_constant_not_undef_lane(i64 %x) {
; CHECK-LABEL: @xor_constant_not_undef_lane(
; CHECK-NEXT: [[INS:%.*]] = insertelement <2 x i64> undef, i64 [[X:%.*]], i32 0
; CHECK-NEXT: [[BO:%.*]] = xor <2 x i64> [[INS]], <i64 42, i64 -42>
; CHECK-NEXT: [[BO_SCALAR:%.*]] = xor i64 [[X:%.*]], 42
; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x i64> undef, i64 [[BO_SCALAR]], i64 0
; CHECK-NEXT: ret <2 x i64> [[BO]]
;
%ins = insertelement <2 x i64> undef, i64 %x, i32 0
@ -537,8 +553,8 @@ define <2 x i64> @xor_constant_not_undef_lane(i64 %x) {
define <2 x double> @fadd_constant(double %x) {
; CHECK-LABEL: @fadd_constant(
; CHECK-NEXT: [[INS:%.*]] = insertelement <2 x double> undef, double [[X:%.*]], i32 0
; CHECK-NEXT: [[BO:%.*]] = fadd <2 x double> [[INS]], <double 4.200000e+01, double undef>
; CHECK-NEXT: [[BO_SCALAR:%.*]] = fadd double [[X:%.*]], 4.200000e+01
; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x double> <double 0x7FF8000000000000, double undef>, double [[BO_SCALAR]], i64 0
; CHECK-NEXT: ret <2 x double> [[BO]]
;
%ins = insertelement <2 x double> undef, double %x, i32 0
@ -548,8 +564,8 @@ define <2 x double> @fadd_constant(double %x) {
define <2 x double> @fadd_constant_not_undef_lane(double %x) {
; CHECK-LABEL: @fadd_constant_not_undef_lane(
; CHECK-NEXT: [[INS:%.*]] = insertelement <2 x double> undef, double [[X:%.*]], i32 1
; CHECK-NEXT: [[BO:%.*]] = fadd <2 x double> [[INS]], <double 4.200000e+01, double -4.200000e+01>
; CHECK-NEXT: [[BO_SCALAR:%.*]] = fadd double [[X:%.*]], -4.200000e+01
; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x double> <double 0x7FF8000000000000, double 0x7FF8000000000000>, double [[BO_SCALAR]], i64 1
; CHECK-NEXT: ret <2 x double> [[BO]]
;
%ins = insertelement <2 x double> undef, double %x, i32 1
@ -559,8 +575,8 @@ define <2 x double> @fadd_constant_not_undef_lane(double %x) {
define <2 x double> @fsub_constant_op0(double %x) {
; CHECK-LABEL: @fsub_constant_op0(
; CHECK-NEXT: [[INS:%.*]] = insertelement <2 x double> undef, double [[X:%.*]], i32 0
; CHECK-NEXT: [[BO:%.*]] = fsub fast <2 x double> <double 4.200000e+01, double undef>, [[INS]]
; CHECK-NEXT: [[BO_SCALAR:%.*]] = fsub fast double 4.200000e+01, [[X:%.*]]
; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x double> <double 0x7FF8000000000000, double undef>, double [[BO_SCALAR]], i64 0
; CHECK-NEXT: ret <2 x double> [[BO]]
;
%ins = insertelement <2 x double> undef, double %x, i32 0
@ -570,8 +586,8 @@ define <2 x double> @fsub_constant_op0(double %x) {
define <2 x double> @fsub_constant_op0_not_undef_lane(double %x) {
; CHECK-LABEL: @fsub_constant_op0_not_undef_lane(
; CHECK-NEXT: [[INS:%.*]] = insertelement <2 x double> undef, double [[X:%.*]], i32 1
; CHECK-NEXT: [[BO:%.*]] = fsub nsz <2 x double> <double 4.200000e+01, double -4.200000e+01>, [[INS]]
; CHECK-NEXT: [[BO_SCALAR:%.*]] = fsub nsz double -4.200000e+01, [[X:%.*]]
; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x double> <double 0x7FF8000000000000, double 0x7FF8000000000000>, double [[BO_SCALAR]], i64 1
; CHECK-NEXT: ret <2 x double> [[BO]]
;
%ins = insertelement <2 x double> undef, double %x, i32 1
@ -581,8 +597,8 @@ define <2 x double> @fsub_constant_op0_not_undef_lane(double %x) {
define <2 x double> @fsub_constant_op1(double %x) {
; CHECK-LABEL: @fsub_constant_op1(
; CHECK-NEXT: [[INS:%.*]] = insertelement <2 x double> undef, double [[X:%.*]], i32 1
; CHECK-NEXT: [[BO:%.*]] = fsub <2 x double> [[INS]], <double undef, double 4.200000e+01>
; CHECK-NEXT: [[BO_SCALAR:%.*]] = fsub double [[X:%.*]], 4.200000e+01
; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x double> <double undef, double 0x7FF8000000000000>, double [[BO_SCALAR]], i64 1
; CHECK-NEXT: ret <2 x double> [[BO]]
;
%ins = insertelement <2 x double> undef, double %x, i32 1
@ -592,8 +608,8 @@ define <2 x double> @fsub_constant_op1(double %x) {
define <2 x double> @fsub_constant_op1_not_undef_lane(double %x) {
; CHECK-LABEL: @fsub_constant_op1_not_undef_lane(
; CHECK-NEXT: [[INS:%.*]] = insertelement <2 x double> undef, double [[X:%.*]], i32 0
; CHECK-NEXT: [[BO:%.*]] = fsub <2 x double> [[INS]], <double 4.200000e+01, double -4.200000e+01>
; CHECK-NEXT: [[BO_SCALAR:%.*]] = fsub double [[X:%.*]], 4.200000e+01
; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x double> <double 0x7FF8000000000000, double 0x7FF8000000000000>, double [[BO_SCALAR]], i64 0
; CHECK-NEXT: ret <2 x double> [[BO]]
;
%ins = insertelement <2 x double> undef, double %x, i32 0
@ -603,8 +619,8 @@ define <2 x double> @fsub_constant_op1_not_undef_lane(double %x) {
define <2 x double> @fmul_constant(double %x) {
; CHECK-LABEL: @fmul_constant(
; CHECK-NEXT: [[INS:%.*]] = insertelement <2 x double> undef, double [[X:%.*]], i32 0
; CHECK-NEXT: [[BO:%.*]] = fmul reassoc <2 x double> [[INS]], <double 4.200000e+01, double undef>
; CHECK-NEXT: [[BO_SCALAR:%.*]] = fmul reassoc double [[X:%.*]], 4.200000e+01
; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x double> <double 0x7FF8000000000000, double undef>, double [[BO_SCALAR]], i64 0
; CHECK-NEXT: ret <2 x double> [[BO]]
;
%ins = insertelement <2 x double> undef, double %x, i32 0
@ -614,8 +630,8 @@ define <2 x double> @fmul_constant(double %x) {
define <2 x double> @fmul_constant_not_undef_lane(double %x) {
; CHECK-LABEL: @fmul_constant_not_undef_lane(
; CHECK-NEXT: [[INS:%.*]] = insertelement <2 x double> undef, double [[X:%.*]], i32 1
; CHECK-NEXT: [[BO:%.*]] = fmul <2 x double> [[INS]], <double 4.200000e+01, double -4.200000e+01>
; CHECK-NEXT: [[BO_SCALAR:%.*]] = fmul double [[X:%.*]], -4.200000e+01
; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x double> <double 0x7FF8000000000000, double 0x7FF8000000000000>, double [[BO_SCALAR]], i64 1
; CHECK-NEXT: ret <2 x double> [[BO]]
;
%ins = insertelement <2 x double> undef, double %x, i32 1
@ -625,8 +641,8 @@ define <2 x double> @fmul_constant_not_undef_lane(double %x) {
define <2 x double> @fdiv_constant_op0(double %x) {
; CHECK-LABEL: @fdiv_constant_op0(
; CHECK-NEXT: [[INS:%.*]] = insertelement <2 x double> undef, double [[X:%.*]], i32 1
; CHECK-NEXT: [[BO:%.*]] = fdiv nnan <2 x double> <double undef, double 4.200000e+01>, [[INS]]
; CHECK-NEXT: [[BO_SCALAR:%.*]] = fdiv nnan double 4.200000e+01, [[X:%.*]]
; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x double> <double undef, double 0x7FF8000000000000>, double [[BO_SCALAR]], i64 1
; CHECK-NEXT: ret <2 x double> [[BO]]
;
%ins = insertelement <2 x double> undef, double %x, i32 1
@ -636,8 +652,8 @@ define <2 x double> @fdiv_constant_op0(double %x) {
define <2 x double> @fdiv_constant_op0_not_undef_lane(double %x) {
; CHECK-LABEL: @fdiv_constant_op0_not_undef_lane(
; CHECK-NEXT: [[INS:%.*]] = insertelement <2 x double> undef, double [[X:%.*]], i32 0
; CHECK-NEXT: [[BO:%.*]] = fdiv ninf <2 x double> <double 4.200000e+01, double -4.200000e+01>, [[INS]]
; CHECK-NEXT: [[BO_SCALAR:%.*]] = fdiv ninf double 4.200000e+01, [[X:%.*]]
; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x double> <double 0x7FF8000000000000, double 0x7FF8000000000000>, double [[BO_SCALAR]], i64 0
; CHECK-NEXT: ret <2 x double> [[BO]]
;
%ins = insertelement <2 x double> undef, double %x, i32 0
@ -647,8 +663,8 @@ define <2 x double> @fdiv_constant_op0_not_undef_lane(double %x) {
define <2 x double> @fdiv_constant_op1(double %x) {
; CHECK-LABEL: @fdiv_constant_op1(
; CHECK-NEXT: [[INS:%.*]] = insertelement <2 x double> undef, double [[X:%.*]], i32 0
; CHECK-NEXT: [[BO:%.*]] = fdiv <2 x double> [[INS]], <double 4.200000e+01, double undef>
; CHECK-NEXT: [[BO_SCALAR:%.*]] = fdiv double [[X:%.*]], 4.200000e+01
; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x double> <double 0x7FF8000000000000, double undef>, double [[BO_SCALAR]], i64 0
; CHECK-NEXT: ret <2 x double> [[BO]]
;
%ins = insertelement <2 x double> undef, double %x, i32 0
@ -658,8 +674,8 @@ define <2 x double> @fdiv_constant_op1(double %x) {
define <2 x double> @fdiv_constant_op1_not_undef_lane(double %x) {
; CHECK-LABEL: @fdiv_constant_op1_not_undef_lane(
; CHECK-NEXT: [[INS:%.*]] = insertelement <2 x double> undef, double [[X:%.*]], i32 0
; CHECK-NEXT: [[BO:%.*]] = fdiv <2 x double> [[INS]], <double 4.200000e+01, double -4.200000e+01>
; CHECK-NEXT: [[BO_SCALAR:%.*]] = fdiv double [[X:%.*]], 4.200000e+01
; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x double> <double 0x7FF8000000000000, double 0x7FF8000000000000>, double [[BO_SCALAR]], i64 0
; CHECK-NEXT: ret <2 x double> [[BO]]
;
%ins = insertelement <2 x double> undef, double %x, i32 0
@ -669,8 +685,8 @@ define <2 x double> @fdiv_constant_op1_not_undef_lane(double %x) {
define <2 x double> @frem_constant_op0(double %x) {
; CHECK-LABEL: @frem_constant_op0(
; CHECK-NEXT: [[INS:%.*]] = insertelement <2 x double> undef, double [[X:%.*]], i32 0
; CHECK-NEXT: [[BO:%.*]] = frem fast <2 x double> <double 4.200000e+01, double undef>, [[INS]]
; CHECK-NEXT: [[BO_SCALAR:%.*]] = frem fast double 4.200000e+01, [[X:%.*]]
; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x double> <double 0x7FF8000000000000, double undef>, double [[BO_SCALAR]], i64 0
; CHECK-NEXT: ret <2 x double> [[BO]]
;
%ins = insertelement <2 x double> undef, double %x, i32 0
@ -680,8 +696,8 @@ define <2 x double> @frem_constant_op0(double %x) {
define <2 x double> @frem_constant_op0_not_undef_lane(double %x) {
; CHECK-LABEL: @frem_constant_op0_not_undef_lane(
; CHECK-NEXT: [[INS:%.*]] = insertelement <2 x double> undef, double [[X:%.*]], i32 1
; CHECK-NEXT: [[BO:%.*]] = frem <2 x double> <double 4.200000e+01, double -4.200000e+01>, [[INS]]
; CHECK-NEXT: [[BO_SCALAR:%.*]] = frem double -4.200000e+01, [[X:%.*]]
; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x double> <double 0x7FF8000000000000, double 0x7FF8000000000000>, double [[BO_SCALAR]], i64 1
; CHECK-NEXT: ret <2 x double> [[BO]]
;
%ins = insertelement <2 x double> undef, double %x, i32 1
@ -691,8 +707,8 @@ define <2 x double> @frem_constant_op0_not_undef_lane(double %x) {
define <2 x double> @frem_constant_op1(double %x) {
; CHECK-LABEL: @frem_constant_op1(
; CHECK-NEXT: [[INS:%.*]] = insertelement <2 x double> undef, double [[X:%.*]], i32 1
; CHECK-NEXT: [[BO:%.*]] = frem ninf <2 x double> [[INS]], <double undef, double 4.200000e+01>
; CHECK-NEXT: [[BO_SCALAR:%.*]] = frem ninf double [[X:%.*]], 4.200000e+01
; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x double> <double undef, double 0x7FF8000000000000>, double [[BO_SCALAR]], i64 1
; CHECK-NEXT: ret <2 x double> [[BO]]
;
%ins = insertelement <2 x double> undef, double %x, i32 1
@ -702,8 +718,8 @@ define <2 x double> @frem_constant_op1(double %x) {
define <2 x double> @frem_constant_op1_not_undef_lane(double %x) {
; CHECK-LABEL: @frem_constant_op1_not_undef_lane(
; CHECK-NEXT: [[INS:%.*]] = insertelement <2 x double> undef, double [[X:%.*]], i32 0
; CHECK-NEXT: [[BO:%.*]] = frem nnan <2 x double> [[INS]], <double 4.200000e+01, double -4.200000e+01>
; CHECK-NEXT: [[BO_SCALAR:%.*]] = frem nnan double [[X:%.*]], 4.200000e+01
; CHECK-NEXT: [[BO:%.*]] = insertelement <2 x double> <double 0x7FF8000000000000, double 0x7FF8000000000000>, double [[BO_SCALAR]], i64 0
; CHECK-NEXT: ret <2 x double> [[BO]]
;
%ins = insertelement <2 x double> undef, double %x, i32 0