[PATCH] D144057: [GVN] permit GVN of non-local loads for ASAN unless undef or alloca is produced
Nick Desaulniers via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Mon May 1 14:45:51 PDT 2023
nickdesaulniers added a comment.
In D144057#4175101 <https://reviews.llvm.org/D144057#4175101>, @nikic wrote:
> In D144057#4130597 <https://reviews.llvm.org/D144057#4130597>, @nickdesaulniers wrote:
>
>> In D144057#4128142 <https://reviews.llvm.org/D144057#4128142>, @nikic wrote:
>>
>>> I don't think this is right as implemented. Imagine you have `if (...) { store v, p } x = load p`. GVN would convert this to something like `x = phi(v, undef)`. With asan, we want this to report if the if is not taken. However, I believe that your checks will permit the transform, because the load folding result is not literally undef (but is still undef on one path).
>>
>> Is this what you're imagining? https://godbolt.org/z/Pc3YezE44
>>
>> Seems like ASAN already misses that? In this case, we go to replace the load with alloca, so adding a check remedies that case. But it doesn't change the fact that asan misses that C test case.
>
> In this case SROA should drop the alloca and it will never get to GVN. You want something more like this: https://godbolt.org/z/8z66K7xbh
>
> I still don't think that this makes sense as-implemented. You are only checking the final result after SSA construction. I believe this needs to at least check all AvailableValues for isUndefValue().
Something like this?
diff --git a/llvm/lib/Transforms/Scalar/GVN.cpp b/llvm/lib/Transforms/Scalar/GVN.cpp
index f36fa0bd0979..ca80c0b40557 100644
--- a/llvm/lib/Transforms/Scalar/GVN.cpp
+++ b/llvm/lib/Transforms/Scalar/GVN.cpp
@@ -1781,11 +1781,14 @@ bool GVNPass::processNonLocalLoad(LoadInst *Load) {
// If a non-local load would result in producing undef or an alloca (which
// is not initialized), don't fold away control flow. We want the
// sanitizers to help report this case.
- if (isa<UndefValue>(V) || isa<AllocaInst>(V)) {
- Function *F = Load->getParent()->getParent();
- if (F->hasFnAttribute(Attribute::SanitizeAddress) ||
- F->hasFnAttribute(Attribute::SanitizeHWAddress))
- return false;
+ Function *F = Load->getParent()->getParent();
+ if (F->hasFnAttribute(Attribute::SanitizeAddress) ||
+ F->hasFnAttribute(Attribute::SanitizeHWAddress)) {
+ for (AvailableValueInBlock &AV : ValuesPerBlock) {
+ if (AV.AV.isUndefValue()) {
+ return false;
+ }
+ }
}
Load->replaceAllUsesWith(V);
That doesn't seem to work, though perhaps you envisioned something else?
In D144057#4180735 <https://reviews.llvm.org/D144057#4180735>, @melver wrote:
> In D144057#4179643 <https://reviews.llvm.org/D144057#4179643>, @nickdesaulniers wrote:
>
>> In D144057#4166558 <https://reviews.llvm.org/D144057#4166558>, @melver wrote:
>>
>>> Do the KASAN tests in the kernel pass (need to use -next, mainline is currently broken)? Wondering how we can double check there are no new false positives nor false negatives.
>>
>> How do I run those?
>
> Just CONFIG_KASAN_KUNIT_TEST=y should do and then boot kernel.
I've done so and the system boots. Was there supposed to be anything printed to the console? I just enabled KASAN=y, KUNIT=y, KASAN_KUNIT_TEST=y.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D144057/new/
https://reviews.llvm.org/D144057
More information about the llvm-commits
mailing list