Skip to content

Commit

Permalink
Merge fixes to release branch (#3611)
Browse files Browse the repository at this point in the history
Cherry-pick changes to release branch:
cd3ef21 Roll back llvm::ArrayRef dependency in ExecutionTest (#3613)
2791c51 Generate descriptions for resources with no names (#3598)
22fa209 Fix LifetimeIntrinsicTest issues (#3609)
2039610 Fix Dxil validator compat and test issues (#3610)
220e884 Rename payload qualifier field to not match type (#3607)
0e89206 Correct exception handler sprintf for 32-bit (#3608)
9b475a7 Add dxc exception handler (#3604)
e8372b9 Fixed arg pairs not correct for old source in module pdbs (#3599)
2bda44f Add constant evaluation for clamp() (#3581)
640c9af Added way for caller to replace args in PDB utils (#3595)
de00b01 Fix const error check for object subscript operator (#3580)
  • Loading branch information
tex3d authored Mar 23, 2021
2 parents 6b8d715 + 1725482 commit 3d5e8b9
Show file tree
Hide file tree
Showing 39 changed files with 912 additions and 306 deletions.
4 changes: 4 additions & 0 deletions include/dxc/Support/FileIOHelper.h
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,10 @@ HRESULT DxcCreateBlobWithEncodingFromPinned(
_In_bytecount_(size) LPCVOID pText, UINT32 size, UINT32 codePage,
_COM_Outptr_ IDxcBlobEncoding **pBlobEncoding) throw();

HRESULT DxcCreateBlobFromPinned(
_In_bytecount_(size) LPCVOID pText, UINT32 size,
_COM_Outptr_ IDxcBlob **pBlob) throw();

HRESULT
DxcCreateBlobWithEncodingFromStream(
IStream *pStream, bool newInstanceAlways, UINT32 codePage,
Expand Down
1 change: 1 addition & 0 deletions include/dxc/Support/HLSLOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ class DxcOpts {

bool PrintAfterAll; // OPT_print_after_all
bool EnablePayloadQualifiers = false; // OPT_enable_payload_qualifiers
bool HandleExceptions = false; // OPT_disable_exception_handling

// Rewriter Options
RewriterOpts RWOpt;
Expand Down
2 changes: 2 additions & 0 deletions include/dxc/Support/HLSLOptions.td
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,8 @@ def enable_payload_qualifiers : Flag<["-", "/"], "enable-payload-qualifiers">, G
HelpText<"Enables support for payload access qualifiers for raytracing payloads in SM 6.6.">;
def disable_payload_qualifiers : Flag<["-", "/"], "disable-payload-qualifiers">, Group<hlslcomp_Group>, Flags<[CoreOption, RewriteOption, DriverOption]>,
HelpText<"Disables support for payload access qualifiers for raytracing payloads in SM 6.7.">;
def disable_exception_handling : Flag<["-", "/"], "disable-exception-handling">, Group<hlslcomp_Group>, Flags<[DriverOption, HelpHidden]>,
HelpText<"Disable dxc handling of exceptions">;

// Used with API only
def skip_serialization : Flag<["-", "/"], "skip-serialization">, Group<hlslcore_Group>, Flags<[CoreOption, HelpHidden]>,
Expand Down
7 changes: 7 additions & 0 deletions include/dxc/dxcapi.h
Original file line number Diff line number Diff line change
Expand Up @@ -582,6 +582,11 @@ struct IDxcVersionInfo3 : public IUnknown {
) = 0;
};

struct DxcArgPair {
const WCHAR *pName;
const WCHAR *pValue;
};

CROSS_PLATFORM_UUIDOF(IDxcPdbUtils, "E6C9647E-9D6A-4C3B-B94C-524B5A6C343D")
struct IDxcPdbUtils : public IUnknown {
virtual HRESULT STDMETHODCALLTYPE Load(_In_ IDxcBlob *pPdbOrDxil) = 0;
Expand Down Expand Up @@ -616,6 +621,8 @@ struct IDxcPdbUtils : public IUnknown {

virtual HRESULT STDMETHODCALLTYPE SetCompiler(_In_ IDxcCompiler3 *pCompiler) = 0;
virtual HRESULT STDMETHODCALLTYPE CompileForFullPDB(_COM_Outptr_ IDxcResult **ppResult) = 0;
virtual HRESULT STDMETHODCALLTYPE OverrideArgs(_In_ DxcArgPair *pArgPairs, UINT32 uNumArgPairs) = 0;
virtual HRESULT STDMETHODCALLTYPE OverrideRootSignature(_In_ const WCHAR *pRootSignature) = 0;
};

// Note: __declspec(selectany) requires 'extern'
Expand Down
4 changes: 2 additions & 2 deletions include/llvm/Support/ErrorHandling.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,8 @@ namespace llvm {
#ifndef NDEBUG
#define llvm_unreachable(msg) \
::llvm::llvm_unreachable_internal(msg, __FILE__, __LINE__)
#elif defined(LLVM_BUILTIN_UNREACHABLE)
#define llvm_unreachable(msg) LLVM_BUILTIN_UNREACHABLE
//#elif defined(LLVM_BUILTIN_UNREACHABLE) // HLSL Change - always throw exception for unreachable
//#define llvm_unreachable(msg) LLVM_BUILTIN_UNREACHABLE
#else
#define llvm_unreachable(msg) ::llvm::llvm_unreachable_internal()
#endif
Expand Down
3 changes: 2 additions & 1 deletion lib/DXIL/DxilShaderFlags.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,7 @@ ShaderFlags ShaderFlags::CollectShaderFlags(const Function *F,
M->GetValidatorVersion(valMajor, valMinor);
bool hasMulticomponentUAVLoadsBackCompat = valMajor == 1 && valMinor == 0;
bool hasViewportOrRTArrayIndexBackCombat = valMajor == 1 && valMinor < 4;
bool hasBarycentricsBackCompat = valMajor == 1 && valMinor < 6;

Type *int16Ty = Type::getInt16Ty(F->getContext());
Type *int64Ty = Type::getInt64Ty(F->getContext());
Expand Down Expand Up @@ -630,7 +631,7 @@ ShaderFlags ShaderFlags::CollectShaderFlags(const Function *F,
flag.SetViewID(hasViewID);
flag.SetViewportAndRTArrayIndex(hasViewportOrRTArrayIndex);
flag.SetShadingRate(hasShadingRate);
flag.SetBarycentrics(hasBarycentrics);
flag.SetBarycentrics(hasBarycentricsBackCompat ? false : hasBarycentrics);
flag.SetSamplerFeedback(hasSamplerFeedback);
flag.SetRaytracingTier1_1(hasRaytracingTier1_1);
flag.SetAtomicInt64OnTypedResource(hasAtomicInt64OnTypedResource);
Expand Down
8 changes: 8 additions & 0 deletions lib/DxcSupport/FileIOHelper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -778,6 +778,14 @@ HRESULT DxcCreateBlobWithEncodingFromPinned(LPCVOID pText, UINT32 size,
return DxcCreateBlob(pText, size, true, false, true, codePage, nullptr, pBlobEncoding);
}

HRESULT DxcCreateBlobFromPinned(
_In_bytecount_(size) LPCVOID pText, UINT32 size,
_COM_Outptr_ IDxcBlob **pBlob) throw() {
CComPtr<IDxcBlobEncoding> pBlobEncoding;
DxcCreateBlob(pText, size, true, false, false, CP_ACP, nullptr, &pBlobEncoding);
return pBlobEncoding.QueryInterface(pBlob);
}

_Use_decl_annotations_
HRESULT
DxcCreateBlobWithEncodingFromStream(IStream *pStream, bool newInstanceAlways,
Expand Down
2 changes: 2 additions & 0 deletions lib/DxcSupport/HLSLOptions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -663,6 +663,8 @@ int ReadDxcOpts(const OptTable *optionTable, unsigned flagsToInclude,
return 1;
}

opts.HandleExceptions = !Args.hasFlag(OPT_disable_exception_handling, OPT_INVALID, false);

if (opts.DefaultColMajor && opts.DefaultRowMajor) {
errors << "Cannot specify /Zpr and /Zpc together, use /? to get usage information";
return 1;
Expand Down
51 changes: 46 additions & 5 deletions lib/HLSL/DxilValidation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -687,16 +687,57 @@ struct ValidationContext {
Failed = true;
}

// Use this instead of DxilResourceBase::GetGlobalName
std::string GetResourceName(const hlsl::DxilResourceBase *Res) {
if (!Res)
return "nullptr";
std::string resName = Res->GetGlobalName();
if (!resName.empty())
return resName;
if (pDebugModule) {
DxilModule &DM = pDebugModule->GetOrCreateDxilModule();
switch (Res->GetClass()) {
case DXIL::ResourceClass::CBuffer: return DM.GetCBuffer(Res->GetID()).GetGlobalName();
case DXIL::ResourceClass::Sampler: return DM.GetSampler(Res->GetID()).GetGlobalName();
case DXIL::ResourceClass::SRV: return DM.GetSRV(Res->GetID()).GetGlobalName();
case DXIL::ResourceClass::UAV: return DM.GetUAV(Res->GetID()).GetGlobalName();
default: return "Invalid Resource";
}
}
// When names have been stripped, use class and binding location to
// identify the resource. Format is roughly:
// Allocated: (CB|T|U|S)<ID>: <ResourceKind> ((cb|t|u|s)<LB>[<RangeSize>] space<SpaceID>)
// Unallocated: (CB|T|U|S)<ID>: <ResourceKind> (no bind location)
// Example: U0: TypedBuffer (u5[2] space1)
// [<RangeSize>] and space<SpaceID> skipped if 1 and 0 respectively.
return (Twine(Res->GetResIDPrefix()) + Twine(Res->GetID()) + ": " +
Twine(Res->GetResKindName()) +
(Res->IsAllocated()
? (" (" + Twine(Res->GetResBindPrefix()) +
Twine(Res->GetLowerBound()) +
(Res->IsUnbounded()
? Twine("[unbounded]")
: (Res->GetRangeSize() != 1)
? "[" + Twine(Res->GetRangeSize()) + "]"
: Twine()) +
((Res->GetSpaceID() != 0)
? " space" + Twine(Res->GetSpaceID())
: Twine()) +
")")
: Twine(" (no bind location)")))
.str();
}

void EmitResourceError(const hlsl::DxilResourceBase *Res, ValidationRule rule) {
std::string QuotedRes = " '" + Res->GetGlobalName() + "'";
std::string QuotedRes = " '" + GetResourceName(Res) + "'";
dxilutil::EmitErrorOnContext(M.getContext(), GetValidationRuleText(rule) + QuotedRes);
Failed = true;
}

void EmitResourceFormatError(const hlsl::DxilResourceBase *Res,
ValidationRule rule,
ArrayRef<StringRef> args) {
std::string QuotedRes = " '" + Res->GetGlobalName() + "'";
std::string QuotedRes = " '" + GetResourceName(Res) + "'";
std::string ruleText = GetValidationRuleText(rule);
FormatRuleText(ruleText, args);
dxilutil::EmitErrorOnContext(M.getContext(), ruleText + QuotedRes);
Expand Down Expand Up @@ -3996,7 +4037,7 @@ static void ValidateResourceOverlap(
if (conflictRes) {
ValCtx.EmitFormatError(
ValidationRule::SmResourceRangeOverlap,
{res.GetGlobalName(), std::to_string(base),
{ValCtx.GetResourceName(&res), std::to_string(base),
std::to_string(size),
std::to_string(conflictRes->GetLowerBound()),
std::to_string(conflictRes->GetRangeSize()),
Expand Down Expand Up @@ -4208,7 +4249,7 @@ static void ValidateCBuffer(DxilCBuffer &cb, ValidationContext &ValCtx) {
DXIL::kMaxCBufferSize << 4);
CollectCBufferRanges(annotation, constAllocator,
0, typeSys,
cb.GetGlobalName(), ValCtx);
ValCtx.GetResourceName(&cb), ValCtx);
}

static void ValidateResources(ValidationContext &ValCtx) {
Expand Down Expand Up @@ -4240,7 +4281,7 @@ static void ValidateResources(ValidationContext &ValCtx) {
if (uav->HasCounter() && uav->IsGloballyCoherent())
ValCtx.EmitResourceFormatError(uav.get(),
ValidationRule::MetaGlcNotOnAppendConsume,
{uav.get()->GetGlobalName()});
{ValCtx.GetResourceName(uav.get())});

ValidateResource(*uav, ValCtx);
ValidateResourceOverlap(*uav, uavAllocator, ValCtx);
Expand Down
92 changes: 92 additions & 0 deletions tools/clang/lib/CodeGen/CGHLSLMSFinishCodeGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1460,6 +1460,10 @@ typedef APInt(__cdecl *IntBinaryEvalFuncType)(const APInt &, const APInt &);
typedef float(__cdecl *FloatBinaryEvalFuncType)(float, float);
typedef double(__cdecl *DoubleBinaryEvalFuncType)(double, double);

typedef APInt(__cdecl *IntTernaryEvalFuncType)(const APInt &, const APInt &, const APInt &);
typedef float(__cdecl *FloatTernaryEvalFuncType)(float, float, float);
typedef double(__cdecl *DoubleTernaryEvalFuncType)(double, double, double);

Value *EvalUnaryIntrinsic(ConstantFP *fpV, FloatUnaryEvalFuncType floatEvalFunc,
DoubleUnaryEvalFuncType doubleEvalFunc) {
llvm::Type *Ty = fpV->getType();
Expand Down Expand Up @@ -1510,6 +1514,45 @@ Value *EvalBinaryIntrinsic(Constant *cV0, Constant *cV1,
return Result;
}

Value *EvalTernaryIntrinsic(Constant *cV0, Constant *cV1, Constant *cV2,
FloatTernaryEvalFuncType floatEvalFunc,
DoubleTernaryEvalFuncType doubleEvalFunc,
IntTernaryEvalFuncType intEvalFunc) {
llvm::Type *Ty = cV0->getType();
Value *Result = nullptr;
if (Ty->isDoubleTy()) {
ConstantFP *fpV0 = cast<ConstantFP>(cV0);
ConstantFP *fpV1 = cast<ConstantFP>(cV1);
ConstantFP *fpV2 = cast<ConstantFP>(cV2);
double dV0 = fpV0->getValueAPF().convertToDouble();
double dV1 = fpV1->getValueAPF().convertToDouble();
double dV2 = fpV2->getValueAPF().convertToDouble();
Value *dResult = ConstantFP::get(Ty, doubleEvalFunc(dV0, dV1, dV2));
Result = dResult;
} else if (Ty->isFloatTy()) {
ConstantFP *fpV0 = cast<ConstantFP>(cV0);
ConstantFP *fpV1 = cast<ConstantFP>(cV1);
ConstantFP *fpV2 = cast<ConstantFP>(cV2);
float fV0 = fpV0->getValueAPF().convertToFloat();
float fV1 = fpV1->getValueAPF().convertToFloat();
float fV2 = fpV2->getValueAPF().convertToFloat();
Value *dResult = ConstantFP::get(Ty, floatEvalFunc(fV0, fV1, fV2));
Result = dResult;
} else {
DXASSERT_NOMSG(Ty->isIntegerTy());
DXASSERT_NOMSG(intEvalFunc);
ConstantInt *ciV0 = cast<ConstantInt>(cV0);
ConstantInt *ciV1 = cast<ConstantInt>(cV1);
ConstantInt *ciV2 = cast<ConstantInt>(cV2);
const APInt &iV0 = ciV0->getValue();
const APInt &iV1 = ciV1->getValue();
const APInt &iV2 = ciV2->getValue();
Value *dResult = ConstantInt::get(Ty, intEvalFunc(iV0, iV1, iV2));
Result = dResult;
}
return Result;
}

Value *EvalUnaryIntrinsic(CallInst *CI, FloatUnaryEvalFuncType floatEvalFunc,
DoubleUnaryEvalFuncType doubleEvalFunc) {
Value *V = CI->getArgOperand(0);
Expand Down Expand Up @@ -1566,6 +1609,43 @@ Value *EvalBinaryIntrinsic(CallInst *CI, FloatBinaryEvalFuncType floatEvalFunc,
return Result;
}

Value *EvalTernaryIntrinsic(CallInst *CI, FloatTernaryEvalFuncType floatEvalFunc,
DoubleTernaryEvalFuncType doubleEvalFunc,
IntTernaryEvalFuncType intEvalFunc = nullptr) {
Value *V0 = CI->getArgOperand(0);
Value *V1 = CI->getArgOperand(1);
Value *V2 = CI->getArgOperand(2);
llvm::Type *Ty = CI->getType();
Value *Result = nullptr;
if (llvm::VectorType *VT = dyn_cast<llvm::VectorType>(Ty)) {
Result = UndefValue::get(Ty);
Constant *CV0 = cast<Constant>(V0);
Constant *CV1 = cast<Constant>(V1);
Constant *CV2 = cast<Constant>(V2);
IRBuilder<> Builder(CI);
for (unsigned i = 0; i < VT->getNumElements(); i++) {
Constant *cV0 = cast<Constant>(CV0->getAggregateElement(i));
Constant *cV1 = cast<Constant>(CV1->getAggregateElement(i));
Constant *cV2 = cast<Constant>(CV2->getAggregateElement(i));
Value *EltResult = EvalTernaryIntrinsic(cV0, cV1, cV2, floatEvalFunc,
doubleEvalFunc, intEvalFunc);
Result = Builder.CreateInsertElement(Result, EltResult, i);
}
} else {
Constant *cV0 = cast<Constant>(V0);
Constant *cV1 = cast<Constant>(V1);
Constant *cV2 = cast<Constant>(V2);
Result = EvalTernaryIntrinsic(cV0, cV1, cV2, floatEvalFunc, doubleEvalFunc,
intEvalFunc);
}
CI->replaceAllUsesWith(Result);
CI->eraseFromParent();
return Result;

CI->eraseFromParent();
return Result;
}

void SimpleTransformForHLDXIRInst(Instruction *I, SmallInstSet &deadInsts) {

unsigned opcode = I->getOpcode();
Expand Down Expand Up @@ -1789,6 +1869,18 @@ Value *TryEvalIntrinsic(CallInst *CI, IntrinsicOp intriOp,
CI->eraseFromParent();
return cNan;
} break;
case IntrinsicOp::IOP_clamp: {
auto clampF = [](float a, float b, float c) {
return a < b ? b : a > c ? c : a;
};
auto clampD = [](double a, double b, double c) {
return a < b ? b : a > c ? c : a;
};
auto clampI = [](const APInt &a, const APInt &b, const APInt &c) -> APInt {
return a.slt(b) ? b : a.sgt(c) ? c : a;
};
return EvalTernaryIntrinsic(CI, clampF, clampD, clampI);
} break;
default:
return nullptr;
}
Expand Down
10 changes: 5 additions & 5 deletions tools/clang/lib/Sema/SemaDXR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ struct PayloadAccessInfo {
};

struct DxrShaderDiagnoseInfo {
const FunctionDecl *FunctionDecl;
const FunctionDecl *funcDecl;
const VarDecl *Payload;
DXIL::PayloadAccessShaderStage Stage;
std::vector<TraceRayCall> TraceCalls;
Expand Down Expand Up @@ -689,7 +689,7 @@ DiagnosePayloadAsFunctionArg(
}

if (CalleeInfo.Payload) {
CalleeInfo.FunctionDecl = CalledFunction;
CalleeInfo.funcDecl = CalledFunction;
CalleeInfo.Stage = Info.Stage;
auto FieldsToIgnoreRead = CollectDominatingWritesForCall(Use, Info, DT);
auto FieldsToIgnoreWrite = CollectReachableWritesForCall(Use, Info);
Expand Down Expand Up @@ -925,7 +925,7 @@ DiagnosePayloadAccess(Sema &S, DxrShaderDiagnoseInfo &Info,
clang::DominatorTree DT;
AnalysisDeclContextManager AnalysisManager;
AnalysisDeclContext *AnalysisContext =
AnalysisManager.getContext(Info.FunctionDecl);
AnalysisManager.getContext(Info.funcDecl);

CFG &TheCFG = *AnalysisContext->getCFG();
DT.buildDominatorTree(*AnalysisContext);
Expand Down Expand Up @@ -1093,7 +1093,7 @@ class DXRShaderVisitor : public RecursiveASTVisitor<DXRShaderVisitor> {
DiagnosePayloadParameter(S, Payload, Decl, Stage);
}
DxrShaderDiagnoseInfo Info;
Info.FunctionDecl = Decl;
Info.funcDecl = Decl;
Info.Payload = Payload;
Info.Stage = Stage;

Expand All @@ -1116,4 +1116,4 @@ void DiagnoseRaytracingPayloadAccess(clang::Sema &S,
visitor.diagnose(TU);
}

} // namespace hlsl
} // namespace hlsl
5 changes: 4 additions & 1 deletion tools/clang/lib/Sema/SemaExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9460,7 +9460,10 @@ bool CheckForModifiableLvalue(Expr *E, SourceLocation Loc, Sema &S) { // HLSL Ch
assert(!E->hasPlaceholderType(BuiltinType::PseudoObject));
// HLSL Change Starts - check const for array subscript operator for HLSL vector/matrix
if (S.Context.getLangOpts().HLSL && E->getStmtClass() == Stmt::CXXOperatorCallExprClass) {
// check if it's a vector or matrix
// check if it's a vector or matrix
const CXXOperatorCallExpr *expr = cast<CXXOperatorCallExpr>(E);
QualType qt = expr->getArg(0)->getType();
if ((hlsl::IsMatrixType(&S, qt) || hlsl::IsVectorType(&S, qt)))
return HLSLCheckForModifiableLValue(E, Loc, S);
}
// HLSL Change Ends
Expand Down
4 changes: 2 additions & 2 deletions tools/clang/test/HLSL/array-index-out-of-bounds-HV-2016.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
void dead()
{
int array[2];
array[-1] = 0; /* expected-warning {{array index -1 is before the beginning of the array}} fxc-pass */
array[-1] = 0; /* expected-warning {{array index -1 is before the beginning of the array}} fxc-pass {{}} */
array[0] = 0;
array[1] = 0;
array[2] = 0; /* expected-warning {{array index 2 is past the end of the array (which contains 2 elements)}} fxc-pass */
array[2] = 0; /* expected-warning {{array index 2 is past the end of the array (which contains 2 elements)}} fxc-pass {{}} */
}

void main() {}
Loading

0 comments on commit 3d5e8b9

Please sign in to comment.