[PATCH] D128897: [SimplifyCFG] Improve SwitchToLookupTable optimization
Hans Wennborg via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Thu Jul 7 07:31:22 PDT 2022
hans added a comment.
I think I found another miscompile, see the comment about reuseTableCompare. Can we be sure that there are no more? :)
This is why I'm worried about this approach of tweaking how we use the lookup table, and think that perhaps updating the actual table would be a safer approach.
================
Comment at: llvm/lib/Transforms/Utils/SimplifyCFG.cpp:6373
+ uint64_t ZeroOffsetTableSize = MaxCaseVal->getLimitedValue() + 1;
+
----------------
Could this overflow?
================
Comment at: llvm/lib/Transforms/Utils/SimplifyCFG.cpp:6378
Value *TableIndex;
- if (MinCaseVal->isNullValue())
+ ConstantInt *Offset;
+ if (MinCaseVal->isNullValue() ||
----------------
Offset is a pretty generic name for a variable that's used in such wide scope. Is there a more descriptive name?
================
Comment at: llvm/lib/Transforms/Utils/SimplifyCFG.cpp:6380
+ if (MinCaseVal->isNullValue() ||
+ (!MinCaseVal->isNegative() && (HasDefaultResults || NeedMask) &&
+ ShouldBuildLookupTable(SI, ZeroOffsetTableSize, TTI, DL, ResultTypes) &&
----------------
This now becomes a pretty complicated condition. I wonder if it could be simplified, or at least made easier to follow somehow. In any case it probably needs a comment about what's going on.
================
Comment at: llvm/lib/Transforms/Utils/SimplifyCFG.cpp:6492
// possible.
if (!TableHasHoles && HasDefaultResults && RangeCheckBranch) {
BasicBlock *PhiBlock = PHI->getParent();
----------------
I think your optimization may break this. Consider:
```
void g();
unsigned char f(int x) {
unsigned char r;
switch (x) {
case 1: r = 1; break;
case 2: r = 5; break;
case 3: r = 7; break;
case 4: r = 18; break;
default: r = 0;
}
if (r != 0) {
g();
}
return r;
}
```
Because `TableHasHoles` is false, this code and the code in `reuseTableCompare` will conclude that a lookup in the table yields a value that's different from the default, and so the "r != 0" comparison can be replaced with the range check. However, with your optimization we've essentially added "case 0" to the table with the default value.
I believe the result is (though I didn't test it) that with the transformation in this patch, `f(0)` would end up incorrectly calling `g()`.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D128897/new/
https://reviews.llvm.org/D128897
More information about the llvm-commits
mailing list