@@ -165,7 +165,8 @@ ValidateSignatureAccess(Instruction *I, DxilSignature &Sig, Value *SigId,
165165
166166static DxilResourceProperties GetResourceFromHandle (Value *Handle,
167167 ValidationContext &ValCtx) {
168- if (!isa<CallInst>(Handle)) {
168+ CallInst *HandleCall = dyn_cast<CallInst>(Handle);
169+ if (!HandleCall) {
169170 if (Instruction *I = dyn_cast<Instruction>(Handle))
170171 ValCtx.EmitInstrError (I, ValidationRule::InstrHandleNotFromCreateHandle);
171172 else
@@ -175,10 +176,13 @@ static DxilResourceProperties GetResourceFromHandle(Value *Handle,
175176 }
176177
177178 DxilResourceProperties RP = ValCtx.GetResourceFromVal (Handle);
178- if (RP.getResourceClass () == DXIL::ResourceClass::Invalid) {
179+ if (RP.getResourceClass () == DXIL::ResourceClass::Invalid)
179180 ValCtx.EmitInstrError (cast<CallInst>(Handle),
180181 ValidationRule::InstrHandleNotFromCreateHandle);
181- }
182+ if (RP.Basic .IsReorderCoherent &&
183+ !ValCtx.DxilMod .GetShaderModel ()->IsSM69Plus ())
184+ ValCtx.EmitInstrError (HandleCall,
185+ ValidationRule::InstrReorderCoherentRequiresSM69);
182186
183187 return RP;
184188}
@@ -1229,6 +1233,32 @@ static void ValidateImmOperandsForOuterProdAcc(CallInst *CI,
12291233 {" MatrixLayout" });
12301234 return ;
12311235 }
1236+ ConstantInt *ML = cast<ConstantInt>(MatrixLayout);
1237+ uint64_t MLValue = ML->getLimitedValue ();
1238+ if (MLValue !=
1239+ static_cast <unsigned >(DXIL::LinalgMatrixLayout::OuterProductOptimal))
1240+ ValCtx.EmitInstrFormatError (
1241+ CI,
1242+ ValidationRule::
1243+ InstrLinalgInvalidMatrixLayoutValueForOuterProductAccumulate,
1244+ {GetMatrixLayoutStr (MLValue),
1245+ GetMatrixLayoutStr (static_cast <unsigned >(
1246+ DXIL::LinalgMatrixLayout::OuterProductOptimal))});
1247+
1248+ llvm::Value *MatrixStride =
1249+ CI->getOperand (DXIL::OperandIndex::kOuterProdAccMatrixStride );
1250+ if (!llvm::isa<llvm::Constant>(MatrixStride)) {
1251+ ValCtx.EmitInstrError (
1252+ CI, ValidationRule::InstrLinalgMatrixStrideZeroForOptimalLayouts);
1253+ return ;
1254+ }
1255+ ConstantInt *MS = cast<ConstantInt>(MatrixStride);
1256+ uint64_t MSValue = MS->getLimitedValue ();
1257+ if (MSValue != 0 ) {
1258+ ValCtx.EmitInstrError (
1259+ CI, ValidationRule::InstrLinalgMatrixStrideZeroForOptimalLayouts);
1260+ return ;
1261+ }
12321262}
12331263
12341264// Validate the type-defined mask compared to the store value mask which
@@ -4182,6 +4212,9 @@ static void ValidateResourceOverlap(
41824212
41834213static void ValidateResource (hlsl::DxilResource &Res,
41844214 ValidationContext &ValCtx) {
4215+ if (Res.IsReorderCoherent () && !ValCtx.DxilMod .GetShaderModel ()->IsSM69Plus ())
4216+ ValCtx.EmitResourceError (&Res,
4217+ ValidationRule::InstrReorderCoherentRequiresSM69);
41854218 switch (Res.GetKind ()) {
41864219 case DXIL::ResourceKind::RawBuffer:
41874220 case DXIL::ResourceKind::TypedBuffer:
@@ -4413,10 +4446,13 @@ static void ValidateResources(ValidationContext &ValCtx) {
44134446 ValCtx.EmitResourceError (Uav.get (),
44144447 ValidationRule::SmCounterOnlyOnStructBuf);
44154448 }
4416- if (Uav->HasCounter () && Uav->IsGloballyCoherent ())
4417- ValCtx.EmitResourceFormatError (Uav.get (),
4418- ValidationRule::MetaGlcNotOnAppendConsume,
4419- {ValCtx.GetResourceName (Uav.get ())});
4449+ const bool UavIsCoherent =
4450+ Uav->IsGloballyCoherent () || Uav->IsReorderCoherent ();
4451+ if (Uav->HasCounter () && UavIsCoherent) {
4452+ StringRef Prefix = Uav->IsGloballyCoherent () ? " globally" : " reorder" ;
4453+ ValCtx.EmitResourceFormatError (
4454+ Uav.get (), ValidationRule::MetaCoherenceNotOnAppendConsume, {Prefix});
4455+ }
44204456
44214457 ValidateResource (*Uav, ValCtx);
44224458 ValidateResourceOverlap (*Uav, UavAllocator, ValCtx);
0 commit comments