Skip to content

Conversation

david-arm
Copy link
Contributor

Avoid calling getLegacyCost for single scalar loads and stores where the cost is trivial to calculate.

@llvmbot
Copy link
Member

llvmbot commented Aug 12, 2025

@llvm/pr-subscribers-vectorizers

@llvm/pr-subscribers-llvm-transforms

Author: David Sherwood (david-arm)

Changes

Avoid calling getLegacyCost for single scalar loads and stores where the cost is trivial to calculate.


Full diff: https://github.com/llvm/llvm-project/pull/153218.diff

1 Files Affected:

  • (modified) llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp (+16)
diff --git a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp
index e34cab117f321..b301aee6dad23 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp
@@ -2975,6 +2975,22 @@ InstructionCost VPReplicateRecipe::computeCost(ElementCount VF,
                Op2Info, Operands, UI, &Ctx.TLI) *
            (isSingleScalar() ? 1 : VF.getFixedValue());
   }
+  case Instruction::Load:
+  case Instruction::Store: {
+    if (isSingleScalar()) {
+      Type *ValTy = getLoadStoreType(UI);
+      Type *ScalarPtrTy = getLoadStorePointerOperand(UI)->getType();
+      const Align Alignment = getLoadStoreAlignment(UI);
+      unsigned AS = getLoadStoreAddressSpace(UI);
+      TTI::OperandValueInfo OpInfo = TTI::getOperandInfo(UI->getOperand(0));
+      InstructionCost ScalarMemOpCost = Ctx.TTI.getMemoryOpCost(
+          UI->getOpcode(), ValTy, Alignment, AS, CostKind, OpInfo, UI);
+      return ScalarMemOpCost + Ctx.TTI.getAddressComputationCost(ScalarPtrTy);
+    }
+    // TODO: See getMemInstScalarizationCost for how to handle vector and
+    // predicated cases.
+    break;
+  }
   }
 
   return Ctx.getLegacyCost(UI, VF);

@david-arm
Copy link
Contributor Author

Gentle ping. :)

UI->getOpcode(), ValTy, Alignment, AS, CostKind, OpInfo, UI);
return ScalarMemOpCost + Ctx.TTI.getAddressComputationCost(ScalarPtrTy);
}
// TODO: See getMemInstScalarizationCost for how to handle vector and
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// TODO: See getMemInstScalarizationCost for how to handle vector and
// TODO: See getMemInstScalarizationCost for how to handle replicating and

This code here won't handle vector cases?

Comment on lines 2981 to 2982
Type *ValTy = getLoadStoreType(UI);
Type *ScalarPtrTy = getLoadStorePointerOperand(UI)->getType();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we get this from the VPlan type analysis?

Avoid calling getLegacyCost for single scalar loads and stores
where the cost is trivial to calculate.
Comment on lines +5208 to +5209
// TODO: Is this right? Operand 0 has a different meaning for loads and
// stores.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is indeed confusing and the argument isn't documented, but it looks like in RISCV TTI and X86 TTI (https://github.com/llvm/llvm-project/blob/main/llvm/lib/Target/X86/X86TargetTransformInfo.cpp#L5241) the argument is used as it is passed here: stored value for stores, address for loads. AArch64 and ARM TTIs don't use it.

So it seems it is used as expected, even though the documentation of the interface could be improved

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants