Skip to content

[X86][Performance][regression] Adding nosync to sqrt causes ~40% SPEC CPU 2017 544.nab_r & 644.nab_s regression on AMD Zen 4 #216794

Description

@freaknbigpanda

The following two SPEC CPU 2017 tests are showing severe regressions after #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 #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<GlobalValue>(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.


Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    Status
    No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions