[llvm] [AArch64] Add a basic i128 mul cost. (PR #203271)
David Green via llvm-commits
llvm-commits at lists.llvm.org
Thu Jun 11 07:03:33 PDT 2026
https://github.com/davemgreen created https://github.com/llvm/llvm-project/pull/203271
This adds a basic cost for i128 multiply instructions, which has a basic cost of 4 and scales n^2 with bitsize.
>From 43fdbb56b3814142ff7a16430d79366d0f3e8a91 Mon Sep 17 00:00:00 2001
From: David Green <david.green at arm.com>
Date: Thu, 11 Jun 2026 09:48:21 +0100
Subject: [PATCH] [AArch64] Add a basic i128 mul cost.
This adds a basic cost for i128 multiply instructions, which has a basic cost
of 4 and scales n^2 with bitsize.
---
.../Target/AArch64/AArch64TargetTransformInfo.cpp | 9 +++++++++
.../Analysis/CostModel/AArch64/arith-overflow.ll | 12 ++++++------
llvm/test/Analysis/CostModel/AArch64/arith.ll | 4 ++--
llvm/test/Analysis/CostModel/AArch64/div.ll | 8 ++++----
llvm/test/Analysis/CostModel/AArch64/rem.ll | 8 ++++----
5 files changed, 25 insertions(+), 16 deletions(-)
diff --git a/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp b/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
index 6a5a31fcfeef9..81419c03f65eb 100644
--- a/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
+++ b/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
@@ -4409,6 +4409,15 @@ InstructionCost AArch64TTIImpl::getArithmeticInstrCost(
case ISD::SUB:
return LT.first; // Also works for i128
case ISD::MUL:
+ // i128 multiply is umulh + 2*madd + mul and grows ~n^2.
+ if (Ty->getScalarSizeInBits() > 64) {
+ unsigned NumLanes = isa<FixedVectorType>(Ty)
+ ? cast<FixedVectorType>(Ty)->getNumElements()
+ : 1;
+ InstructionCost CostPerLane = LT.first / NumLanes;
+ return CostPerLane * CostPerLane * NumLanes;
+ }
+
if (LT.second == MVT::v2i64) {
// When SVE is available, then we can lower the v2i64 operation using
// the SVE mul instruction, which has a lower cost.
diff --git a/llvm/test/Analysis/CostModel/AArch64/arith-overflow.ll b/llvm/test/Analysis/CostModel/AArch64/arith-overflow.ll
index 5bbb80f693655..60cd03e57f885 100644
--- a/llvm/test/Analysis/CostModel/AArch64/arith-overflow.ll
+++ b/llvm/test/Analysis/CostModel/AArch64/arith-overflow.ll
@@ -278,9 +278,9 @@ declare {<64 x i8>, <64 x i1>} @llvm.smul.with.overflow.v64i8(<64 x i8>, <64 x
define i32 @smul(i32 %arg) {
; CHECK-LABEL: 'smul'
; CHECK-NEXT: Cost Model: Found costs of 3 for: %I64 = call { i64, i1 } @llvm.smul.with.overflow.i64(i64 undef, i64 undef)
-; CHECK-NEXT: Cost Model: Found costs of RThru:34 CodeSize:20 Lat:28 SizeLat:28 for: %V2I64 = call { <2 x i64>, <2 x i1> } @llvm.smul.with.overflow.v2i64(<2 x i64> undef, <2 x i64> undef)
-; CHECK-NEXT: Cost Model: Found costs of RThru:68 CodeSize:37 Lat:53 SizeLat:53 for: %V4I64 = call { <4 x i64>, <4 x i1> } @llvm.smul.with.overflow.v4i64(<4 x i64> undef, <4 x i64> undef)
-; CHECK-NEXT: Cost Model: Found costs of RThru:136 CodeSize:71 Lat:103 SizeLat:103 for: %V8I64 = call { <8 x i64>, <8 x i1> } @llvm.smul.with.overflow.v8i64(<8 x i64> undef, <8 x i64> undef)
+; CHECK-NEXT: Cost Model: Found costs of RThru:38 CodeSize:20 Lat:28 SizeLat:28 for: %V2I64 = call { <2 x i64>, <2 x i1> } @llvm.smul.with.overflow.v2i64(<2 x i64> undef, <2 x i64> undef)
+; CHECK-NEXT: Cost Model: Found costs of RThru:76 CodeSize:37 Lat:53 SizeLat:53 for: %V4I64 = call { <4 x i64>, <4 x i1> } @llvm.smul.with.overflow.v4i64(<4 x i64> undef, <4 x i64> undef)
+; CHECK-NEXT: Cost Model: Found costs of RThru:152 CodeSize:71 Lat:103 SizeLat:103 for: %V8I64 = call { <8 x i64>, <8 x i1> } @llvm.smul.with.overflow.v8i64(<8 x i64> undef, <8 x i64> undef)
; CHECK-NEXT: Cost Model: Found costs of 2 for: %I32 = call { i32, i1 } @llvm.smul.with.overflow.i32(i32 undef, i32 undef)
; CHECK-NEXT: Cost Model: Found costs of RThru:38 CodeSize:10 Lat:10 SizeLat:10 for: %V4I32 = call { <4 x i32>, <4 x i1> } @llvm.smul.with.overflow.v4i32(<4 x i32> undef, <4 x i32> undef)
; CHECK-NEXT: Cost Model: Found costs of RThru:76 CodeSize:17 Lat:17 SizeLat:17 for: %V8I32 = call { <8 x i32>, <8 x i1> } @llvm.smul.with.overflow.v8i32(<8 x i32> undef, <8 x i32> undef)
@@ -341,9 +341,9 @@ declare {<64 x i8>, <64 x i1>} @llvm.umul.with.overflow.v64i8(<64 x i8>, <64 x
define i32 @umul(i32 %arg) {
; CHECK-LABEL: 'umul'
; CHECK-NEXT: Cost Model: Found costs of 3 for: %I64 = call { i64, i1 } @llvm.umul.with.overflow.i64(i64 undef, i64 undef)
-; CHECK-NEXT: Cost Model: Found costs of RThru:33 CodeSize:19 Lat:27 SizeLat:27 for: %V2I64 = call { <2 x i64>, <2 x i1> } @llvm.umul.with.overflow.v2i64(<2 x i64> undef, <2 x i64> undef)
-; CHECK-NEXT: Cost Model: Found costs of RThru:66 CodeSize:36 Lat:52 SizeLat:52 for: %V4I64 = call { <4 x i64>, <4 x i1> } @llvm.umul.with.overflow.v4i64(<4 x i64> undef, <4 x i64> undef)
-; CHECK-NEXT: Cost Model: Found costs of RThru:132 CodeSize:70 Lat:102 SizeLat:102 for: %V8I64 = call { <8 x i64>, <8 x i1> } @llvm.umul.with.overflow.v8i64(<8 x i64> undef, <8 x i64> undef)
+; CHECK-NEXT: Cost Model: Found costs of RThru:37 CodeSize:19 Lat:27 SizeLat:27 for: %V2I64 = call { <2 x i64>, <2 x i1> } @llvm.umul.with.overflow.v2i64(<2 x i64> undef, <2 x i64> undef)
+; CHECK-NEXT: Cost Model: Found costs of RThru:74 CodeSize:36 Lat:52 SizeLat:52 for: %V4I64 = call { <4 x i64>, <4 x i1> } @llvm.umul.with.overflow.v4i64(<4 x i64> undef, <4 x i64> undef)
+; CHECK-NEXT: Cost Model: Found costs of RThru:148 CodeSize:70 Lat:102 SizeLat:102 for: %V8I64 = call { <8 x i64>, <8 x i1> } @llvm.umul.with.overflow.v8i64(<8 x i64> undef, <8 x i64> undef)
; CHECK-NEXT: Cost Model: Found costs of 2 for: %I32 = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 undef, i32 undef)
; CHECK-NEXT: Cost Model: Found costs of RThru:37 CodeSize:9 Lat:9 SizeLat:9 for: %V4I32 = call { <4 x i32>, <4 x i1> } @llvm.umul.with.overflow.v4i32(<4 x i32> undef, <4 x i32> undef)
; CHECK-NEXT: Cost Model: Found costs of RThru:74 CodeSize:16 Lat:16 SizeLat:16 for: %V8I32 = call { <8 x i32>, <8 x i1> } @llvm.umul.with.overflow.v8i32(<8 x i32> undef, <8 x i32> undef)
diff --git a/llvm/test/Analysis/CostModel/AArch64/arith.ll b/llvm/test/Analysis/CostModel/AArch64/arith.ll
index dc7a3c4ccc0e3..7e177a95fa8c7 100644
--- a/llvm/test/Analysis/CostModel/AArch64/arith.ll
+++ b/llvm/test/Analysis/CostModel/AArch64/arith.ll
@@ -132,7 +132,7 @@ define void @i128() {
; CHECK-LABEL: 'i128'
; CHECK-NEXT: Cost Model: Found costs of RThru:2 CodeSize:1 Lat:1 SizeLat:1 for: %c = add i128 undef, undef
; CHECK-NEXT: Cost Model: Found costs of RThru:2 CodeSize:1 Lat:1 SizeLat:1 for: %d = sub i128 undef, undef
-; CHECK-NEXT: Cost Model: Found costs of RThru:2 CodeSize:1 Lat:1 SizeLat:1 for: %e = mul i128 undef, undef
+; CHECK-NEXT: Cost Model: Found costs of RThru:4 CodeSize:1 Lat:1 SizeLat:1 for: %e = mul i128 undef, undef
; CHECK-NEXT: Cost Model: Found costs of RThru:2 CodeSize:1 Lat:1 SizeLat:1 for: %f = ashr i128 undef, undef
; CHECK-NEXT: Cost Model: Found costs of RThru:2 CodeSize:1 Lat:1 SizeLat:1 for: %g = lshr i128 undef, undef
; CHECK-NEXT: Cost Model: Found costs of RThru:2 CodeSize:1 Lat:1 SizeLat:1 for: %h = shl i128 undef, undef
@@ -474,7 +474,7 @@ define void @vi128() {
; CHECK-LABEL: 'vi128'
; CHECK-NEXT: Cost Model: Found costs of RThru:4 CodeSize:1 Lat:1 SizeLat:1 for: %c2 = add <2 x i128> undef, undef
; CHECK-NEXT: Cost Model: Found costs of RThru:4 CodeSize:1 Lat:1 SizeLat:1 for: %d2 = sub <2 x i128> undef, undef
-; CHECK-NEXT: Cost Model: Found costs of RThru:4 CodeSize:1 Lat:1 SizeLat:1 for: %e2 = mul <2 x i128> undef, undef
+; CHECK-NEXT: Cost Model: Found costs of RThru:8 CodeSize:1 Lat:1 SizeLat:1 for: %e2 = mul <2 x i128> undef, undef
; CHECK-NEXT: Cost Model: Found costs of RThru:4 CodeSize:1 Lat:1 SizeLat:1 for: %f2 = ashr <2 x i128> undef, undef
; CHECK-NEXT: Cost Model: Found costs of RThru:4 CodeSize:1 Lat:1 SizeLat:1 for: %g2 = lshr <2 x i128> undef, undef
; CHECK-NEXT: Cost Model: Found costs of RThru:4 CodeSize:1 Lat:1 SizeLat:1 for: %h2 = shl <2 x i128> undef, undef
diff --git a/llvm/test/Analysis/CostModel/AArch64/div.ll b/llvm/test/Analysis/CostModel/AArch64/div.ll
index 3a2358dba51b2..2c5be1acbbd7b 100644
--- a/llvm/test/Analysis/CostModel/AArch64/div.ll
+++ b/llvm/test/Analysis/CostModel/AArch64/div.ll
@@ -345,7 +345,7 @@ define void @sdiv_const() {
define void @udiv_const() {
; CHECK-LABEL: 'udiv_const'
-; CHECK-NEXT: Cost Model: Found costs of RThru:10 CodeSize:4 Lat:4 SizeLat:4 for: %I128 = udiv i128 undef, 7
+; CHECK-NEXT: Cost Model: Found costs of RThru:12 CodeSize:4 Lat:4 SizeLat:4 for: %I128 = udiv i128 undef, 7
; CHECK-NEXT: Cost Model: Found costs of 4 for: %I64 = udiv i64 undef, 7
; CHECK-NEXT: Cost Model: Found costs of RThru:32 CodeSize:4 Lat:4 SizeLat:4 for: %V2i64 = udiv <2 x i64> undef, <i64 6, i64 7>
; CHECK-NEXT: Cost Model: Found costs of RThru:64 CodeSize:4 Lat:4 SizeLat:4 for: %V4i64 = udiv <4 x i64> undef, <i64 4, i64 5, i64 6, i64 7>
@@ -462,7 +462,7 @@ define void @sdiv_uniformconst() {
define void @udiv_uniformconst() {
; CHECK-LABEL: 'udiv_uniformconst'
-; CHECK-NEXT: Cost Model: Found costs of RThru:10 CodeSize:4 Lat:4 SizeLat:4 for: %I128 = udiv i128 undef, 7
+; CHECK-NEXT: Cost Model: Found costs of RThru:12 CodeSize:4 Lat:4 SizeLat:4 for: %I128 = udiv i128 undef, 7
; CHECK-NEXT: Cost Model: Found costs of 4 for: %I64 = udiv i64 undef, 7
; CHECK-NEXT: Cost Model: Found costs of RThru:32 CodeSize:4 Lat:4 SizeLat:4 for: %V2i64 = udiv <2 x i64> undef, splat (i64 7)
; CHECK-NEXT: Cost Model: Found costs of RThru:64 CodeSize:4 Lat:4 SizeLat:4 for: %V4i64 = udiv <4 x i64> undef, splat (i64 7)
@@ -810,7 +810,7 @@ define void @sdiv_constnegpow2() {
define void @udiv_constnegpow2() {
; CHECK-LABEL: 'udiv_constnegpow2'
-; CHECK-NEXT: Cost Model: Found costs of RThru:10 CodeSize:4 Lat:4 SizeLat:4 for: %I128 = udiv i128 undef, -16
+; CHECK-NEXT: Cost Model: Found costs of RThru:12 CodeSize:4 Lat:4 SizeLat:4 for: %I128 = udiv i128 undef, -16
; CHECK-NEXT: Cost Model: Found costs of 4 for: %I64 = udiv i64 undef, -16
; CHECK-NEXT: Cost Model: Found costs of RThru:32 CodeSize:4 Lat:4 SizeLat:4 for: %V2i64 = udiv <2 x i64> undef, <i64 -8, i64 -16>
; CHECK-NEXT: Cost Model: Found costs of RThru:64 CodeSize:4 Lat:4 SizeLat:4 for: %V4i64 = udiv <4 x i64> undef, <i64 -2, i64 -4, i64 -8, i64 -16>
@@ -926,7 +926,7 @@ define void @sdiv_uniformconstnegpow2() {
define void @udiv_uniformconstnegpow2() {
; CHECK-LABEL: 'udiv_uniformconstnegpow2'
-; CHECK-NEXT: Cost Model: Found costs of RThru:10 CodeSize:4 Lat:4 SizeLat:4 for: %I128 = udiv i128 undef, -16
+; CHECK-NEXT: Cost Model: Found costs of RThru:12 CodeSize:4 Lat:4 SizeLat:4 for: %I128 = udiv i128 undef, -16
; CHECK-NEXT: Cost Model: Found costs of 4 for: %I64 = udiv i64 undef, -16
; CHECK-NEXT: Cost Model: Found costs of RThru:32 CodeSize:4 Lat:4 SizeLat:4 for: %V2i64 = udiv <2 x i64> undef, splat (i64 -16)
; CHECK-NEXT: Cost Model: Found costs of RThru:64 CodeSize:4 Lat:4 SizeLat:4 for: %V4i64 = udiv <4 x i64> undef, splat (i64 -16)
diff --git a/llvm/test/Analysis/CostModel/AArch64/rem.ll b/llvm/test/Analysis/CostModel/AArch64/rem.ll
index 2fa62f1705911..22b9e5cd545af 100644
--- a/llvm/test/Analysis/CostModel/AArch64/rem.ll
+++ b/llvm/test/Analysis/CostModel/AArch64/rem.ll
@@ -345,7 +345,7 @@ define void @srem_const() {
define void @urem_const() {
; CHECK-LABEL: 'urem_const'
-; CHECK-NEXT: Cost Model: Found costs of RThru:14 CodeSize:4 Lat:4 SizeLat:4 for: %I128 = urem i128 undef, 7
+; CHECK-NEXT: Cost Model: Found costs of RThru:18 CodeSize:4 Lat:4 SizeLat:4 for: %I128 = urem i128 undef, 7
; CHECK-NEXT: Cost Model: Found costs of RThru:6 CodeSize:4 Lat:4 SizeLat:4 for: %I64 = urem i64 undef, 7
; CHECK-NEXT: Cost Model: Found costs of RThru:47 CodeSize:4 Lat:4 SizeLat:4 for: %V2i64 = urem <2 x i64> undef, <i64 6, i64 7>
; CHECK-NEXT: Cost Model: Found costs of RThru:94 CodeSize:4 Lat:4 SizeLat:4 for: %V4i64 = urem <4 x i64> undef, <i64 4, i64 5, i64 6, i64 7>
@@ -462,7 +462,7 @@ define void @srem_uniformconst() {
define void @urem_uniformconst() {
; CHECK-LABEL: 'urem_uniformconst'
-; CHECK-NEXT: Cost Model: Found costs of RThru:14 CodeSize:4 Lat:4 SizeLat:4 for: %I128 = urem i128 undef, 7
+; CHECK-NEXT: Cost Model: Found costs of RThru:18 CodeSize:4 Lat:4 SizeLat:4 for: %I128 = urem i128 undef, 7
; CHECK-NEXT: Cost Model: Found costs of RThru:6 CodeSize:4 Lat:4 SizeLat:4 for: %I64 = urem i64 undef, 7
; CHECK-NEXT: Cost Model: Found costs of RThru:47 CodeSize:4 Lat:4 SizeLat:4 for: %V2i64 = urem <2 x i64> undef, splat (i64 7)
; CHECK-NEXT: Cost Model: Found costs of RThru:94 CodeSize:4 Lat:4 SizeLat:4 for: %V4i64 = urem <4 x i64> undef, splat (i64 7)
@@ -810,7 +810,7 @@ define void @srem_constnegpow2() {
define void @urem_constnegpow2() {
; CHECK-LABEL: 'urem_constnegpow2'
-; CHECK-NEXT: Cost Model: Found costs of RThru:14 CodeSize:4 Lat:4 SizeLat:4 for: %I128 = urem i128 undef, -16
+; CHECK-NEXT: Cost Model: Found costs of RThru:18 CodeSize:4 Lat:4 SizeLat:4 for: %I128 = urem i128 undef, -16
; CHECK-NEXT: Cost Model: Found costs of RThru:6 CodeSize:4 Lat:4 SizeLat:4 for: %I64 = urem i64 undef, -16
; CHECK-NEXT: Cost Model: Found costs of RThru:47 CodeSize:4 Lat:4 SizeLat:4 for: %V2i64 = urem <2 x i64> undef, <i64 -8, i64 -16>
; CHECK-NEXT: Cost Model: Found costs of RThru:94 CodeSize:4 Lat:4 SizeLat:4 for: %V4i64 = urem <4 x i64> undef, <i64 -2, i64 -4, i64 -8, i64 -16>
@@ -926,7 +926,7 @@ define void @srem_uniformconstnegpow2() {
define void @urem_uniformconstnegpow2() {
; CHECK-LABEL: 'urem_uniformconstnegpow2'
-; CHECK-NEXT: Cost Model: Found costs of RThru:14 CodeSize:4 Lat:4 SizeLat:4 for: %I128 = urem i128 undef, -16
+; CHECK-NEXT: Cost Model: Found costs of RThru:18 CodeSize:4 Lat:4 SizeLat:4 for: %I128 = urem i128 undef, -16
; CHECK-NEXT: Cost Model: Found costs of RThru:6 CodeSize:4 Lat:4 SizeLat:4 for: %I64 = urem i64 undef, -16
; CHECK-NEXT: Cost Model: Found costs of RThru:47 CodeSize:4 Lat:4 SizeLat:4 for: %V2i64 = urem <2 x i64> undef, splat (i64 -16)
; CHECK-NEXT: Cost Model: Found costs of RThru:94 CodeSize:4 Lat:4 SizeLat:4 for: %V4i64 = urem <4 x i64> undef, splat (i64 -16)
More information about the llvm-commits
mailing list