[llvm] [AArch64] Implement latency costs for loads (PR #201567)

David Green via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 10 03:06:01 PDT 2026


================
@@ -5055,8 +5054,59 @@ InstructionCost AArch64TTIImpl::getMemoryOpCost(unsigned Opcode, Type *Ty,
   if (CostKind == TTI::TCK_CodeSize || CostKind == TTI::TCK_SizeAndLatency)
     return LT.first;
 
-  if (CostKind != TTI::TCK_RecipThroughput)
-    return 1;
+  if (CostKind == TTI::TCK_Latency) {
+    // Latency doesn't make much sense for stores, so just return 1
+    if (Opcode == Instruction::Store)
+      return 1;
+    // We expect the load to become LT.first loads of type LT.second. The
+    // latency will be the latency of the last load plus the time it gets to get
+    // there, which will be the amount of other loads before that (i.e. total
+    // loads - 1). We get the latency from the SchedModel, and assume that the
+    // loads become the variant with unsigned integer offset.
+    unsigned Inst = 0;
+    if (LT.second.isScalableVector() ||
+        ST->useSVEForFixedLengthVectors(LT.second)) {
+      Inst = AArch64::LDR_ZXI;
+    } else if (LT.second.isVector() || LT.second.isFloatingPoint()) {
+      switch (LT.second.getSizeInBits()) {
+      case 8:
+        Inst = AArch64::LDRBui;
+        break;
+      case 16:
+        Inst = AArch64::LDRHui;
+        break;
+      case 32:
+        Inst = AArch64::LDRSui;
+        break;
+      case 64:
+        Inst = AArch64::LDRDui;
+        break;
+      case 128:
+        Inst = AArch64::LDRQui;
+        break;
+      default:
+        llvm_unreachable("Unexpected float or vector type");
+      }
+    } else {
+      switch (LT.second.getSizeInBits()) {
+      case 8:
+        Inst = AArch64::LDRBBui;
+        break;
+      case 16:
+        Inst = AArch64::LDRHHui;
+        break;
+      case 32:
+        Inst = AArch64::LDRWui;
+        break;
+      case 64:
+        Inst = AArch64::LDRXui;
+        break;
+      default:
+        llvm_unreachable("Unexpected integer type");
+      }
+    }
+    return (LT.first - 1) + SchedModel.computeInstrLatency(Inst);
----------------
davemgreen wrote:

The scheduling model is available through ST->getSchedModel().

You can see hasKnownLowerThroughputFromSchedulingModel for how we already use the scheduling model. It can be a bit unreliable and can create an huge surface area for performance issues in the cost model. With the amount of special cases it sometimes ends up needing to make things performant, I'm not very convinced that the engineering tradeoff between using it more and the benefits we get out of it are really there. In reality this is only changing between a latency of 2, 3 or 4 though I think.

The generic CPU is meant to be a middle-ground that gives the best result across many cpus. From the look of the test updates that might not be remaining true. Can you override it to a give a middle-ground latency?

https://github.com/llvm/llvm-project/pull/201567


More information about the llvm-commits mailing list