|
@@ -36,40 +36,44 @@ using namespace llvm;
|
|
|
using namespace hlsl;
|
|
|
|
|
|
namespace {
|
|
|
-class FailUndefResource : public ModulePass {
|
|
|
+class PoisonUndefResources : public ModulePass {
|
|
|
public:
|
|
|
static char ID;
|
|
|
|
|
|
- explicit FailUndefResource() : ModulePass(ID) {
|
|
|
+ explicit PoisonUndefResources() : ModulePass(ID) {
|
|
|
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;
|
|
|
};
|
|
|
}
|
|
|
|
|
|
-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) {
|
|
|
- // Undef resources may be removed on simplify due to the interpretation
|
|
|
- // of undef that any value could be substituted for identical meaning.
|
|
|
- // However, these likely indicate uninitialized locals being used in
|
|
|
- // some code path, which we should catch and report.
|
|
|
+bool PoisonUndefResources::runOnModule(Module &M) {
|
|
|
+ // Undef resources typically indicate uninitialized locals being used
|
|
|
+ // in some code path, which we should catch and report. However, some
|
|
|
+ // code patterns in large shaders cause dead undef resources to momentarily,
|
|
|
+ // 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()) {
|
|
|
if (GetHLOpcodeGroupByName(&F) == HLOpcodeGroup::HLCreateHandle) {
|
|
|
Type *ResTy = F.getFunctionType()->getParamType(
|
|
|
HLOperandIndex::kCreateHandleResourceOpIdx);
|
|
|
UndefValue *UndefRes = UndefValue::get(ResTy);
|
|
|
- for (auto U : UndefRes->users()) {
|
|
|
- // Only report instruction users.
|
|
|
- if (Instruction *I = dyn_cast<Instruction>(U))
|
|
|
- dxilutil::EmitResMappingError(I);
|
|
|
+ if (!UndefRes->use_empty()) {
|
|
|
+ Constant *PoisonRes = ConstantAggregateZero::get(ResTy);
|
|
|
+ UndefRes->replaceAllUsesWith(PoisonRes);
|
|
|
}
|
|
|
}
|
|
|
}
|