The fix.
This commit is contained in:
Родитель
41a1ab10fc
Коммит
7c1f9f01e9
|
@ -67,7 +67,7 @@ ModulePass *createDxilLegalizeResources();
|
||||||
ModulePass *createDxilLegalizeEvalOperationsPass();
|
ModulePass *createDxilLegalizeEvalOperationsPass();
|
||||||
FunctionPass *createDxilLegalizeSampleOffsetPass();
|
FunctionPass *createDxilLegalizeSampleOffsetPass();
|
||||||
FunctionPass *createDxilSimpleGVNHoistPass();
|
FunctionPass *createDxilSimpleGVNHoistPass();
|
||||||
ModulePass *createFailUndefResourcePass();
|
ModulePass *createPoisonUndefResourcesPass();
|
||||||
FunctionPass *createSimplifyInstPass();
|
FunctionPass *createSimplifyInstPass();
|
||||||
ModulePass *createDxilTranslateRawBuffer();
|
ModulePass *createDxilTranslateRawBuffer();
|
||||||
ModulePass *createNoPausePassesPass();
|
ModulePass *createNoPausePassesPass();
|
||||||
|
@ -99,7 +99,7 @@ void initializeDxilLegalizeResourcesPass(llvm::PassRegistry&);
|
||||||
void initializeDxilLegalizeEvalOperationsPass(llvm::PassRegistry&);
|
void initializeDxilLegalizeEvalOperationsPass(llvm::PassRegistry&);
|
||||||
void initializeDxilLegalizeSampleOffsetPassPass(llvm::PassRegistry&);
|
void initializeDxilLegalizeSampleOffsetPassPass(llvm::PassRegistry&);
|
||||||
void initializeDxilSimpleGVNHoistPass(llvm::PassRegistry&);
|
void initializeDxilSimpleGVNHoistPass(llvm::PassRegistry&);
|
||||||
void initializeFailUndefResourcePass(llvm::PassRegistry&);
|
void initializePoisonUndefResourcesPass(llvm::PassRegistry&);
|
||||||
void initializeSimplifyInstPass(llvm::PassRegistry&);
|
void initializeSimplifyInstPass(llvm::PassRegistry&);
|
||||||
void initializeDxilTranslateRawBufferPass(llvm::PassRegistry&);
|
void initializeDxilTranslateRawBufferPass(llvm::PassRegistry&);
|
||||||
void initializeNoPausePassesPass(llvm::PassRegistry&);
|
void initializeNoPausePassesPass(llvm::PassRegistry&);
|
||||||
|
|
|
@ -110,7 +110,7 @@ HRESULT SetupRegistryPassForHLSL() {
|
||||||
initializeDynamicIndexingVectorToArrayPass(Registry);
|
initializeDynamicIndexingVectorToArrayPass(Registry);
|
||||||
initializeEarlyCSELegacyPassPass(Registry);
|
initializeEarlyCSELegacyPassPass(Registry);
|
||||||
initializeEliminateAvailableExternallyPass(Registry);
|
initializeEliminateAvailableExternallyPass(Registry);
|
||||||
initializeFailUndefResourcePass(Registry);
|
initializePoisonUndefResourcesPass(Registry);
|
||||||
initializeFloat2IntPass(Registry);
|
initializeFloat2IntPass(Registry);
|
||||||
initializeFunctionAttrsPass(Registry);
|
initializeFunctionAttrsPass(Registry);
|
||||||
initializeGVNPass(Registry);
|
initializeGVNPass(Registry);
|
||||||
|
|
|
@ -447,6 +447,8 @@ public:
|
||||||
m_bIsLib = DM.GetShaderModel()->IsLib();
|
m_bIsLib = DM.GetShaderModel()->IsLib();
|
||||||
m_bLegalizationFailed = false;
|
m_bLegalizationFailed = false;
|
||||||
|
|
||||||
|
FailOnPoisonResources();
|
||||||
|
|
||||||
bool bChanged = false;
|
bool bChanged = false;
|
||||||
unsigned numResources = DM.GetCBuffers().size() + DM.GetUAVs().size() +
|
unsigned numResources = DM.GetCBuffers().size() + DM.GetUAVs().size() +
|
||||||
DM.GetSRVs().size() + DM.GetSamplers().size();
|
DM.GetSRVs().size() + DM.GetSamplers().size();
|
||||||
|
@ -506,6 +508,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void FailOnPoisonResources();
|
||||||
bool RemovePhiOnResource();
|
bool RemovePhiOnResource();
|
||||||
void UpdateResourceSymbols();
|
void UpdateResourceSymbols();
|
||||||
void TranslateDxilResourceUses(DxilResourceBase &res);
|
void TranslateDxilResourceUses(DxilResourceBase &res);
|
||||||
|
@ -1690,6 +1693,23 @@ void UpdateStructTypeForLegacyLayoutOnDM(DxilModule &DM) {
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
void DxilLowerCreateHandleForLib::FailOnPoisonResources() {
|
||||||
|
// A previous pass replaced all undef resources with constant zero resources.
|
||||||
|
// If those made it here, the program is malformed.
|
||||||
|
for (Function &Func : this->m_DM->GetModule()->functions()) {
|
||||||
|
hlsl::OP::OpCodeClass OpcodeClass;
|
||||||
|
if (m_DM->GetOP()->GetOpCodeClass(&Func, OpcodeClass)
|
||||||
|
&& OpcodeClass == OP::OpCodeClass::CreateHandleForLib) {
|
||||||
|
Type *ResTy = Func.getFunctionType()->getParamType(
|
||||||
|
DXIL::OperandIndex::kCreateHandleForLibResOpIdx);
|
||||||
|
Constant *PoisonRes = ConstantAggregateZero::get(ResTy);
|
||||||
|
for (User *PoisonUser : PoisonRes->users())
|
||||||
|
if (Instruction *PoisonUserInst = dyn_cast<Instruction>(PoisonUser))
|
||||||
|
dxilutil::EmitResMappingError(PoisonUserInst);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void DxilLowerCreateHandleForLib::UpdateStructTypeForLegacyLayout() {
|
void DxilLowerCreateHandleForLib::UpdateStructTypeForLegacyLayout() {
|
||||||
UpdateStructTypeForLegacyLayoutOnDM(*m_DM);
|
UpdateStructTypeForLegacyLayoutOnDM(*m_DM);
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,40 +36,44 @@ using namespace llvm;
|
||||||
using namespace hlsl;
|
using namespace hlsl;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
class FailUndefResource : public ModulePass {
|
class PoisonUndefResources : public ModulePass {
|
||||||
public:
|
public:
|
||||||
static char ID;
|
static char ID;
|
||||||
|
|
||||||
explicit FailUndefResource() : ModulePass(ID) {
|
explicit PoisonUndefResources() : ModulePass(ID) {
|
||||||
initializeScalarizerPass(*PassRegistry::getPassRegistry());
|
initializeScalarizerPass(*PassRegistry::getPassRegistry());
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *getPassName() const override { return "Fail on undef resource use"; }
|
const char *getPassName() const override { return "Poison undef resources"; }
|
||||||
|
|
||||||
bool runOnModule(Module &M) override;
|
bool runOnModule(Module &M) override;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
char FailUndefResource::ID = 0;
|
char PoisonUndefResources::ID = 0;
|
||||||
|
|
||||||
ModulePass *llvm::createFailUndefResourcePass() { return new FailUndefResource(); }
|
ModulePass *llvm::createPoisonUndefResourcesPass() { return new PoisonUndefResources(); }
|
||||||
|
|
||||||
INITIALIZE_PASS(FailUndefResource, "fail-undef-resource", "Fail on undef resource use", false, false)
|
INITIALIZE_PASS(PoisonUndefResources, "poison-undef-resource", "Poison undef resources", false, false)
|
||||||
|
|
||||||
bool FailUndefResource::runOnModule(Module &M) {
|
bool PoisonUndefResources::runOnModule(Module &M) {
|
||||||
// Undef resources may be removed on simplify due to the interpretation
|
// Undef resources typically indicate uninitialized locals being used
|
||||||
// of undef that any value could be substituted for identical meaning.
|
// in some code path, which we should catch and report. However, some
|
||||||
// However, these likely indicate uninitialized locals being used in
|
// code patterns in large shaders cause dead undef resources to momentarily,
|
||||||
// some code path, which we should catch and report.
|
// which is not an error. We must wait until cleanup passes
|
||||||
|
// have run to know whether we must produce an error.
|
||||||
|
// However, we can't leave the undef values in because they could eliminated,
|
||||||
|
// such as by reading from resources seen in a code path that was not taken.
|
||||||
|
// We avoid the problem by replacing undef values by another poison
|
||||||
|
// value that we can identify later.
|
||||||
for (auto &F : M.functions()) {
|
for (auto &F : M.functions()) {
|
||||||
if (GetHLOpcodeGroupByName(&F) == HLOpcodeGroup::HLCreateHandle) {
|
if (GetHLOpcodeGroupByName(&F) == HLOpcodeGroup::HLCreateHandle) {
|
||||||
Type *ResTy = F.getFunctionType()->getParamType(
|
Type *ResTy = F.getFunctionType()->getParamType(
|
||||||
HLOperandIndex::kCreateHandleResourceOpIdx);
|
HLOperandIndex::kCreateHandleResourceOpIdx);
|
||||||
UndefValue *UndefRes = UndefValue::get(ResTy);
|
UndefValue *UndefRes = UndefValue::get(ResTy);
|
||||||
for (auto U : UndefRes->users()) {
|
if (!UndefRes->use_empty()) {
|
||||||
// Only report instruction users.
|
Constant *PoisonRes = ConstantAggregateZero::get(ResTy);
|
||||||
if (Instruction *I = dyn_cast<Instruction>(U))
|
UndefRes->replaceAllUsesWith(PoisonRes);
|
||||||
dxilutil::EmitResMappingError(I);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -277,7 +277,7 @@ static void addHLSLPasses(bool HLSLHighLevel, unsigned OptLevel, hlsl::HLSLExten
|
||||||
MPM.add(createDxilPromoteLocalResources());
|
MPM.add(createDxilPromoteLocalResources());
|
||||||
MPM.add(createDxilPromoteStaticResources());
|
MPM.add(createDxilPromoteStaticResources());
|
||||||
// Verify no undef resource again after promotion
|
// Verify no undef resource again after promotion
|
||||||
MPM.add(createFailUndefResourcePass());
|
MPM.add(createPoisonUndefResourcesPass());
|
||||||
|
|
||||||
MPM.add(createDxilGenerationPass(NoOpt, ExtHelper));
|
MPM.add(createDxilGenerationPass(NoOpt, ExtHelper));
|
||||||
|
|
||||||
|
|
|
@ -1560,7 +1560,7 @@ class db_dxil(object):
|
||||||
add_pass('hlsl-dxil-legalize-eval-operations', 'DxilLegalizeEvalOperations', 'DXIL legalize eval operations', [])
|
add_pass('hlsl-dxil-legalize-eval-operations', 'DxilLegalizeEvalOperations', 'DXIL legalize eval operations', [])
|
||||||
add_pass('dxilgen', 'DxilGenerationPass', 'HLSL DXIL Generation', [
|
add_pass('dxilgen', 'DxilGenerationPass', 'HLSL DXIL Generation', [
|
||||||
{'n':'NotOptimized','t':'bool','c':1}])
|
{'n':'NotOptimized','t':'bool','c':1}])
|
||||||
add_pass('fail-undef-resource', 'FailUndefResource', 'Fail on undef resource use', [])
|
add_pass('poison-undef-resource', 'PoisonUndefResources', 'Poison undef resources', [])
|
||||||
add_pass('simplify-inst', 'SimplifyInst', 'Simplify Instructions', [])
|
add_pass('simplify-inst', 'SimplifyInst', 'Simplify Instructions', [])
|
||||||
add_pass('hlsl-dxil-precise', 'DxilPrecisePropagatePass', 'DXIL precise attribute propagate', [])
|
add_pass('hlsl-dxil-precise', 'DxilPrecisePropagatePass', 'DXIL precise attribute propagate', [])
|
||||||
add_pass('dxil-legalize-sample-offset', 'DxilLegalizeSampleOffsetPass', 'DXIL legalize sample offset', [])
|
add_pass('dxil-legalize-sample-offset', 'DxilLegalizeSampleOffsetPass', 'DXIL legalize sample offset', [])
|
||||||
|
|
Загрузка…
Ссылка в новой задаче