[llvm] ed67f5e - [VectorCombine] scalarize compares with insertelement operand(s)
Sanjay Patel via llvm-commits
llvm-commits at lists.llvm.org
Tue Jun 16 10:48:17 PDT 2020
Author: Sanjay Patel
Date: 2020-06-16T13:48:10-04:00
New Revision: ed67f5e7ab59d378bb09153a0df132333c43c9cb
URL: https://github.com/llvm/llvm-project/commit/ed67f5e7ab59d378bb09153a0df132333c43c9cb
DIFF: https://github.com/llvm/llvm-project/commit/ed67f5e7ab59d378bb09153a0df132333c43c9cb.diff
LOG: [VectorCombine] scalarize compares with insertelement operand(s)
Generalize scalarization (recently enhanced with D80885)
to allow compares as well as binops.
Similar to binops, we are avoiding scalarization of a loaded
value because that could avoid a register transfer in codegen.
This requires 1 extra predicate that I am aware of: we do not
want to scalarize the condition value of a vector select. That
might also invert a transform that we do in instcombine that
prefers a vector condition operand for a vector select.
I think this is the final step in solving PR37463:
https://bugs.llvm.org/show_bug.cgi?id=37463
Differential Revision: https://reviews.llvm.org/D81661
Added:
Modified:
llvm/lib/Transforms/Vectorize/VectorCombine.cpp
llvm/test/Transforms/VectorCombine/X86/scalarize-cmp.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/Vectorize/VectorCombine.cpp b/llvm/lib/Transforms/Vectorize/VectorCombine.cpp
index d78a4e429033..05f9c6f7daff 100644
--- a/llvm/lib/Transforms/Vectorize/VectorCombine.cpp
+++ b/llvm/lib/Transforms/Vectorize/VectorCombine.cpp
@@ -37,6 +37,7 @@ STATISTIC(NumVecCmp, "Number of vector compares formed");
STATISTIC(NumVecBO, "Number of vector binops formed");
STATISTIC(NumShufOfBitcast, "Number of shuffles moved after bitcast");
STATISTIC(NumScalarBO, "Number of scalar binops formed");
+STATISTIC(NumScalarCmp, "Number of scalar compares formed");
static cl::opt<bool> DisableVectorCombine(
"disable-vector-combine", cl::init(false), cl::Hidden,
@@ -312,18 +313,31 @@ static bool foldBitcastShuf(Instruction &I, const TargetTransformInfo &TTI) {
return true;
}
-/// 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) {
+/// Match a vector binop or compare instruction with at least one inserted
+/// scalar operand and convert to scalar binop/cmp followed by insertelement.
+static bool scalarizeBinopOrCmp(Instruction &I,
+ const TargetTransformInfo &TTI) {
+ CmpInst::Predicate Pred = CmpInst::BAD_ICMP_PREDICATE;
Value *Ins0, *Ins1;
- if (!match(&I, m_BinOp(m_Value(Ins0), m_Value(Ins1))))
+ if (!match(&I, m_BinOp(m_Value(Ins0), m_Value(Ins1))) &&
+ !match(&I, m_Cmp(Pred, m_Value(Ins0), m_Value(Ins1))))
return false;
+ // Do not convert the vector condition of a vector select into a scalar
+ // condition. That may cause problems for codegen because of
diff erences in
+ // boolean formats and register-file transfers.
+ // TODO: Can we account for that in the cost model?
+ bool IsCmp = Pred != CmpInst::Predicate::BAD_ICMP_PREDICATE;
+ if (IsCmp)
+ for (User *U : I.users())
+ if (match(U, m_Select(m_Specific(&I), m_Value(), m_Value())))
+ 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)
+ // vec_op VecC0, (inselt VecC1, V1, Index)
+ // vec_op (inselt VecC0, V0, Index), VecC1
+ // vec_op (inselt VecC0, V0, Index), (inselt VecC1, V1, Index)
// TODO: Deal with mismatched index constants and variable indexes?
Constant *VecC0 = nullptr, *VecC1 = nullptr;
Value *V0 = nullptr, *V1 = nullptr;
@@ -360,9 +374,15 @@ static bool scalarizeBinop(Instruction &I, const TargetTransformInfo &TTI) {
(ScalarTy->isIntegerTy() || ScalarTy->isFloatingPointTy()) &&
"Unexpected types for insert into binop");
- Instruction::BinaryOps Opcode = cast<BinaryOperator>(&I)->getOpcode();
- int ScalarOpCost = TTI.getArithmeticInstrCost(Opcode, ScalarTy);
- int VectorOpCost = TTI.getArithmeticInstrCost(Opcode, VecTy);
+ unsigned Opcode = I.getOpcode();
+ int ScalarOpCost, VectorOpCost;
+ if (IsCmp) {
+ ScalarOpCost = TTI.getCmpSelInstrCost(Opcode, ScalarTy);
+ VectorOpCost = TTI.getCmpSelInstrCost(Opcode, VecTy);
+ } else {
+ ScalarOpCost = TTI.getArithmeticInstrCost(Opcode, ScalarTy);
+ VectorOpCost = TTI.getArithmeticInstrCost(Opcode, VecTy);
+ }
// Get cost estimate for the insert element. This cost will factor into
// both sequences.
@@ -378,18 +398,26 @@ static bool scalarizeBinop(Instruction &I, const TargetTransformInfo &TTI) {
if (OldCost < NewCost)
return false;
- // vec_bo (inselt VecC0, V0, Index), (inselt VecC1, V1, Index) -->
- // inselt NewVecC, (scalar_bo V0, V1), Index
- ++NumScalarBO;
- IRBuilder<> Builder(&I);
+ // vec_op (inselt VecC0, V0, Index), (inselt VecC1, V1, Index) -->
+ // inselt NewVecC, (scalar_op V0, V1), Index
+ if (IsCmp)
+ ++NumScalarCmp;
+ else
+ ++NumScalarBO;
// For constant cases, extract the scalar element, this should constant fold.
+ IRBuilder<> Builder(&I);
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");
+ Value *Scalar =
+ IsCmp ? Opcode == Instruction::FCmp ? Builder.CreateFCmp(Pred, V0, V1)
+ : Builder.CreateICmp(Pred, V0, V1)
+ : Builder.CreateBinOp((Instruction::BinaryOps)Opcode, V0, V1);
+
+ Scalar->setName(I.getName() + ".scalar");
// All IR flags are safe to back-propagate. There is no potential for extra
// poison to be created by the scalar instruction.
@@ -397,7 +425,8 @@ static bool scalarizeBinop(Instruction &I, const TargetTransformInfo &TTI) {
ScalarInst->copyIRFlags(&I);
// Fold the vector constants in the original vectors into a new base vector.
- Constant *NewVecC = ConstantExpr::get(Opcode, VecC0, VecC1);
+ Constant *NewVecC = IsCmp ? ConstantExpr::getCompare(Pred, VecC0, VecC1)
+ : ConstantExpr::get(Opcode, VecC0, VecC1);
Value *Insert = Builder.CreateInsertElement(NewVecC, Scalar, Index);
I.replaceAllUsesWith(Insert);
Insert->takeName(&I);
@@ -425,7 +454,7 @@ static bool runImpl(Function &F, const TargetTransformInfo &TTI,
continue;
MadeChange |= foldExtractExtract(I, TTI);
MadeChange |= foldBitcastShuf(I, TTI);
- MadeChange |= scalarizeBinop(I, TTI);
+ MadeChange |= scalarizeBinopOrCmp(I, TTI);
}
}
diff --git a/llvm/test/Transforms/VectorCombine/X86/scalarize-cmp.ll b/llvm/test/Transforms/VectorCombine/X86/scalarize-cmp.ll
index f176465ecc29..fe2d1f0a5597 100644
--- a/llvm/test/Transforms/VectorCombine/X86/scalarize-cmp.ll
+++ b/llvm/test/Transforms/VectorCombine/X86/scalarize-cmp.ll
@@ -9,9 +9,8 @@ declare void @usef(<4 x float>)
define <16 x i1> @ins0_ins0_i8(i8 %x, i8 %y) {
; CHECK-LABEL: @ins0_ins0_i8(
-; CHECK-NEXT: [[I0:%.*]] = insertelement <16 x i8> undef, i8 [[X:%.*]], i32 0
-; CHECK-NEXT: [[I1:%.*]] = insertelement <16 x i8> undef, i8 [[Y:%.*]], i32 0
-; CHECK-NEXT: [[R:%.*]] = icmp eq <16 x i8> [[I0]], [[I1]]
+; CHECK-NEXT: [[R_SCALAR:%.*]] = icmp eq i8 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT: [[R:%.*]] = insertelement <16 x i1> undef, i1 [[R_SCALAR]], i64 0
; CHECK-NEXT: ret <16 x i1> [[R]]
;
%i0 = insertelement <16 x i8> undef, i8 %x, i32 0
@@ -24,9 +23,8 @@ define <16 x i1> @ins0_ins0_i8(i8 %x, i8 %y) {
define <8 x i1> @ins5_ins5_i16(i16 %x, i16 %y) {
; CHECK-LABEL: @ins5_ins5_i16(
-; CHECK-NEXT: [[I0:%.*]] = insertelement <8 x i16> undef, i16 [[X:%.*]], i8 5
-; CHECK-NEXT: [[I1:%.*]] = insertelement <8 x i16> undef, i16 [[Y:%.*]], i32 5
-; CHECK-NEXT: [[R:%.*]] = icmp sgt <8 x i16> [[I0]], [[I1]]
+; CHECK-NEXT: [[R_SCALAR:%.*]] = icmp sgt i16 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT: [[R:%.*]] = insertelement <8 x i1> undef, i1 [[R_SCALAR]], i64 5
; CHECK-NEXT: ret <8 x i1> [[R]]
;
%i0 = insertelement <8 x i16> undef, i16 %x, i8 5
@@ -39,9 +37,8 @@ define <8 x i1> @ins5_ins5_i16(i16 %x, i16 %y) {
define <2 x i1> @ins1_ins1_i64(i64 %x, i64 %y) {
; CHECK-LABEL: @ins1_ins1_i64(
-; CHECK-NEXT: [[I0:%.*]] = insertelement <2 x i64> zeroinitializer, i64 [[X:%.*]], i64 1
-; CHECK-NEXT: [[I1:%.*]] = insertelement <2 x i64> <i64 1, i64 -1>, i64 [[Y:%.*]], i32 1
-; CHECK-NEXT: [[R:%.*]] = icmp sle <2 x i64> [[I0]], [[I1]]
+; CHECK-NEXT: [[R_SCALAR:%.*]] = icmp sle i64 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT: [[R:%.*]] = insertelement <2 x i1> <i1 true, i1 false>, i1 [[R_SCALAR]], i64 1
; CHECK-NEXT: ret <2 x i1> [[R]]
;
%i0 = insertelement <2 x i64> zeroinitializer, i64 %x, i64 1
@@ -54,9 +51,8 @@ define <2 x i1> @ins1_ins1_i64(i64 %x, i64 %y) {
define <2 x i1> @ins0_ins0_f64(double %x, double %y) {
; CHECK-LABEL: @ins0_ins0_f64(
-; CHECK-NEXT: [[I0:%.*]] = insertelement <2 x double> undef, double [[X:%.*]], i32 0
-; CHECK-NEXT: [[I1:%.*]] = insertelement <2 x double> undef, double [[Y:%.*]], i32 0
-; CHECK-NEXT: [[R:%.*]] = fcmp nnan ninf uge <2 x double> [[I0]], [[I1]]
+; CHECK-NEXT: [[R_SCALAR:%.*]] = fcmp nnan ninf uge double [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT: [[R:%.*]] = insertelement <2 x i1> <i1 true, i1 true>, i1 [[R_SCALAR]], i64 0
; CHECK-NEXT: ret <2 x i1> [[R]]
;
%i0 = insertelement <2 x double> undef, double %x, i32 0
@@ -84,9 +80,8 @@ define <16 x i1> @ins1_ins0_i8(i8 %x, i8 %y) {
define <4 x i1> @ins0_ins0_i32(i32 %x, i32 %y) {
; CHECK-LABEL: @ins0_ins0_i32(
-; CHECK-NEXT: [[I0:%.*]] = insertelement <4 x i32> zeroinitializer, i32 [[X:%.*]], i32 0
-; CHECK-NEXT: [[I1:%.*]] = insertelement <4 x i32> undef, i32 [[Y:%.*]], i32 0
-; CHECK-NEXT: [[R:%.*]] = icmp ne <4 x i32> [[I0]], [[I1]]
+; CHECK-NEXT: [[R_SCALAR:%.*]] = icmp ne i32 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT: [[R:%.*]] = insertelement <4 x i1> undef, i1 [[R_SCALAR]], i64 0
; CHECK-NEXT: ret <4 x i1> [[R]]
;
%i0 = insertelement <4 x i32> zeroinitializer, i32 %x, i32 0
@@ -101,8 +96,8 @@ define <4 x i1> @ins0_ins0_i32_use(i32 %x, i32 %y) {
; CHECK-LABEL: @ins0_ins0_i32_use(
; CHECK-NEXT: [[I0:%.*]] = insertelement <4 x i32> undef, i32 [[X:%.*]], i32 0
; CHECK-NEXT: call void @use(<4 x i32> [[I0]])
-; CHECK-NEXT: [[I1:%.*]] = insertelement <4 x i32> undef, i32 [[Y:%.*]], i32 0
-; CHECK-NEXT: [[R:%.*]] = icmp ugt <4 x i32> [[I0]], [[I1]]
+; CHECK-NEXT: [[R_SCALAR:%.*]] = icmp ugt i32 [[X]], [[Y:%.*]]
+; CHECK-NEXT: [[R:%.*]] = insertelement <4 x i1> undef, i1 [[R_SCALAR]], i64 0
; CHECK-NEXT: ret <4 x i1> [[R]]
;
%i0 = insertelement <4 x i32> undef, i32 %x, i32 0
@@ -116,10 +111,10 @@ define <4 x i1> @ins0_ins0_i32_use(i32 %x, i32 %y) {
define <4 x i1> @ins1_ins1_f32_use(float %x, float %y) {
; CHECK-LABEL: @ins1_ins1_f32_use(
-; CHECK-NEXT: [[I0:%.*]] = insertelement <4 x float> undef, float [[X:%.*]], i32 1
; CHECK-NEXT: [[I1:%.*]] = insertelement <4 x float> undef, float [[Y:%.*]], i32 1
; CHECK-NEXT: call void @usef(<4 x float> [[I1]])
-; CHECK-NEXT: [[R:%.*]] = fcmp ogt <4 x float> [[I0]], [[I1]]
+; CHECK-NEXT: [[R_SCALAR:%.*]] = fcmp ogt float [[X:%.*]], [[Y]]
+; CHECK-NEXT: [[R:%.*]] = insertelement <4 x i1> zeroinitializer, i1 [[R_SCALAR]], i64 1
; CHECK-NEXT: ret <4 x i1> [[R]]
;
%i0 = insertelement <4 x float> undef, float %x, i32 1
@@ -150,8 +145,8 @@ define <4 x i1> @ins2_ins2_f32_uses(float %x, float %y) {
define <2 x i1> @constant_op1_i64(i64 %x) {
; CHECK-LABEL: @constant_op1_i64(
-; CHECK-NEXT: [[INS:%.*]] = insertelement <2 x i64> undef, i64 [[X:%.*]], i32 0
-; CHECK-NEXT: [[R:%.*]] = icmp ne <2 x i64> [[INS]], <i64 42, i64 undef>
+; CHECK-NEXT: [[R_SCALAR:%.*]] = icmp ne i64 [[X:%.*]], 42
+; CHECK-NEXT: [[R:%.*]] = insertelement <2 x i1> undef, i1 [[R_SCALAR]], i64 0
; CHECK-NEXT: ret <2 x i1> [[R]]
;
%ins = insertelement <2 x i64> undef, i64 %x, i32 0
@@ -161,8 +156,8 @@ define <2 x i1> @constant_op1_i64(i64 %x) {
define <2 x i1> @constant_op1_i64_not_undef_lane(i64 %x) {
; CHECK-LABEL: @constant_op1_i64_not_undef_lane(
-; CHECK-NEXT: [[INS:%.*]] = insertelement <2 x i64> undef, i64 [[X:%.*]], i32 0
-; CHECK-NEXT: [[R:%.*]] = icmp sge <2 x i64> [[INS]], <i64 42, i64 -42>
+; CHECK-NEXT: [[R_SCALAR:%.*]] = icmp sge i64 [[X:%.*]], 42
+; CHECK-NEXT: [[R:%.*]] = insertelement <2 x i1> <i1 true, i1 true>, i1 [[R_SCALAR]], i64 0
; CHECK-NEXT: ret <2 x i1> [[R]]
;
%ins = insertelement <2 x i64> undef, i64 %x, i32 0
@@ -170,6 +165,8 @@ define <2 x i1> @constant_op1_i64_not_undef_lane(i64 %x) {
ret <2 x i1> %r
}
+; negative test - load prevents the transform
+
define <2 x i1> @constant_op1_i64_load(i64* %p) {
; CHECK-LABEL: @constant_op1_i64_load(
; CHECK-NEXT: [[LD:%.*]] = load i64, i64* [[P:%.*]], align 4
@@ -185,8 +182,8 @@ define <2 x i1> @constant_op1_i64_load(i64* %p) {
define <4 x i1> @constant_op0_i32(i32 %x) {
; CHECK-LABEL: @constant_op0_i32(
-; CHECK-NEXT: [[INS:%.*]] = insertelement <4 x i32> undef, i32 [[X:%.*]], i32 1
-; CHECK-NEXT: [[R:%.*]] = icmp ult <4 x i32> <i32 undef, i32 -42, i32 undef, i32 undef>, [[INS]]
+; CHECK-NEXT: [[R_SCALAR:%.*]] = icmp ult i32 -42, [[X:%.*]]
+; CHECK-NEXT: [[R:%.*]] = insertelement <4 x i1> zeroinitializer, i1 [[R_SCALAR]], i64 1
; CHECK-NEXT: ret <4 x i1> [[R]]
;
%ins = insertelement <4 x i32> undef, i32 %x, i32 1
@@ -196,8 +193,8 @@ define <4 x i1> @constant_op0_i32(i32 %x) {
define <4 x i1> @constant_op0_i32_not_undef_lane(i32 %x) {
; CHECK-LABEL: @constant_op0_i32_not_undef_lane(
-; CHECK-NEXT: [[INS:%.*]] = insertelement <4 x i32> undef, i32 [[X:%.*]], i32 1
-; CHECK-NEXT: [[R:%.*]] = icmp ule <4 x i32> <i32 1, i32 42, i32 42, i32 -42>, [[INS]]
+; CHECK-NEXT: [[R_SCALAR:%.*]] = icmp ule i32 42, [[X:%.*]]
+; CHECK-NEXT: [[R:%.*]] = insertelement <4 x i1> <i1 true, i1 true, i1 true, i1 true>, i1 [[R_SCALAR]], i64 1
; CHECK-NEXT: ret <4 x i1> [[R]]
;
%ins = insertelement <4 x i32> undef, i32 %x, i32 1
@@ -207,8 +204,8 @@ define <4 x i1> @constant_op0_i32_not_undef_lane(i32 %x) {
define <2 x i1> @constant_op0_f64(double %x) {
; CHECK-LABEL: @constant_op0_f64(
-; CHECK-NEXT: [[INS:%.*]] = insertelement <2 x double> undef, double [[X:%.*]], i32 0
-; CHECK-NEXT: [[R:%.*]] = fcmp fast olt <2 x double> <double 4.200000e+01, double undef>, [[INS]]
+; CHECK-NEXT: [[R_SCALAR:%.*]] = fcmp fast olt double 4.200000e+01, [[X:%.*]]
+; CHECK-NEXT: [[R:%.*]] = insertelement <2 x i1> zeroinitializer, i1 [[R_SCALAR]], i64 0
; CHECK-NEXT: ret <2 x i1> [[R]]
;
%ins = insertelement <2 x double> undef, double %x, i32 0
@@ -218,8 +215,8 @@ define <2 x i1> @constant_op0_f64(double %x) {
define <2 x i1> @constant_op0_f64_not_undef_lane(double %x) {
; CHECK-LABEL: @constant_op0_f64_not_undef_lane(
-; CHECK-NEXT: [[INS:%.*]] = insertelement <2 x double> undef, double [[X:%.*]], i32 1
-; CHECK-NEXT: [[R:%.*]] = fcmp nnan ueq <2 x double> <double 4.200000e+01, double -4.200000e+01>, [[INS]]
+; CHECK-NEXT: [[R_SCALAR:%.*]] = fcmp nnan ueq double -4.200000e+01, [[X:%.*]]
+; CHECK-NEXT: [[R:%.*]] = insertelement <2 x i1> <i1 true, i1 true>, i1 [[R_SCALAR]], i64 1
; CHECK-NEXT: ret <2 x i1> [[R]]
;
%ins = insertelement <2 x double> undef, double %x, i32 1
@@ -229,8 +226,8 @@ define <2 x i1> @constant_op0_f64_not_undef_lane(double %x) {
define <2 x i1> @constant_op1_f64(double %x) {
; CHECK-LABEL: @constant_op1_f64(
-; CHECK-NEXT: [[INS:%.*]] = insertelement <2 x double> undef, double [[X:%.*]], i32 1
-; CHECK-NEXT: [[R:%.*]] = fcmp one <2 x double> [[INS]], <double undef, double 4.200000e+01>
+; CHECK-NEXT: [[R_SCALAR:%.*]] = fcmp one double [[X:%.*]], 4.200000e+01
+; CHECK-NEXT: [[R:%.*]] = insertelement <2 x i1> zeroinitializer, i1 [[R_SCALAR]], i64 1
; CHECK-NEXT: ret <2 x i1> [[R]]
;
%ins = insertelement <2 x double> undef, double %x, i32 1
@@ -240,8 +237,8 @@ define <2 x i1> @constant_op1_f64(double %x) {
define <4 x i1> @constant_op1_f32_not_undef_lane(float %x) {
; CHECK-LABEL: @constant_op1_f32_not_undef_lane(
-; CHECK-NEXT: [[INS:%.*]] = insertelement <4 x float> undef, float [[X:%.*]], i32 0
-; CHECK-NEXT: [[R:%.*]] = fcmp uge <4 x float> [[INS]], <float 4.200000e+01, float -4.200000e+01, float 0.000000e+00, float 1.000000e+00>
+; CHECK-NEXT: [[R_SCALAR:%.*]] = fcmp uge float [[X:%.*]], 4.200000e+01
+; CHECK-NEXT: [[R:%.*]] = insertelement <4 x i1> <i1 true, i1 true, i1 true, i1 true>, i1 [[R_SCALAR]], i64 0
; CHECK-NEXT: ret <4 x i1> [[R]]
;
%ins = insertelement <4 x float> undef, float %x, i32 0
@@ -249,6 +246,8 @@ define <4 x i1> @constant_op1_f32_not_undef_lane(float %x) {
ret <4 x i1> %r
}
+; negative test - select prevents the transform
+
define <4 x float> @vec_select_use1(<4 x float> %x, <4 x float> %y, i32 %a, i32 %b) {
; CHECK-LABEL: @vec_select_use1(
; CHECK-NEXT: [[VECA:%.*]] = insertelement <4 x i32> undef, i32 [[A:%.*]], i8 0
@@ -264,6 +263,8 @@ define <4 x float> @vec_select_use1(<4 x float> %x, <4 x float> %y, i32 %a, i32
ret <4 x float> %r
}
+; negative test - select prevents the transform
+
define <4 x float> @vec_select_use2(<4 x float> %x, <4 x float> %y, float %a) {
; CHECK-LABEL: @vec_select_use2(
; CHECK-NEXT: [[VECA:%.*]] = insertelement <4 x float> undef, float [[A:%.*]], i8 0
More information about the llvm-commits
mailing list