From 6b857dc5c7f2657dd34c99b222ac41d492f21f2d Mon Sep 17 00:00:00 2001 From: "Stokop, Krzysztof" Date: Mon, 2 Dec 2024 16:20:12 +0000 Subject: [PATCH] Preserve metadata in scalarization pass Preserve metadata in scalarization pass --- IGC/Compiler/Optimizer/Scalarizer.cpp | 52 +++++++++++-------- ...arize-binary-instruction-typed-pointers.ll | 23 ++++++++ .../scalarize-binary-instruction.ll | 23 ++++++++ ...alarize-cast-instruction-typed-pointers.ll | 17 ++++++ .../scalarize-cast-instruction.ll | 17 ++++++ ...alarize-comp-instruction-typed-pointers.ll | 19 +++++++ .../scalarize-comp-instruction.ll | 19 +++++++ ...etelementptr-instruction-typed-pointers.ll | 28 +++++++++- .../scalarize-getelementptr-instruction.ll | 11 ++++ ...calarize-phi-instruction-typed-pointers.ll | 33 ++++++++++++ .../scalarize-phi-instruction.ll | 33 ++++++++++++ ...arize-select-instruction-typed-pointers.ll | 21 ++++++++ .../scalarize-select-instruction.ll | 21 ++++++++ ...larize-unary-instruction-typed-pointers.ll | 23 +++++++- .../scalarize-unary-instruction.ll | 21 ++++++++ 15 files changed, 337 insertions(+), 24 deletions(-) diff --git a/IGC/Compiler/Optimizer/Scalarizer.cpp b/IGC/Compiler/Optimizer/Scalarizer.cpp index efe80f2e6b27..2f71ab84b6b6 100644 --- a/IGC/Compiler/Optimizer/Scalarizer.cpp +++ b/IGC/Compiler/Optimizer/Scalarizer.cpp @@ -410,17 +410,16 @@ void ScalarizeFunction::visitUnaryOperator(UnaryOperator& UI) newScalarizedInsts.resize(numElements); for (unsigned dup = 0; dup < numElements; dup++) { - Value* Val = UnaryOperator::Create( + UnaryOperator* Val = UnaryOperator::Create( UI.getOpcode(), operand0[dup], UI.getName(), &UI ); - if (UnaryOperator* UO = dyn_cast(Val)) { - // Copy fast math flags if any. - if (isa(UO)) - UO->setFastMathFlags(UI.getFastMathFlags()); - } + // Copy fast math flags if any. + if (isa(Val)) + Val->setFastMathFlags(UI.getFastMathFlags()); + Val->copyMetadata(UI); newScalarizedInsts[dup] = Val; } @@ -461,26 +460,27 @@ void ScalarizeFunction::visitBinaryOperator(BinaryOperator& BI) newScalarizedInsts.resize(numElements); for (unsigned dup = 0; dup < numElements; dup++) { - Value* Val = BinaryOperator::Create( + BinaryOperator* Val = BinaryOperator::Create( BI.getOpcode(), operand0[dup], operand1[dup], BI.getName(), &BI ); - if (BinaryOperator* BO = dyn_cast(Val)) { - // Copy overflow flags if any. - if (isa(BO)) { - BO->setHasNoSignedWrap(BI.hasNoSignedWrap()); - BO->setHasNoUnsignedWrap(BI.hasNoUnsignedWrap()); - } - // Copy exact flag if any. - if (isa(BO)) - BO->setIsExact(BI.isExact()); - // Copy fast math flags if any. - if (isa(BO)) - BO->setFastMathFlags(BI.getFastMathFlags()); + + // Copy overflow flags if any. + if (isa(Val)) { + Val->setHasNoSignedWrap(BI.hasNoSignedWrap()); + Val->setHasNoUnsignedWrap(BI.hasNoUnsignedWrap()); } + // Copy exact flag if any. + if (isa(Val)) + Val->setIsExact(BI.isExact()); + // Copy fast math flags if any. + if (isa(Val)) + Val->setFastMathFlags(BI.getFastMathFlags()); + + Val->copyMetadata(BI); newScalarizedInsts[dup] = Val; } @@ -534,6 +534,7 @@ void ScalarizeFunction::visitCmpInst(CmpInst& CI) { Val->setFastMathFlags(CI.getFastMathFlags()); } + Val->copyMetadata(CI); newScalarizedInsts[dup] = Val; } @@ -599,13 +600,15 @@ void ScalarizeFunction::visitCastInst(CastInst& CI) newScalarizedInsts.resize(numElements); for (unsigned dup = 0; dup < numElements; dup++) { - newScalarizedInsts[dup] = CastInst::Create( + CastInst* tmp = CastInst::Create( CI.getOpcode(), operand0[dup], scalarDestType, CI.getName(), &CI ); + tmp->copyMetadata(CI); + newScalarizedInsts[dup] = tmp; } // Add new value/s to SCM @@ -715,6 +718,8 @@ void ScalarizeFunction::visitPHINode(PHINode& PI) tmp->setFastMathFlags(PI.getFastMathFlags()); } + tmp->copyMetadata(PI); + newScalarizedPHI[i] = tmp; } @@ -800,6 +805,7 @@ void ScalarizeFunction::visitSelectInst(SelectInst& SI) { Val->setFastMathFlags(SI.getFastMathFlags()); } + Val->copyMetadata(SI); newScalarizedInsts[dup] = Val; } else @@ -1007,12 +1013,13 @@ void ScalarizeFunction::visitCallInst(CallInst& CI) for (unsigned i = 0; i < numElements; i++) { Type* scalarType = operand0[i]->getType(); - Value* scalarFshl = CallInst::Create( + CallInst* scalarFshl = CallInst::Create( Intrinsic::getDeclaration(CI.getModule(), Intrinsic::fshl, { scalarType }), { operand0[i], operand1[i], operand2[i] }, CI.getName() + ".scalar", &CI ); + scalarFshl->copyMetadata(CI); newScalarizedInsts[i] = scalarFshl; } @@ -1077,8 +1084,9 @@ void ScalarizeFunction::visitGetElementPtrInst(GetElementPtrInst& GI) auto op2 = indexValue->getType()->isVectorTy() ? operand2[i] : indexValue; Type* BaseTy = GI.getSourceElementType(); - Value* newGEP = GetElementPtrInst::Create(BaseTy, op1, op2, + GetElementPtrInst* newGEP = GetElementPtrInst::Create(BaseTy, op1, op2, VALUE_NAME(GI.getName()), &GI); + newGEP->copyMetadata(GI); Value* constIndex = ConstantInt::get(Type::getInt32Ty(context()), i); Instruction* insert = InsertElementInst::Create(assembledVector, newGEP, constIndex, diff --git a/IGC/Compiler/tests/ScalarizeFunction/scalarize-binary-instruction-typed-pointers.ll b/IGC/Compiler/tests/ScalarizeFunction/scalarize-binary-instruction-typed-pointers.ll index 036a29dff3ba..6e0f0be35133 100644 --- a/IGC/Compiler/tests/ScalarizeFunction/scalarize-binary-instruction-typed-pointers.ll +++ b/IGC/Compiler/tests/ScalarizeFunction/scalarize-binary-instruction-typed-pointers.ll @@ -35,6 +35,27 @@ define spir_kernel void @basic(<2 x i32> %src1, <2 x i32> %src2) { ret void } +define spir_kernel void @should_preserve_metadata(<2 x i32> %src1, <2 x i32> %src2) { +; CHECK-LABEL: define spir_kernel void @should_preserve_metadata( +; CHECK-SAME: <2 x i32> [[SRC1:%.*]], <2 x i32> [[SRC2:%.*]]) { +; CHECK-NEXT: [[SRC2_SCALAR:%.*]] = extractelement <2 x i32> [[SRC2]], i32 0 +; CHECK-NEXT: [[SRC2_SCALAR2:%.*]] = extractelement <2 x i32> [[SRC2]], i32 1 +; CHECK-NEXT: [[SRC1_SCALAR:%.*]] = extractelement <2 x i32> [[SRC1]], i32 0 +; CHECK-NEXT: [[SRC1_SCALAR1:%.*]] = extractelement <2 x i32> [[SRC1]], i32 1 +; CHECK-NEXT: [[TMP1:%.*]] = alloca <2 x i32>, align 8 +; CHECK-NEXT: [[TMP2:%.*]] = add i32 [[SRC1_SCALAR]], [[SRC2_SCALAR]], !any_metadata [[META0:![0-9]+]] +; CHECK-NEXT: [[TMP3:%.*]] = add i32 [[SRC1_SCALAR1]], [[SRC2_SCALAR2]], !any_metadata [[META0]] +; CHECK-NEXT: [[DOTASSEMBLED_VECT:%.*]] = insertelement <2 x i32> undef, i32 [[TMP2]], i32 0 +; CHECK-NEXT: [[DOTASSEMBLED_VECT3:%.*]] = insertelement <2 x i32> [[DOTASSEMBLED_VECT]], i32 [[TMP3]], i32 1 +; CHECK-NEXT: store <2 x i32> [[DOTASSEMBLED_VECT3]], <2 x i32>* [[TMP1]], align 8 +; CHECK-NEXT: ret void +; + %1 = alloca <2 x i32> + %2 = add <2 x i32> %src1, %src2, !any_metadata !{i32 0} + store <2 x i32> %2, <2 x i32>* %1 + ret void +} + define spir_kernel void @should_work_with_different_instruction_type(<2 x float> %src1, <2 x float> %src2) { ; CHECK-LABEL: define spir_kernel void @should_work_with_different_instruction_type( ; CHECK-SAME: <2 x float> [[SRC1:%.*]], <2 x float> [[SRC2:%.*]]) { @@ -255,3 +276,5 @@ define spir_kernel void @should_work_with_nuw_nsw(<2 x i32> %src1, <2 x i32> %sr store <2 x i32> %2, <2 x i32>* %1 ret void } + +; CHECK: [[META0]] = !{i32 0} \ No newline at end of file diff --git a/IGC/Compiler/tests/ScalarizeFunction/scalarize-binary-instruction.ll b/IGC/Compiler/tests/ScalarizeFunction/scalarize-binary-instruction.ll index 50c5921271ee..6afb62f482dc 100644 --- a/IGC/Compiler/tests/ScalarizeFunction/scalarize-binary-instruction.ll +++ b/IGC/Compiler/tests/ScalarizeFunction/scalarize-binary-instruction.ll @@ -36,6 +36,27 @@ define spir_kernel void @basic(<2 x i32> %src1, <2 x i32> %src2) { ret void } +define spir_kernel void @should_preserve_metadata(<2 x i32> %src1, <2 x i32> %src2) { +; CHECK-LABEL: define spir_kernel void @should_preserve_metadata( +; CHECK-SAME: <2 x i32> [[SRC1:%.*]], <2 x i32> [[SRC2:%.*]]) { +; CHECK-NEXT: [[SRC2_SCALAR:%.*]] = extractelement <2 x i32> [[SRC2]], i32 0 +; CHECK-NEXT: [[SRC2_SCALAR2:%.*]] = extractelement <2 x i32> [[SRC2]], i32 1 +; CHECK-NEXT: [[SRC1_SCALAR:%.*]] = extractelement <2 x i32> [[SRC1]], i32 0 +; CHECK-NEXT: [[SRC1_SCALAR1:%.*]] = extractelement <2 x i32> [[SRC1]], i32 1 +; CHECK-NEXT: [[TMP1:%.*]] = alloca <2 x i32>, align 8 +; CHECK-NEXT: [[TMP2:%.*]] = add i32 [[SRC1_SCALAR]], [[SRC2_SCALAR]], !any_metadata [[META0:![0-9]+]] +; CHECK-NEXT: [[TMP3:%.*]] = add i32 [[SRC1_SCALAR1]], [[SRC2_SCALAR2]], !any_metadata [[META0]] +; CHECK-NEXT: [[DOTASSEMBLED_VECT:%.*]] = insertelement <2 x i32> undef, i32 [[TMP2]], i32 0 +; CHECK-NEXT: [[DOTASSEMBLED_VECT3:%.*]] = insertelement <2 x i32> [[DOTASSEMBLED_VECT]], i32 [[TMP3]], i32 1 +; CHECK-NEXT: store <2 x i32> [[DOTASSEMBLED_VECT3]], ptr [[TMP1]], align 8 +; CHECK-NEXT: ret void +; + %1 = alloca <2 x i32> + %2 = add <2 x i32> %src1, %src2, !any_metadata !{i32 0} + store <2 x i32> %2, ptr %1 + ret void +} + define spir_kernel void @should_work_with_different_instruction_type(<2 x float> %src1, <2 x float> %src2) { ; CHECK-LABEL: define spir_kernel void @should_work_with_different_instruction_type( ; CHECK-SAME: <2 x float> [[SRC1:%.*]], <2 x float> [[SRC2:%.*]]) { @@ -257,3 +278,5 @@ define spir_kernel void @should_work_with_nuw_nsw(<2 x i32> %src1, <2 x i32> %sr store <2 x i32> %2, ptr %1 ret void } + +; CHECK: [[META0]] = !{i32 0} \ No newline at end of file diff --git a/IGC/Compiler/tests/ScalarizeFunction/scalarize-cast-instruction-typed-pointers.ll b/IGC/Compiler/tests/ScalarizeFunction/scalarize-cast-instruction-typed-pointers.ll index c2ad0702afd7..93afa64f4c9c 100644 --- a/IGC/Compiler/tests/ScalarizeFunction/scalarize-cast-instruction-typed-pointers.ll +++ b/IGC/Compiler/tests/ScalarizeFunction/scalarize-cast-instruction-typed-pointers.ll @@ -29,6 +29,21 @@ define <2 x i8> @basic(<2 x i32> %src1) { ret <2 x i8> %1 } +define <2 x i8> @should_preserve_metadata(<2 x i32> %src1) { +; CHECK-LABEL: define <2 x i8> @should_preserve_metadata( +; CHECK-SAME: <2 x i32> [[SRC1:%.*]]) { +; CHECK-NEXT: [[SRC1_SCALAR:%.*]] = extractelement <2 x i32> [[SRC1]], i32 0 +; CHECK-NEXT: [[SRC1_SCALAR1:%.*]] = extractelement <2 x i32> [[SRC1]], i32 1 +; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[SRC1_SCALAR]] to i8, !any_metadata [[META0:![0-9]+]] +; CHECK-NEXT: [[TMP2:%.*]] = trunc i32 [[SRC1_SCALAR1]] to i8, !any_metadata [[META0]] +; CHECK-NEXT: [[DOTASSEMBLED_VECT:%.*]] = insertelement <2 x i8> undef, i8 [[TMP1]], i32 0 +; CHECK-NEXT: [[DOTASSEMBLED_VECT2:%.*]] = insertelement <2 x i8> [[DOTASSEMBLED_VECT]], i8 [[TMP2]], i32 1 +; CHECK-NEXT: ret <2 x i8> [[DOTASSEMBLED_VECT2]] +; + %1 = trunc <2 x i32> %src1 to <2 x i8>, !any_metadata !{i32 0} + ret <2 x i8> %1 +} + define <2 x float> @should_work_with_different_instruction_type(<2 x double> %src1) { ; CHECK-LABEL: define <2 x float> @should_work_with_different_instruction_type( ; CHECK-SAME: <2 x double> [[SRC1:%.*]]) { @@ -193,3 +208,5 @@ define i8 @should_not_scalarize_scalar() { %1 = trunc i32 4 to i8 ret i8 %1 } + +; CHECK: [[META0]] = !{i32 0} diff --git a/IGC/Compiler/tests/ScalarizeFunction/scalarize-cast-instruction.ll b/IGC/Compiler/tests/ScalarizeFunction/scalarize-cast-instruction.ll index e8369bb48df1..5076f9b3215c 100644 --- a/IGC/Compiler/tests/ScalarizeFunction/scalarize-cast-instruction.ll +++ b/IGC/Compiler/tests/ScalarizeFunction/scalarize-cast-instruction.ll @@ -30,6 +30,21 @@ define <2 x i8> @basic(<2 x i32> %src1) { ret <2 x i8> %1 } +define <2 x i8> @should_preserve_metadata(<2 x i32> %src1) { +; CHECK-LABEL: define <2 x i8> @should_preserve_metadata( +; CHECK-SAME: <2 x i32> [[SRC1:%.*]]) { +; CHECK-NEXT: [[SRC1_SCALAR:%.*]] = extractelement <2 x i32> [[SRC1]], i32 0 +; CHECK-NEXT: [[SRC1_SCALAR1:%.*]] = extractelement <2 x i32> [[SRC1]], i32 1 +; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[SRC1_SCALAR]] to i8, !any_metadata [[META0:![0-9]+]] +; CHECK-NEXT: [[TMP2:%.*]] = trunc i32 [[SRC1_SCALAR1]] to i8, !any_metadata [[META0]] +; CHECK-NEXT: [[DOTASSEMBLED_VECT:%.*]] = insertelement <2 x i8> undef, i8 [[TMP1]], i32 0 +; CHECK-NEXT: [[DOTASSEMBLED_VECT2:%.*]] = insertelement <2 x i8> [[DOTASSEMBLED_VECT]], i8 [[TMP2]], i32 1 +; CHECK-NEXT: ret <2 x i8> [[DOTASSEMBLED_VECT2]] +; + %1 = trunc <2 x i32> %src1 to <2 x i8>, !any_metadata !{i32 0} + ret <2 x i8> %1 +} + define <2 x float> @should_work_with_different_instruction_type(<2 x double> %src1) { ; CHECK-LABEL: define <2 x float> @should_work_with_different_instruction_type( ; CHECK-SAME: <2 x double> [[SRC1:%.*]]) { @@ -194,3 +209,5 @@ define i8 @should_not_scalarize_scalar() { %1 = trunc i32 4 to i8 ret i8 %1 } + +; CHECK: [[META0]] = !{i32 0} \ No newline at end of file diff --git a/IGC/Compiler/tests/ScalarizeFunction/scalarize-comp-instruction-typed-pointers.ll b/IGC/Compiler/tests/ScalarizeFunction/scalarize-comp-instruction-typed-pointers.ll index 42b7e166eeef..cceafd2fa6bf 100644 --- a/IGC/Compiler/tests/ScalarizeFunction/scalarize-comp-instruction-typed-pointers.ll +++ b/IGC/Compiler/tests/ScalarizeFunction/scalarize-comp-instruction-typed-pointers.ll @@ -31,6 +31,23 @@ define <2 x i1> @basic(<2 x i32> %src1, <2 x i32> %src2) { ret <2 x i1> %1 } +define <2 x i1> @should_preserve_metadata(<2 x i32> %src1, <2 x i32> %src2) { +; CHECK-LABEL: define <2 x i1> @should_preserve_metadata( +; CHECK-SAME: <2 x i32> [[SRC1:%.*]], <2 x i32> [[SRC2:%.*]]) { +; CHECK-NEXT: [[SRC2_SCALAR:%.*]] = extractelement <2 x i32> [[SRC2]], i32 0 +; CHECK-NEXT: [[SRC2_SCALAR2:%.*]] = extractelement <2 x i32> [[SRC2]], i32 1 +; CHECK-NEXT: [[SRC1_SCALAR:%.*]] = extractelement <2 x i32> [[SRC1]], i32 0 +; CHECK-NEXT: [[SRC1_SCALAR1:%.*]] = extractelement <2 x i32> [[SRC1]], i32 1 +; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[SRC1_SCALAR]], [[SRC2_SCALAR]], !any_metadata [[META0:![0-9]+]] +; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[SRC1_SCALAR1]], [[SRC2_SCALAR2]], !any_metadata [[META0]] +; CHECK-NEXT: [[DOTASSEMBLED_VECT:%.*]] = insertelement <2 x i1> undef, i1 [[TMP1]], i32 0 +; CHECK-NEXT: [[DOTASSEMBLED_VECT3:%.*]] = insertelement <2 x i1> [[DOTASSEMBLED_VECT]], i1 [[TMP2]], i32 1 +; CHECK-NEXT: ret <2 x i1> [[DOTASSEMBLED_VECT3]] +; + %1 = icmp eq <2 x i32> %src1, %src2, !any_metadata !{i32 0} + ret <2 x i1> %1 +} + define <2 x i1> @should_work_with_different_instruction_type(<2 x float> %src1, <2 x float> %src2) { ; CHECK-LABEL: define <2 x i1> @should_work_with_different_instruction_type( ; CHECK-SAME: <2 x float> [[SRC1:%.*]], <2 x float> [[SRC2:%.*]]) { @@ -212,3 +229,5 @@ define <2 x i1> @should_not_scalarize_two_constants() { %1 = icmp eq <2 x i32> , ret <2 x i1> %1 } + +; CHECK: [[META0]] = !{i32 0} \ No newline at end of file diff --git a/IGC/Compiler/tests/ScalarizeFunction/scalarize-comp-instruction.ll b/IGC/Compiler/tests/ScalarizeFunction/scalarize-comp-instruction.ll index afb0ecf183a9..ea8d6d3b3e29 100644 --- a/IGC/Compiler/tests/ScalarizeFunction/scalarize-comp-instruction.ll +++ b/IGC/Compiler/tests/ScalarizeFunction/scalarize-comp-instruction.ll @@ -32,6 +32,23 @@ define <2 x i1> @basic(<2 x i32> %src1, <2 x i32> %src2) { ret <2 x i1> %1 } +define <2 x i1> @should_preserve_metadata(<2 x i32> %src1, <2 x i32> %src2) { +; CHECK-LABEL: define <2 x i1> @should_preserve_metadata( +; CHECK-SAME: <2 x i32> [[SRC1:%.*]], <2 x i32> [[SRC2:%.*]]) { +; CHECK-NEXT: [[SRC2_SCALAR:%.*]] = extractelement <2 x i32> [[SRC2]], i32 0 +; CHECK-NEXT: [[SRC2_SCALAR2:%.*]] = extractelement <2 x i32> [[SRC2]], i32 1 +; CHECK-NEXT: [[SRC1_SCALAR:%.*]] = extractelement <2 x i32> [[SRC1]], i32 0 +; CHECK-NEXT: [[SRC1_SCALAR1:%.*]] = extractelement <2 x i32> [[SRC1]], i32 1 +; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[SRC1_SCALAR]], [[SRC2_SCALAR]], !any_metadata [[META0:![0-9]+]] +; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[SRC1_SCALAR1]], [[SRC2_SCALAR2]], !any_metadata [[META0]] +; CHECK-NEXT: [[DOTASSEMBLED_VECT:%.*]] = insertelement <2 x i1> undef, i1 [[TMP1]], i32 0 +; CHECK-NEXT: [[DOTASSEMBLED_VECT3:%.*]] = insertelement <2 x i1> [[DOTASSEMBLED_VECT]], i1 [[TMP2]], i32 1 +; CHECK-NEXT: ret <2 x i1> [[DOTASSEMBLED_VECT3]] +; + %1 = icmp eq <2 x i32> %src1, %src2, !any_metadata !{i32 0} + ret <2 x i1> %1 +} + define <2 x i1> @should_work_with_different_instruction_type(<2 x float> %src1, <2 x float> %src2) { ; CHECK-LABEL: define <2 x i1> @should_work_with_different_instruction_type( ; CHECK-SAME: <2 x float> [[SRC1:%.*]], <2 x float> [[SRC2:%.*]]) { @@ -214,3 +231,5 @@ define <2 x i1> @should_not_scalarize_two_constants() { %1 = icmp eq <2 x i32> , ret <2 x i1> %1 } + +; CHECK: [[META0]] = !{i32 0} \ No newline at end of file diff --git a/IGC/Compiler/tests/ScalarizeFunction/scalarize-getelementptr-instruction-typed-pointers.ll b/IGC/Compiler/tests/ScalarizeFunction/scalarize-getelementptr-instruction-typed-pointers.ll index c57b0533194a..98f7a51d5042 100644 --- a/IGC/Compiler/tests/ScalarizeFunction/scalarize-getelementptr-instruction-typed-pointers.ll +++ b/IGC/Compiler/tests/ScalarizeFunction/scalarize-getelementptr-instruction-typed-pointers.ll @@ -38,6 +38,30 @@ define double @basic(<2 x double*> %pointers) { ret double %return } +define double @should_preserve_metadata(<2 x double*> %pointers) { +; CHECK-LABEL: define double @should_preserve_metadata( +; CHECK-SAME: <2 x double*> [[POINTERS:%.*]]) { +; CHECK-NEXT: [[POINTERS_SCALAR:%.*]] = extractelement <2 x double*> [[POINTERS]], i32 0 +; CHECK-NEXT: [[POINTERS_SCALAR1:%.*]] = extractelement <2 x double*> [[POINTERS]], i32 1 +; CHECK-NEXT: [[POINTER_TO_DOUBLE2:%.*]] = getelementptr double, double* [[POINTERS_SCALAR]], i32 1, !any_metadata [[META0:![0-9]+]] +; CHECK-NEXT: [[POINTER_TO_DOUBLE_ASSEMBLED_VECT:%.*]] = insertelement <2 x double*> undef, double* [[POINTER_TO_DOUBLE2]], i32 0 +; CHECK-NEXT: [[POINTER_TO_DOUBLE3:%.*]] = getelementptr double, double* [[POINTERS_SCALAR1]], i32 1, !any_metadata [[META0]] +; CHECK-NEXT: [[POINTER_TO_DOUBLE_ASSEMBLED_VECT4:%.*]] = insertelement <2 x double*> [[POINTER_TO_DOUBLE_ASSEMBLED_VECT]], double* [[POINTER_TO_DOUBLE3]], i32 1 +; CHECK-NEXT: [[VAL0:%.*]] = load double, double* [[POINTER_TO_DOUBLE2]], align 8 +; CHECK-NEXT: [[VAL1:%.*]] = load double, double* [[POINTER_TO_DOUBLE3]], align 8 +; CHECK-NEXT: [[RETURN:%.*]] = fadd double [[VAL0]], [[VAL1]] +; CHECK-NEXT: ret double [[RETURN]] +; + %pointer_to_double = getelementptr double, <2 x double*> %pointers, i32 1, !any_metadata !{i32 0} + + %ptr0 = extractelement <2 x double*> %pointer_to_double, i32 0 + %ptr1 = extractelement <2 x double*> %pointer_to_double, i32 1 + %val0 = load double, double* %ptr0 + %val1 = load double, double* %ptr1 + %return = fadd double %val0, %val1 + ret double %return +} + define double @should_work_with_vector_of_indices(<2 x double*> %pointers) { ; CHECK-LABEL: define double @should_work_with_vector_of_indices( ; CHECK-SAME: <2 x double*> [[POINTERS:%.*]]) { @@ -187,4 +211,6 @@ define i64 @should_scalarize_only_vectors(%some_type* %pointer) { %val1 = extractvalue %some_type %val, 0 %return = add i64 %val0, %val1 ret i64 %return -} \ No newline at end of file +} + +; CHECK: [[META0]] = !{i32 0} \ No newline at end of file diff --git a/IGC/Compiler/tests/ScalarizeFunction/scalarize-getelementptr-instruction.ll b/IGC/Compiler/tests/ScalarizeFunction/scalarize-getelementptr-instruction.ll index 7d064bcc58ce..abbfe5439eb2 100644 --- a/IGC/Compiler/tests/ScalarizeFunction/scalarize-getelementptr-instruction.ll +++ b/IGC/Compiler/tests/ScalarizeFunction/scalarize-getelementptr-instruction.ll @@ -27,6 +27,17 @@ define double @basic(<2 x ptr> %pointers) { ret double %return } +define double @should_preserve_metadata(<2 x ptr> %pointers) { + %pointer_to_double = getelementptr double, <2 x ptr> %pointers, i32 1, !any_metadata !{i32 0} + + %ptr0 = extractelement <2 x ptr> %pointer_to_double, i32 0 + %ptr1 = extractelement <2 x ptr> %pointer_to_double, i32 1 + %val0 = load double, ptr %ptr0 + %val1 = load double, ptr %ptr1 + %return = fadd double %val0, %val1 + ret double %return +} + define double @should_work_with_vector_of_indices(<2 x ptr> %pointers) { %pointers_to_double = getelementptr double, <2 x ptr> %pointers, <2 x i32> diff --git a/IGC/Compiler/tests/ScalarizeFunction/scalarize-phi-instruction-typed-pointers.ll b/IGC/Compiler/tests/ScalarizeFunction/scalarize-phi-instruction-typed-pointers.ll index 93fa0c344df4..9762aeb5a98b 100644 --- a/IGC/Compiler/tests/ScalarizeFunction/scalarize-phi-instruction-typed-pointers.ll +++ b/IGC/Compiler/tests/ScalarizeFunction/scalarize-phi-instruction-typed-pointers.ll @@ -45,6 +45,37 @@ exit: ret <2 x i32> %result } +define <2 x i32> @should_preserve_metadata(i1 %switch, <2 x i32> %src1, <2 x i32> %src2) { +; CHECK-LABEL: define <2 x i32> @should_preserve_metadata( +; CHECK-SAME: i1 [[SWITCH:%.*]], <2 x i32> [[SRC1:%.*]], <2 x i32> [[SRC2:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: [[SRC2_SCALAR:%.*]] = extractelement <2 x i32> [[SRC2]], i32 0 +; CHECK-NEXT: [[SRC2_SCALAR4:%.*]] = extractelement <2 x i32> [[SRC2]], i32 1 +; CHECK-NEXT: [[SRC1_SCALAR:%.*]] = extractelement <2 x i32> [[SRC1]], i32 0 +; CHECK-NEXT: [[SRC1_SCALAR3:%.*]] = extractelement <2 x i32> [[SRC1]], i32 1 +; CHECK-NEXT: br i1 [[SWITCH]], label %[[FIRST:.*]], label %[[SECOND:.*]] +; CHECK: [[FIRST]]: +; CHECK-NEXT: br label %[[EXIT:.*]] +; CHECK: [[SECOND]]: +; CHECK-NEXT: br label %[[EXIT]] +; CHECK: [[EXIT]]: +; CHECK-NEXT: [[RESULT1:%.*]] = phi i32 [ [[SRC1_SCALAR]], %[[FIRST]] ], [ [[SRC2_SCALAR]], %[[SECOND]] ], !any_metadata [[META0:![0-9]+]] +; CHECK-NEXT: [[RESULT2:%.*]] = phi i32 [ [[SRC1_SCALAR3]], %[[FIRST]] ], [ [[SRC2_SCALAR4]], %[[SECOND]] ], !any_metadata [[META0]] +; CHECK-NEXT: [[RESULT_ASSEMBLED_VECT:%.*]] = insertelement <2 x i32> undef, i32 [[RESULT1]], i32 0 +; CHECK-NEXT: [[RESULT_ASSEMBLED_VECT5:%.*]] = insertelement <2 x i32> [[RESULT_ASSEMBLED_VECT]], i32 [[RESULT2]], i32 1 +; CHECK-NEXT: ret <2 x i32> [[RESULT_ASSEMBLED_VECT5]] +; +entry: + br i1 %switch, label %first, label %second +first: + br label %exit +second: + br label %exit +exit: + %result = phi <2 x i32> [ %src1, %first], [ %src2, %second], !any_metadata !{i32 0} + ret <2 x i32> %result +} + define <2 x float> @should_work_with_different_value_type(i1 %switch, <2 x float> %src1, <2 x float> %src2) { ; CHECK-LABEL: define <2 x float> @should_work_with_different_value_type( ; CHECK-SAME: i1 [[SWITCH:%.*]], <2 x float> [[SRC1:%.*]], <2 x float> [[SRC2:%.*]]) { @@ -583,3 +614,5 @@ declare void @llvm.genx.GenISA.simdMediaBlockWrite.v16i16(i32, i32, i32, i32, <1 declare void @llvm.genx.GenISA.LSC2DBlockWrite.p0i32(i64, i32, i32, i32, i32, i32, i32, i32, i32, i32, i1, i1, i32, <8 x i32>) declare void @llvm.genx.GenISA.LSC2DBlockWriteAddrPayload.p0i32.v16i16(i32*, i32, i32, i32, i32, i32, i32, i1, i1, i32, <16 x i16>) declare spir_func <8 x i32> @do_math_v8i32_v8i32(<8 x i32>) #1 + +; CHECK: [[META0]] = !{i32 0} \ No newline at end of file diff --git a/IGC/Compiler/tests/ScalarizeFunction/scalarize-phi-instruction.ll b/IGC/Compiler/tests/ScalarizeFunction/scalarize-phi-instruction.ll index b8160ef9fadc..03e38038b2c3 100644 --- a/IGC/Compiler/tests/ScalarizeFunction/scalarize-phi-instruction.ll +++ b/IGC/Compiler/tests/ScalarizeFunction/scalarize-phi-instruction.ll @@ -46,6 +46,37 @@ exit: ret <2 x i32> %result } +define <2 x i32> @should_preserve_metadata(i1 %switch, <2 x i32> %src1, <2 x i32> %src2) { +; CHECK-LABEL: define <2 x i32> @should_preserve_metadata( +; CHECK-SAME: i1 [[SWITCH:%.*]], <2 x i32> [[SRC1:%.*]], <2 x i32> [[SRC2:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: [[SRC2_SCALAR:%.*]] = extractelement <2 x i32> [[SRC2]], i32 0 +; CHECK-NEXT: [[SRC2_SCALAR4:%.*]] = extractelement <2 x i32> [[SRC2]], i32 1 +; CHECK-NEXT: [[SRC1_SCALAR:%.*]] = extractelement <2 x i32> [[SRC1]], i32 0 +; CHECK-NEXT: [[SRC1_SCALAR3:%.*]] = extractelement <2 x i32> [[SRC1]], i32 1 +; CHECK-NEXT: br i1 [[SWITCH]], label %[[FIRST:.*]], label %[[SECOND:.*]] +; CHECK: [[FIRST]]: +; CHECK-NEXT: br label %[[EXIT:.*]] +; CHECK: [[SECOND]]: +; CHECK-NEXT: br label %[[EXIT]] +; CHECK: [[EXIT]]: +; CHECK-NEXT: [[RESULT1:%.*]] = phi i32 [ [[SRC1_SCALAR]], %[[FIRST]] ], [ [[SRC2_SCALAR]], %[[SECOND]] ], !any_metadata [[META0:![0-9]+]] +; CHECK-NEXT: [[RESULT2:%.*]] = phi i32 [ [[SRC1_SCALAR3]], %[[FIRST]] ], [ [[SRC2_SCALAR4]], %[[SECOND]] ], !any_metadata [[META0]] +; CHECK-NEXT: [[RESULT_ASSEMBLED_VECT:%.*]] = insertelement <2 x i32> undef, i32 [[RESULT1]], i32 0 +; CHECK-NEXT: [[RESULT_ASSEMBLED_VECT5:%.*]] = insertelement <2 x i32> [[RESULT_ASSEMBLED_VECT]], i32 [[RESULT2]], i32 1 +; CHECK-NEXT: ret <2 x i32> [[RESULT_ASSEMBLED_VECT5]] +; +entry: + br i1 %switch, label %first, label %second +first: + br label %exit +second: + br label %exit +exit: + %result = phi <2 x i32> [ %src1, %first], [ %src2, %second], !any_metadata !{i32 0} + ret <2 x i32> %result +} + define <2 x float> @should_work_with_different_value_type(i1 %switch, <2 x float> %src1, <2 x float> %src2) { ; CHECK-LABEL: define <2 x float> @should_work_with_different_value_type( ; CHECK-SAME: i1 [[SWITCH:%.*]], <2 x float> [[SRC1:%.*]], <2 x float> [[SRC2:%.*]]) { @@ -585,3 +616,5 @@ declare void @llvm.genx.GenISA.simdMediaBlockWrite.v16i16(i32, i32, i32, i32, <1 declare void @llvm.genx.GenISA.LSC2DBlockWrite.p0i32(i64, i32, i32, i32, i32, i32, i32, i32, i32, i32, i1, i1, i32, <8 x i32>) declare void @llvm.genx.GenISA.LSC2DBlockWriteAddrPayload.p0i32.v16i16(ptr, i32, i32, i32, i32, i32, i32, i1, i1, i32, <16 x i16>) declare spir_func <8 x i32> @do_math_v8i32_v8i32(<8 x i32>) #1 + +; CHECK: [[META0]] = !{i32 0} \ No newline at end of file diff --git a/IGC/Compiler/tests/ScalarizeFunction/scalarize-select-instruction-typed-pointers.ll b/IGC/Compiler/tests/ScalarizeFunction/scalarize-select-instruction-typed-pointers.ll index 27cf64df5c8f..784161211eee 100644 --- a/IGC/Compiler/tests/ScalarizeFunction/scalarize-select-instruction-typed-pointers.ll +++ b/IGC/Compiler/tests/ScalarizeFunction/scalarize-select-instruction-typed-pointers.ll @@ -33,6 +33,25 @@ define <2 x i32> @basic(<2 x i1> %switch, <2 x i32> %src1, <2 x i32> %src2) { ret <2 x i32> %result } +define <2 x i32> @should_preserve_metadata(<2 x i1> %switch, <2 x i32> %src1, <2 x i32> %src2) { +; CHECK-LABEL: define <2 x i32> @should_preserve_metadata( +; CHECK-SAME: <2 x i1> [[SWITCH:%.*]], <2 x i32> [[SRC1:%.*]], <2 x i32> [[SRC2:%.*]]) { +; CHECK-NEXT: [[SWITCH_SCALAR:%.*]] = extractelement <2 x i1> [[SWITCH]], i32 0 +; CHECK-NEXT: [[SWITCH_SCALAR3:%.*]] = extractelement <2 x i1> [[SWITCH]], i32 1 +; CHECK-NEXT: [[SRC2_SCALAR:%.*]] = extractelement <2 x i32> [[SRC2]], i32 0 +; CHECK-NEXT: [[SRC2_SCALAR2:%.*]] = extractelement <2 x i32> [[SRC2]], i32 1 +; CHECK-NEXT: [[SRC1_SCALAR:%.*]] = extractelement <2 x i32> [[SRC1]], i32 0 +; CHECK-NEXT: [[SRC1_SCALAR1:%.*]] = extractelement <2 x i32> [[SRC1]], i32 1 +; CHECK-NEXT: [[RESULT4:%.*]] = select i1 [[SWITCH_SCALAR]], i32 [[SRC1_SCALAR]], i32 [[SRC2_SCALAR]], !any_metadata [[META0:![0-9]+]] +; CHECK-NEXT: [[RESULT5:%.*]] = select i1 [[SWITCH_SCALAR3]], i32 [[SRC1_SCALAR1]], i32 [[SRC2_SCALAR2]], !any_metadata [[META0]] +; CHECK-NEXT: [[RESULT_ASSEMBLED_VECT:%.*]] = insertelement <2 x i32> undef, i32 [[RESULT4]], i32 0 +; CHECK-NEXT: [[RESULT_ASSEMBLED_VECT6:%.*]] = insertelement <2 x i32> [[RESULT_ASSEMBLED_VECT]], i32 [[RESULT5]], i32 1 +; CHECK-NEXT: ret <2 x i32> [[RESULT_ASSEMBLED_VECT6]] +; + %result = select <2 x i1> %switch, <2 x i32> %src1, <2 x i32> %src2, !any_metadata !{i32 0} + ret <2 x i32> %result +} + define <2 x float> @should_work_with_different_value_type(<2 x i1> %switch, <2 x float> %src1, <2 x float> %src2) { ; CHECK-LABEL: define <2 x float> @should_work_with_different_value_type( ; CHECK-SAME: <2 x i1> [[SWITCH:%.*]], <2 x float> [[SRC1:%.*]], <2 x float> [[SRC2:%.*]]) { @@ -217,3 +236,5 @@ define i32 @should_not_scalarize_scalar(i1 %switch, i32 %src1, i32 %src2) { %result = select i1 %switch, i32 %src1, i32 %src2 ret i32 %result } + +; CHECK: [[META0]] = !{i32 0} \ No newline at end of file diff --git a/IGC/Compiler/tests/ScalarizeFunction/scalarize-select-instruction.ll b/IGC/Compiler/tests/ScalarizeFunction/scalarize-select-instruction.ll index ed72478361fa..b559d396ca53 100644 --- a/IGC/Compiler/tests/ScalarizeFunction/scalarize-select-instruction.ll +++ b/IGC/Compiler/tests/ScalarizeFunction/scalarize-select-instruction.ll @@ -34,6 +34,25 @@ define <2 x i32> @basic(<2 x i1> %switch, <2 x i32> %src1, <2 x i32> %src2) { ret <2 x i32> %result } +define <2 x i32> @should_preserve_metadata(<2 x i1> %switch, <2 x i32> %src1, <2 x i32> %src2) { +; CHECK-LABEL: define <2 x i32> @should_preserve_metadata( +; CHECK-SAME: <2 x i1> [[SWITCH:%.*]], <2 x i32> [[SRC1:%.*]], <2 x i32> [[SRC2:%.*]]) { +; CHECK-NEXT: [[SWITCH_SCALAR:%.*]] = extractelement <2 x i1> [[SWITCH]], i32 0 +; CHECK-NEXT: [[SWITCH_SCALAR3:%.*]] = extractelement <2 x i1> [[SWITCH]], i32 1 +; CHECK-NEXT: [[SRC2_SCALAR:%.*]] = extractelement <2 x i32> [[SRC2]], i32 0 +; CHECK-NEXT: [[SRC2_SCALAR2:%.*]] = extractelement <2 x i32> [[SRC2]], i32 1 +; CHECK-NEXT: [[SRC1_SCALAR:%.*]] = extractelement <2 x i32> [[SRC1]], i32 0 +; CHECK-NEXT: [[SRC1_SCALAR1:%.*]] = extractelement <2 x i32> [[SRC1]], i32 1 +; CHECK-NEXT: [[RESULT4:%.*]] = select i1 [[SWITCH_SCALAR]], i32 [[SRC1_SCALAR]], i32 [[SRC2_SCALAR]], !any_metadata [[META0:![0-9]+]] +; CHECK-NEXT: [[RESULT5:%.*]] = select i1 [[SWITCH_SCALAR3]], i32 [[SRC1_SCALAR1]], i32 [[SRC2_SCALAR2]], !any_metadata [[META0]] +; CHECK-NEXT: [[RESULT_ASSEMBLED_VECT:%.*]] = insertelement <2 x i32> undef, i32 [[RESULT4]], i32 0 +; CHECK-NEXT: [[RESULT_ASSEMBLED_VECT6:%.*]] = insertelement <2 x i32> [[RESULT_ASSEMBLED_VECT]], i32 [[RESULT5]], i32 1 +; CHECK-NEXT: ret <2 x i32> [[RESULT_ASSEMBLED_VECT6]] +; + %result = select <2 x i1> %switch, <2 x i32> %src1, <2 x i32> %src2, !any_metadata !{i32 0} + ret <2 x i32> %result +} + define <2 x float> @should_work_with_different_value_type(<2 x i1> %switch, <2 x float> %src1, <2 x float> %src2) { ; CHECK-LABEL: define <2 x float> @should_work_with_different_value_type( ; CHECK-SAME: <2 x i1> [[SWITCH:%.*]], <2 x float> [[SRC1:%.*]], <2 x float> [[SRC2:%.*]]) { @@ -219,3 +238,5 @@ define i32 @should_not_scalarize_scalar(i1 %switch, i32 %src1, i32 %src2) { %result = select i1 %switch, i32 %src1, i32 %src2 ret i32 %result } + +; CHECK: [[META0]] = !{i32 0} \ No newline at end of file diff --git a/IGC/Compiler/tests/ScalarizeFunction/scalarize-unary-instruction-typed-pointers.ll b/IGC/Compiler/tests/ScalarizeFunction/scalarize-unary-instruction-typed-pointers.ll index 3b33266b812b..267ab342a27d 100644 --- a/IGC/Compiler/tests/ScalarizeFunction/scalarize-unary-instruction-typed-pointers.ll +++ b/IGC/Compiler/tests/ScalarizeFunction/scalarize-unary-instruction-typed-pointers.ll @@ -33,6 +33,25 @@ define spir_kernel void @basic(<2 x float> %src1) { ret void } +define spir_kernel void @should_preserve_metadata(<2 x float> %src1) { +; CHECK-LABEL: define spir_kernel void @should_preserve_metadata( +; CHECK-SAME: <2 x float> [[SRC1:%.*]]) { +; CHECK-NEXT: [[SRC1_SCALAR:%.*]] = extractelement <2 x float> [[SRC1]], i32 0 +; CHECK-NEXT: [[SRC1_SCALAR1:%.*]] = extractelement <2 x float> [[SRC1]], i32 1 +; CHECK-NEXT: [[TMP1:%.*]] = alloca <2 x float>, align 8 +; CHECK-NEXT: [[TMP2:%.*]] = fneg float [[SRC1_SCALAR]], !any_metadata [[META0:![0-9]+]] +; CHECK-NEXT: [[TMP3:%.*]] = fneg float [[SRC1_SCALAR1]], !any_metadata [[META0]] +; CHECK-NEXT: [[DOTASSEMBLED_VECT:%.*]] = insertelement <2 x float> undef, float [[TMP2]], i32 0 +; CHECK-NEXT: [[DOTASSEMBLED_VECT2:%.*]] = insertelement <2 x float> [[DOTASSEMBLED_VECT]], float [[TMP3]], i32 1 +; CHECK-NEXT: store <2 x float> [[DOTASSEMBLED_VECT2]], <2 x float>* [[TMP1]], align 8 +; CHECK-NEXT: ret void +; + %1 = alloca <2 x float> + %2 = fneg <2 x float> %src1, !any_metadata !{i32 0} + store <2 x float> %2, <2 x float>* %1 + ret void +} + define spir_kernel void @should_work_with_different_type(<2 x double> %src1) { ; CHECK-LABEL: define spir_kernel void @should_work_with_different_type( ; CHECK-SAME: <2 x double> [[SRC1:%.*]]) { @@ -184,4 +203,6 @@ define void @test_fneg_optnone(<4 x float> %src, <3 x float> addrspace(1)* %out) ret void } -attributes #0 = { noinline optnone } \ No newline at end of file +attributes #0 = { noinline optnone } + +; CHECK: [[META0]] = !{i32 0} \ No newline at end of file diff --git a/IGC/Compiler/tests/ScalarizeFunction/scalarize-unary-instruction.ll b/IGC/Compiler/tests/ScalarizeFunction/scalarize-unary-instruction.ll index c8b0720820e6..f8c931e95806 100644 --- a/IGC/Compiler/tests/ScalarizeFunction/scalarize-unary-instruction.ll +++ b/IGC/Compiler/tests/ScalarizeFunction/scalarize-unary-instruction.ll @@ -34,6 +34,25 @@ define spir_kernel void @basic(<2 x float> %src1) { ret void } +define spir_kernel void @should_preserve_metadata(<2 x float> %src1) { +; CHECK-LABEL: define spir_kernel void @should_preserve_metadata( +; CHECK-SAME: <2 x float> [[SRC1:%.*]]) { +; CHECK-NEXT: [[SRC1_SCALAR:%.*]] = extractelement <2 x float> [[SRC1]], i32 0 +; CHECK-NEXT: [[SRC1_SCALAR1:%.*]] = extractelement <2 x float> [[SRC1]], i32 1 +; CHECK-NEXT: [[TMP1:%.*]] = alloca <2 x float>, align 8 +; CHECK-NEXT: [[TMP2:%.*]] = fneg float [[SRC1_SCALAR]], !any_metadata [[META0:![0-9]+]] +; CHECK-NEXT: [[TMP3:%.*]] = fneg float [[SRC1_SCALAR1]], !any_metadata [[META0]] +; CHECK-NEXT: [[DOTASSEMBLED_VECT:%.*]] = insertelement <2 x float> undef, float [[TMP2]], i32 0 +; CHECK-NEXT: [[DOTASSEMBLED_VECT2:%.*]] = insertelement <2 x float> [[DOTASSEMBLED_VECT]], float [[TMP3]], i32 1 +; CHECK-NEXT: store <2 x float> [[DOTASSEMBLED_VECT2]], ptr [[TMP1]], align 8 +; CHECK-NEXT: ret void +; + %1 = alloca <2 x float> + %2 = fneg <2 x float> %src1, !any_metadata !{i32 0} + store <2 x float> %2, ptr %1 + ret void +} + define spir_kernel void @should_work_with_different_type(<2 x double> %src1) { ; CHECK-LABEL: define spir_kernel void @should_work_with_different_type( ; CHECK-SAME: <2 x double> [[SRC1:%.*]]) { @@ -192,3 +211,5 @@ define void @test_fneg_optnone(<4 x float> %src, ptr addrspace(1) %out) #0 { } attributes #0 = { noinline optnone } + +; CHECK: [[META0]] = !{i32 0} \ No newline at end of file