@@ -2993,6 +2993,7 @@ void EmitPass::EmitInsertValueToStruct(InsertValueInst* inst)
2993
2993
CVariable* SrcV = GetSymbol(src0);
2994
2994
if (DstV != SrcV)
2995
2995
{
2996
+ m_encoder->Lifetime(VISAVarLifetime::LIFETIME_START, DstV);
2996
2997
// Only copy SrcV's elements that have been initialized already.
2997
2998
// For the example, DstV = %13, SrcV = %9;
2998
2999
// 'toBeCopied' will be field {0, 1}, not {0,1,2,3}.
@@ -3278,6 +3279,60 @@ void EmitPass::EmitExtractValueFromLayoutStruct(ExtractValueInst* EVI)
3278
3279
}
3279
3280
}
3280
3281
3282
+ void EmitPass::EmitSelectStruct(SelectInst* SI)
3283
+ {
3284
+ StructType* sTy = dyn_cast<StructType>(SI->getType());
3285
+ IGC_ASSERT_MESSAGE(sTy, "This method is only for structs");
3286
+
3287
+ const uint32_t nLanes = numLanes(m_currShader->m_SIMDSize);
3288
+
3289
+ auto* srcTrueV = SI->getTrueValue();
3290
+ auto* srcFalseV = SI->getFalseValue();
3291
+
3292
+ auto* srcTrueS = GetSymbol(srcTrueV);
3293
+ auto* srcFalseS = GetSymbol(srcFalseV);
3294
+ auto* destS = GetSymbol(SI);
3295
+ auto* cond = GetSymbol(SI->getCondition());
3296
+
3297
+ if (srcTrueS != destS && srcFalseS != destS)
3298
+ // if we aren't coalescing with any of the operands, emit lifetime start for the struct
3299
+ m_encoder->Lifetime(VISAVarLifetime::LIFETIME_START, destS);
3300
+
3301
+ auto iterator = {
3302
+ std::make_tuple(srcTrueV, srcTrueS, false),
3303
+ std::make_tuple(srcFalseV, srcFalseS, true)
3304
+ };
3305
+
3306
+ for (auto [srcV, srcS, inv] : iterator)
3307
+ {
3308
+ // For now, do not support uniform dst and non-uniform src
3309
+ IGC_ASSERT_MESSAGE(!srcS->IsUniform() || srcS->IsUniform() == destS->IsUniform(),
3310
+ "Can't select non-uniform value into a uniform struct!");
3311
+
3312
+ if (srcS == destS)
3313
+ continue;
3314
+
3315
+ SmallVector<std::vector<unsigned>> toBeCopied;
3316
+ getAllDefinedMembers(srcV, toBeCopied);
3317
+ for (const auto& II : toBeCopied)
3318
+ {
3319
+
3320
+ Type* ty;
3321
+ uint32_t byteOffset;
3322
+ getStructMemberByteOffsetAndType_1(m_DL, sTy, II, ty, byteOffset);
3323
+
3324
+ uint32_t d_off =
3325
+ byteOffset * (destS->IsUniform() ? 1 : nLanes);
3326
+ uint32_t s_off =
3327
+ byteOffset * (srcS->IsUniform() ? 1 : nLanes);
3328
+
3329
+ m_encoder->SetPredicate(cond);
3330
+ m_encoder->SetInversePredicate(inv);
3331
+ emitMayUnalignedVectorCopy(destS, d_off, srcS, s_off, ty);
3332
+ }
3333
+ }
3334
+ }
3335
+
3281
3336
void EmitPass::EmitAddPair(GenIntrinsicInst* GII, const SSource Sources[4], const DstModifier& DstMod) {
3282
3337
auto [L, H] = getPairOutput(GII);
3283
3338
CVariable* Lo = L ? GetSymbol(L) : nullptr;
@@ -5135,7 +5190,6 @@ void EmitPass::Select(const SSource sources[3], const DstModifier& modifier)
5135
5190
5136
5191
m_encoder->Select(flag, m_destination, src0, src1);
5137
5192
m_encoder->Push();
5138
-
5139
5193
}
5140
5194
5141
5195
void EmitPass::PredAdd(const SSource& pred, bool invert, const SSource sources[2], const DstModifier& modifier)
@@ -11706,6 +11760,9 @@ void EmitPass::EmitNoModifier(llvm::Instruction* inst)
11706
11760
case Instruction::ExtractValue:
11707
11761
EmitExtractValueFromStruct(cast<ExtractValueInst>(inst));
11708
11762
break;
11763
+ case Instruction::Select:
11764
+ EmitSelectStruct(cast<SelectInst>(inst));
11765
+ break;
11709
11766
case Instruction::Unreachable:
11710
11767
break;
11711
11768
default:
0 commit comments