[X86][Performance][regression] Adding nosync to sqrt causes ~40% SPEC CPU 2017 544.nab_r & 644.nab_s regression on AMD Zen 4
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
The following two SPEC CPU 2017 tests are showing severe regressions after https://github.com/llvm/llvm-project/pull/197761 landed:
| CPU | Test | Good (s) | Bad (s) | Slowdown | Regression |
|---|---|---:|---:|---:|---:|
| Zen 2 | `544.nab_r` | 75.9950 | 86.9014 | 1.1435× | **+14.35%** |
| Zen 2 | `644.nab_s` | 76.0114 | 86.8487 | 1.1426× | **+14.26%** |
| Zen 4 | `544.nab_r` | 48.92 | 68.48 | 1.3998× | **+39.98%** |
| Zen 4 | `644.nab_s` | 49.03 | 68.30 | 1.3930× | **+39.30%** |
I worked with Codex to try to figure out what is happening in this particular case and it seems like the path that is causing the regression is:
1. nosync added to sqrt
2. GlobalAA now returns NoModRef for sqrt for a global used by the test (global is named `dim` in this case)
3. EarlySCE removes post call loads for this global
4. The loaded value stays live for longer
5. For some reason this causes pathological codegen on Zen4 and still severe but less bad codegen on Zen2
This was verified this by hacking GlobalAA to not return NoModRef for `dim` and the results returned to pre https://github.com/llvm/llvm-project/pull/197761 levels. This is the diff used:
```
diff --git a/llvm/lib/Analysis/GlobalsModRef.cpp b/llvm/lib/Analysis/GlobalsModRef.cpp
index 06d6be91d99f..d4a76f774dc7 100644
--- a/llvm/lib/Analysis/GlobalsModRef.cpp
+++ b/llvm/lib/Analysis/GlobalsModRef.cpp
@@ -952,6 +952,16 @@ ModRefInfo GlobalsAAResult::getModRefInfo(const CallBase *Call,
const MemoryLocation &Loc,
AAQueryInfo &AAQI) {
ModRefInfo Known = ModRefInfo::ModRef;
+
+ if (const auto *GV =
+ dyn_cast(getUnderlyingObject(Loc.Ptr))) {
+ if (GV->hasLocalLinkage() && GV->getName() == "dim") {
+ if (const Function *F = Call->getCalledFunction()) {
+ if (F->isDeclaration() && F->getName() == "sqrt")
+ return ModRefInfo::ModRef;
+ }
+ }
+ }
// If we are asking for mod/ref info of a direct call with a pointer to a
// global we are tracking, return information if we have it.
```
Contributor guide
Research direction
Start in llvm/lib/Analysis/GlobalsModRef.cpp at GlobalsAAResult::getModRefInfo and compare the behavior introduced by pull request 197761. Reproduce the 544.nab_r and 644.nab_s SPEC CPU 2017 regressions on Zen 2 or Zen 4, then verify that the regression is removed without undoing the intended nosync change.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- compilers, performance
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100