|
@@ -832,40 +832,55 @@ ValidateSignatureAccess(Instruction *I, DxilSignature &sig, Value *sigID,
|
|
return &SE;
|
|
return &SE;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static CallInst *GetHandleFromValue(Value *V, DenseSet<Value *> &Checked);
|
|
static CallInst *GetHandleFromPhi(PHINode *Phi, DenseSet<Value *> &Checked) {
|
|
static CallInst *GetHandleFromPhi(PHINode *Phi, DenseSet<Value *> &Checked) {
|
|
// TODO: validate all incoming values for phi is same kind and class.
|
|
// TODO: validate all incoming values for phi is same kind and class.
|
|
for (Value *V : Phi->incoming_values()) {
|
|
for (Value *V : Phi->incoming_values()) {
|
|
- if (Checked.count(V))
|
|
|
|
- continue;
|
|
|
|
|
|
+ if (CallInst *CI = GetHandleFromValue(V, Checked))
|
|
|
|
+ return CI;
|
|
|
|
+ }
|
|
|
|
+ return nullptr;
|
|
|
|
+}
|
|
|
|
+static CallInst *GetHandleFromSelect(SelectInst *Sel, DenseSet<Value *> &Checked) {
|
|
|
|
+ // TODO: validate all incoming values for select is same kind and class.
|
|
|
|
+ for (Value *V = Sel->getTrueValue(), *F = Sel->getFalseValue(); V != F; V = F) {
|
|
|
|
+ if (CallInst *CI = GetHandleFromValue(V, Checked))
|
|
|
|
+ return CI;
|
|
|
|
+ }
|
|
|
|
+ return nullptr;
|
|
|
|
+}
|
|
|
|
+static CallInst *GetHandleFromValue(Value *V, DenseSet<Value *> &Checked) {
|
|
|
|
+ if (!Checked.count(V)) {
|
|
Checked.insert(V);
|
|
Checked.insert(V);
|
|
if (CallInst *CI = dyn_cast<CallInst>(V)) {
|
|
if (CallInst *CI = dyn_cast<CallInst>(V)) {
|
|
return CI;
|
|
return CI;
|
|
}
|
|
}
|
|
- if (PHINode *P = dyn_cast<PHINode>(V)) {
|
|
|
|
|
|
+ else if (PHINode *P = dyn_cast<PHINode>(V)) {
|
|
if (CallInst *CI = GetHandleFromPhi(P, Checked)) {
|
|
if (CallInst *CI = GetHandleFromPhi(P, Checked)) {
|
|
return CI;
|
|
return CI;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+ else if (SelectInst *S = dyn_cast<SelectInst>(V)) {
|
|
|
|
+ if (CallInst *CI = GetHandleFromSelect(S, Checked)) {
|
|
|
|
+ return CI;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
}
|
|
}
|
|
return nullptr;
|
|
return nullptr;
|
|
}
|
|
}
|
|
|
|
|
|
static DXIL::SamplerKind GetSamplerKind(Value *samplerHandle,
|
|
static DXIL::SamplerKind GetSamplerKind(Value *samplerHandle,
|
|
ValidationContext &ValCtx) {
|
|
ValidationContext &ValCtx) {
|
|
- if (PHINode *Phi = dyn_cast<PHINode>(samplerHandle)) {
|
|
|
|
|
|
+ if (!isa<CallInst>(samplerHandle)) {
|
|
DenseSet<Value *> Checked;
|
|
DenseSet<Value *> Checked;
|
|
- samplerHandle = GetHandleFromPhi(Phi, Checked);
|
|
|
|
- if (!samplerHandle) {
|
|
|
|
|
|
+ if (CallInst *CI = GetHandleFromValue(samplerHandle, Checked)) {
|
|
|
|
+ samplerHandle = CI;
|
|
|
|
+ } else {
|
|
ValCtx.EmitError(ValidationRule::InstrHandleNotFromCreateHandle);
|
|
ValCtx.EmitError(ValidationRule::InstrHandleNotFromCreateHandle);
|
|
return DXIL::SamplerKind::Invalid;
|
|
return DXIL::SamplerKind::Invalid;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- if (!isa<CallInst>(samplerHandle)) {
|
|
|
|
- ValCtx.EmitError(ValidationRule::InstrHandleNotFromCreateHandle);
|
|
|
|
- return DXIL::SamplerKind::Invalid;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
DxilInst_CreateHandle createHandle(cast<CallInst>(samplerHandle));
|
|
DxilInst_CreateHandle createHandle(cast<CallInst>(samplerHandle));
|
|
if (!createHandle) {
|
|
if (!createHandle) {
|
|
auto EmitError = [&]() -> DXIL::SamplerKind {
|
|
auto EmitError = [&]() -> DXIL::SamplerKind {
|
|
@@ -947,19 +962,16 @@ static DXIL::ResourceKind GetResourceKindAndCompTy(Value *handle, DXIL::Componen
|
|
ValidationContext &ValCtx) {
|
|
ValidationContext &ValCtx) {
|
|
CompTy = DXIL::ComponentType::Invalid;
|
|
CompTy = DXIL::ComponentType::Invalid;
|
|
ResClass = DXIL::ResourceClass::Invalid;
|
|
ResClass = DXIL::ResourceClass::Invalid;
|
|
- if (PHINode *Phi = dyn_cast<PHINode>(handle)) {
|
|
|
|
|
|
+ if (!isa<CallInst>(handle)) {
|
|
DenseSet<Value *> Checked;
|
|
DenseSet<Value *> Checked;
|
|
- handle = GetHandleFromPhi(Phi, Checked);
|
|
|
|
- if (!handle) {
|
|
|
|
|
|
+ if (CallInst *CI = GetHandleFromValue(handle, Checked)) {
|
|
|
|
+ handle = CI;
|
|
|
|
+ } else {
|
|
ValCtx.EmitError(ValidationRule::InstrHandleNotFromCreateHandle);
|
|
ValCtx.EmitError(ValidationRule::InstrHandleNotFromCreateHandle);
|
|
return DXIL::ResourceKind::Invalid;
|
|
return DXIL::ResourceKind::Invalid;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// TODO: validate ROV is used only in PS.
|
|
// TODO: validate ROV is used only in PS.
|
|
- if (!isa<CallInst>(handle)) {
|
|
|
|
- ValCtx.EmitError(ValidationRule::InstrHandleNotFromCreateHandle);
|
|
|
|
- return DXIL::ResourceKind::Invalid;
|
|
|
|
- }
|
|
|
|
|
|
|
|
DxilInst_CreateHandle createHandle(cast<CallInst>(handle));
|
|
DxilInst_CreateHandle createHandle(cast<CallInst>(handle));
|
|
if (!createHandle) {
|
|
if (!createHandle) {
|
|
@@ -1218,20 +1230,16 @@ DxilResourceBase *ValidationContext::GetResourceFromVal(Value *resVal) {
|
|
}
|
|
}
|
|
|
|
|
|
static DxilResource *GetResource(Value *handle, ValidationContext &ValCtx) {
|
|
static DxilResource *GetResource(Value *handle, ValidationContext &ValCtx) {
|
|
- if (PHINode *Phi = dyn_cast<PHINode>(handle)) {
|
|
|
|
|
|
+ if (!isa<CallInst>(handle)) {
|
|
DenseSet<Value *> Checked;
|
|
DenseSet<Value *> Checked;
|
|
- handle = GetHandleFromPhi(Phi, Checked);
|
|
|
|
- if (!handle) {
|
|
|
|
|
|
+ if (CallInst *CI = GetHandleFromValue(handle, Checked)) {
|
|
|
|
+ handle = CI;
|
|
|
|
+ } else {
|
|
ValCtx.EmitError(ValidationRule::InstrHandleNotFromCreateHandle);
|
|
ValCtx.EmitError(ValidationRule::InstrHandleNotFromCreateHandle);
|
|
return nullptr;
|
|
return nullptr;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- if (!isa<CallInst>(handle)) {
|
|
|
|
- ValCtx.EmitError(ValidationRule::InstrHandleNotFromCreateHandle);
|
|
|
|
- return nullptr;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
DxilInst_CreateHandle createHandle(cast<CallInst>(handle));
|
|
DxilInst_CreateHandle createHandle(cast<CallInst>(handle));
|
|
if (!createHandle) {
|
|
if (!createHandle) {
|
|
auto EmitError = [&]() -> DXIL::ResourceKind {
|
|
auto EmitError = [&]() -> DXIL::ResourceKind {
|
|
@@ -1551,12 +1559,12 @@ static unsigned StoreValueToMask(ArrayRef<Value *> vals) {
|
|
}
|
|
}
|
|
|
|
|
|
static int GetCBufSize(Value *cbHandle, ValidationContext &ValCtx) {
|
|
static int GetCBufSize(Value *cbHandle, ValidationContext &ValCtx) {
|
|
- if (PHINode *Phi = dyn_cast<PHINode>(cbHandle)) {
|
|
|
|
|
|
+ if (!isa<CallInst>(cbHandle)) {
|
|
DenseSet<Value *> Checked;
|
|
DenseSet<Value *> Checked;
|
|
- cbHandle = GetHandleFromPhi(Phi, Checked);
|
|
|
|
- if (!cbHandle) {
|
|
|
|
- ValCtx.EmitInstrError(Phi,
|
|
|
|
- ValidationRule::InstrHandleNotFromCreateHandle);
|
|
|
|
|
|
+ if (CallInst *CI = GetHandleFromValue(cbHandle, Checked)) {
|
|
|
|
+ cbHandle = CI;
|
|
|
|
+ } else {
|
|
|
|
+ ValCtx.EmitError(ValidationRule::InstrHandleNotFromCreateHandle);
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
}
|
|
}
|