You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Assert in template + out functions when it has local variables #5293
Removing and inlining the template (replacing R with uint);
Removing the unused uint repro = 0; variable. Note that using it in e.g. result = 10 + repro; does not get rid of the assert!;
Replacing out with inout.
Keep in mind that I did hack in a:
if (!idx.hasValue()) {
constauto &astContext = vd->getASTContext();
auto str = vd->getLocation().printToString(astContext.getSourceManager());
printf("Here: %s\n", str.c_str());
}
bit of code to get the compiler to tell me where in our massive shader + #include chain I had to start looking to provide you with a repro (similar to the request for emitError() in #5273). Is there anything I/we can do to streamline this process?
Likewise I wouldn't have found this error without creating a release build of the compiler with -DLLVM_ENABLE_ASSERTIONS=ON, and would like to discuss enabling assertions by default. I have no clue what kind of valid/invalid shader the compiler might have emitted otherwise (or is already emitting, since I am updating our shader compiler and enabling this as a safety guard, but our current older compiler without assertions is accepting this shader just fine: more details in the first paragraph of #5271).
So, I think this issue is more of an argument about why we shouldn’t enable assertions by default than an argument that we should.
The assert is revealing a bug, but it isn’t a bug that prevents correct code generation. With asserts disabled the shader compiles to correct output.
The problem with blanket enabling asserts in the DXC (or LLVM) codebase is that it enables a bunch of really expensive verification steps that are extremely useful for testing, but not for end users. My anecdotal test on DXC is that costs us about 15% on compile time.
Chris B (@llvm-beanz) I've not validated that for larger HLSL source the output is indeed a valid shader. It is not my code but who knows if this is the source of vague/obscure bugs.
In my mind all bets are off when we ignore useful asserts, otherwise the assert shouldn't have been there.
Chris B (@llvm-beanz) I've not validated that for larger HLSL source the output is indeed a valid shader. It is not my code but who knows if this is the source of vague/obscure bugs.
The location of the assert you reported here is during diagnostic construction, and the code still does something correct even if the assert is false. The assert does signify a faulty assumption in the code, which I'll look into, but it does not result in any impact on AST formation or code generation.
In my mind all bets are off when we ignore useful asserts, otherwise the assert shouldn't have been there.
This is okay if that's how you use asserts in your codebase. That is not how asserts are used in LLVM, and applying that assumption to LLVM is not necessarily helpful.
LLVM generally uses asserts to verify assumptions but still expects the code to behave correctly if the assert is removed. Cases that are irrecoverable use report_fatal_error or exit in LLVM to end execution (note: in DXC exit calls have been replaced with exception throws).
DXC's use of asserts is inconsistent at best, but since most of DXC's code is inherited from LLVM & Clang, I don't think you can safely dismiss how that code was written.
Sure, let's settle that discussion there then, and I'll just have to be mindful of our rather uncommon use of many threads poking dxcompiler.dll at the same time (as threading bugs that end up being caught by asserts seem to pop up every once in a while).
Let's instead leave this issue to clear out the diagnostic assert, that'd unblock me from at least being able to run an assertion-enabled release build in case something else goes wrong :)
We (Frostbite) just hit this issue as well. I wanted to clear a few things up since I think from reading the above there's a bit of a misunderstanding about the nature of this issue.
So, if the assert fires, then idx is an Optional with no value. If the assert is "ignored" (i.e. compiled out in Release) then the value of the Optional will be fetched anyway. This will just returned uninitialized memory. This is then used to index into a vector, which unless you are very lucky will be an out-of-bounds access.
Now, it appears that in very simple situations you "get away with it", but this is not true in general -- in our case it just crashes 🙂. We are compiling multiple shaders in parallel, and it sounds like this is what Marijn Suijten (@MarijnS95) is doing too, so it sounds like that's one way to be unlucky 🙂.
So, based on this:
LLVM generally uses asserts to verify assumptions but still expects the code to behave correctly if the assert is removed.
This is definitely not true in this particular instance -- accessing unitialised data is not behaving correctly 🙂.
With asserts disabled the shader compiles to correct output.
IMO this is also not true in this instance -- at best the diagnostic analysis is wrong, attributing the assignment to the wrong variable. At worst it crashes, as we have seen 🙂.
Anyway, that's a very long winded way to say that this is a pretty bad bug, and prevents our use of out params in template functions 😄.
I wanted to clear a few things up since I think from reading the above there's a bit of a misunderstanding about the nature of this issue.
After trying very hard to parse your reply, I couldn't find anything that is different in your report/reply/findings about the nature of this issue (maybe out the way it was written off as a diagnostics bug that still produces "correct" code?). Can you elaborate what this misunderstanding is?
I think we both found out doesn't work in templates, and that we just got lucky that our shader produces a working / "correct" output?
We are compiling multiple shaders in parallel, and it sounds like this is what Marijn Suijten (@MarijnS95) is doing too, so it sounds like that's one way to be unlucky 🙂.
Yes, that's exactly what we're doing. On the same library and I think even compiler COM instance.
I think we both found out doesn't work in templates, and that we just got lucky that our shader produces a working / "correct" output?
Yes, exactly, I believe we both hit the exact same issue. We weren't "lucky" though -- the compiler crashes for us 🙂.
My reference to a misunderstanding is the implication that this is an unimportant issue, because it "works" in Release. For us it very much does not, and is unlikely for most people (given that the code will index into an array with uninitialised memory, some that is very likely to cause a crash).
I'm bumping this thread. It seems we (Asobo) are as unlucky as Simon. We're crashing in Release and hit a LLVM assert in debug. If using the snippet from Simon, it seems this code is the responsible (it was not crashing before tho). It is also templated code with out variable. We'll keep the old version of dxc for now but it would be great to have a fix of this issue.
template <typename T, typename T2, typename T3>
bool TRayVsAABB(T3 rayOrigin, T3 rayDir, T3 AABBMin, T3 AABBMax, out T2 intersections)
{
T3 invRayDir = 1.0 / rayDir;
T3 t0 = (AABBMin - rayOrigin) * invRayDir;
T3 t1 = (AABBMax - rayOrigin) * invRayDir;
T3 tmin = min(t0, t1);
T3 tmax = max(t0, t1);
T tClose = max(max(tmin.x, tmin.y), tmin.z);
T tFar = min(min(tmax.x, tmax.y), tmax.z);
intersections = T2(tClose, tFar);
return tClose <= tFar;
}
Activity
llvm-beanz commentedon Jun 23, 2023
So, I think this issue is more of an argument about why we shouldn’t enable assertions by default than an argument that we should.
The assert is revealing a bug, but it isn’t a bug that prevents correct code generation. With asserts disabled the shader compiles to correct output.
The problem with blanket enabling asserts in the DXC (or LLVM) codebase is that it enables a bunch of really expensive verification steps that are extremely useful for testing, but not for end users. My anecdotal test on DXC is that costs us about 15% on compile time.
MarijnS95 commentedon Jun 23, 2023
Chris B (@llvm-beanz) I've not validated that for larger HLSL source the output is indeed a valid shader. It is not my code but who knows if this is the source of vague/obscure bugs.
In my mind all bets are off when we ignore useful asserts, otherwise the assert shouldn't have been there.
llvm-beanz commentedon Jun 23, 2023
The location of the assert you reported here is during diagnostic construction, and the code still does something correct even if the
assertis false. Theassertdoes signify a faulty assumption in the code, which I'll look into, but it does not result in any impact on AST formation or code generation.This is okay if that's how you use asserts in your codebase. That is not how asserts are used in LLVM, and applying that assumption to LLVM is not necessarily helpful.
LLVM generally uses asserts to verify assumptions but still expects the code to behave correctly if the assert is removed. Cases that are irrecoverable use
report_fatal_errororexitin LLVM to end execution (note: in DXCexitcalls have been replaced with exception throws).MarijnS95 commentedon Jun 23, 2023
That constraint seems to have been loosened as LLVM transformed into DXC then :)
(Not necessarily speaking about this specific assert)
llvm-beanz commentedon Jun 23, 2023
DXC's use of asserts is inconsistent at best, but since most of DXC's code is inherited from LLVM & Clang, I don't think you can safely dismiss how that code was written.
MarijnS95 commentedon Jun 23, 2023
Sure, let's settle that discussion there then, and I'll just have to be mindful of our rather uncommon use of many threads poking
dxcompiler.dllat the same time (as threading bugs that end up being caught by asserts seem to pop up every once in a while).Let's instead leave this issue to clear out the diagnostic
assert, that'd unblock me from at least being able to run an assertion-enabled release build in case something else goes wrong :)simontaylor81 commentedon May 20, 2024
We (Frostbite) just hit this issue as well. I wanted to clear a few things up since I think from reading the above there's a bit of a misunderstanding about the nature of this issue.
This is the code that is asserting:
So, if the assert fires, then
idxis an Optional with no value. If the assert is "ignored" (i.e. compiled out in Release) then the value of the Optional will be fetched anyway. This will just returned uninitialized memory. This is then used to index into a vector, which unless you are very lucky will be an out-of-bounds access.Now, it appears that in very simple situations you "get away with it", but this is not true in general -- in our case it just crashes 🙂. We are compiling multiple shaders in parallel, and it sounds like this is what Marijn Suijten (@MarijnS95) is doing too, so it sounds like that's one way to be unlucky 🙂.
So, based on this:
This is definitely not true in this particular instance -- accessing unitialised data is not behaving correctly 🙂.
IMO this is also not true in this instance -- at best the diagnostic analysis is wrong, attributing the assignment to the wrong variable. At worst it crashes, as we have seen 🙂.
Anyway, that's a very long winded way to say that this is a pretty bad bug, and prevents our use of
outparams in template functions 😄.MarijnS95 commentedon May 21, 2024
After trying very hard to parse your reply, I couldn't find anything that is different in your report/reply/findings about the nature of this issue (maybe out the way it was written off as a diagnostics bug that still produces "correct" code?). Can you elaborate what this misunderstanding is?
I think we both found
outdoesn't work intemplates, and that we just got lucky that our shader produces a working / "correct" output?Yes, that's exactly what we're doing. On the same library and I think even compiler COM instance.
simontaylor81 commentedon May 22, 2024
Yes, exactly, I believe we both hit the exact same issue. We weren't "lucky" though -- the compiler crashes for us 🙂.
My reference to a misunderstanding is the implication that this is an unimportant issue, because it "works" in Release. For us it very much does not, and is unlikely for most people (given that the code will index into an array with uninitialised memory, some that is very likely to cause a crash).
damyanp commentedon Sep 3, 2024
Confirmed that the example in the description still hits this assert.
Add defensive checks for declToIndex entries
rbertin-aso commentedon Aug 10, 2026
Hi.
I'm bumping this thread. It seems we (Asobo) are as unlucky as Simon. We're crashing in Release and hit a LLVM assert in debug. If using the snippet from Simon, it seems this code is the responsible (it was not crashing before tho). It is also templated code with out variable. We'll keep the old version of dxc for now but it would be great to have a fix of this issue.
Cheers,
Robin.
Add defensive checks for declToIndex entries (#8401)