[llvm] 4ff4e7e - [CostModel] Use cost of target trunc type when only it is the only use of a non-register sized load
Andrew Litteken via llvm-commits
llvm-commits at lists.llvm.org
Wed Jan 12 16:04:23 PST 2022
Author: Andrew Litteken
Date: 2022-01-12T18:03:50-06:00
New Revision: 4ff4e7ea3033e8a5f21c5cbc4028255c0b6bae9f
URL: https://github.com/llvm/llvm-project/commit/4ff4e7ea3033e8a5f21c5cbc4028255c0b6bae9f
DIFF: https://github.com/llvm/llvm-project/commit/4ff4e7ea3033e8a5f21c5cbc4028255c0b6bae9f.diff
LOG: [CostModel] Use cost of target trunc type when only it is the only use of a non-register sized load
The code size cost model for most targets uses the legalization cost for the type of the pointer of a load. If this load is followed directly by a trunc instruction, and is the only use of the result of the load, only one instruction is generated in the target assembly language. This adds a check for this case, and uses the target type of the trunc instruction if so.
This did not show any changes in CTMark code size benchmarks.
Reviewers: paquette, samparker, dmgreen
Differential Revision: https://reviews.llvm.org/D109388
Added:
llvm/test/Analysis/CostModel/AArch64/load-to-trunc.ll
llvm/test/Analysis/CostModel/AMDGPU/load-to-trunc.ll
llvm/test/Analysis/CostModel/ARM/load-to-trunc.ll
llvm/test/Analysis/CostModel/PowerPC/load-to-trunc.ll
llvm/test/Analysis/CostModel/RISCV/load-to-trunc.ll
llvm/test/Analysis/CostModel/SystemZ/load-to-trunc.ll
llvm/test/Analysis/CostModel/X86/load-to-trunc.ll
Modified:
llvm/include/llvm/Analysis/TargetTransformInfoImpl.h
Removed:
################################################################################
diff --git a/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h b/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h
index 2c70780dd4f43..72a7d3cbdd305 100644
--- a/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h
+++ b/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h
@@ -1061,7 +1061,20 @@ class TargetTransformInfoImplCRTPBase : public TargetTransformInfoImplBase {
}
case Instruction::Load: {
auto *LI = cast<LoadInst>(U);
- return TargetTTI->getMemoryOpCost(Opcode, U->getType(), LI->getAlign(),
+ Type *LoadType = U->getType();
+ // If there is a non-register sized type, the cost estimation may expand
+ // it to be several instructions to load into multiple registers on the
+ // target. But, if the only use of the load is a trunc instruction to a
+ // register sized type, the instruction selector can combine these
+ // instructions to be a single load. So, in this case, we use the
+ // destination type of the trunc instruction rather than the load to
+ // accurately estimate the cost of this load instruction.
+ if (CostKind == TTI::TCK_CodeSize && LI->hasOneUse() &&
+ !LoadType->isVectorTy()) {
+ if (const TruncInst *TI = dyn_cast<TruncInst>(*LI->user_begin()))
+ LoadType = TI->getDestTy();
+ }
+ return TargetTTI->getMemoryOpCost(Opcode, LoadType, LI->getAlign(),
LI->getPointerAddressSpace(),
CostKind, I);
}
diff --git a/llvm/test/Analysis/CostModel/AArch64/load-to-trunc.ll b/llvm/test/Analysis/CostModel/AArch64/load-to-trunc.ll
new file mode 100644
index 0000000000000..83c839161c4d7
--- /dev/null
+++ b/llvm/test/Analysis/CostModel/AArch64/load-to-trunc.ll
@@ -0,0 +1,27 @@
+; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py
+; Check memory cost model action for a load of an unusually sized integer
+; follow by and a trunc to a register sized integer gives a cost of 1 rather
+; than the expanded cost if it is not.
+
+; RUN: opt -cost-model -cost-kind=code-size -analyze -mtriple=aarch64--linux-gnu < %s | FileCheck %s --check-prefix=CHECK
+
+; Check that cost is 1 for unusual load to register sized load.
+define i32 @loadUnusualIntegerWithTrunc(i128* %ptr) {
+; CHECK-LABEL: 'loadUnusualIntegerWithTrunc'
+; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %out = load i128, i128* %ptr, align 4
+; CHECK-NEXT: Cost Model: Found an estimated cost of 0 for instruction: %trunc = trunc i128 %out to i32
+; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret i32 %trunc
+;
+ %out = load i128, i128* %ptr
+ %trunc = trunc i128 %out to i32
+ ret i32 %trunc
+}
+
+define i128 @loadUnusualInteger(i128* %ptr) {
+; CHECK-LABEL: 'loadUnusualInteger'
+; CHECK-NEXT: Cost Model: Found an estimated cost of 2 for instruction: %out = load i128, i128* %ptr, align 4
+; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret i128 %out
+;
+ %out = load i128, i128* %ptr
+ ret i128 %out
+}
diff --git a/llvm/test/Analysis/CostModel/AMDGPU/load-to-trunc.ll b/llvm/test/Analysis/CostModel/AMDGPU/load-to-trunc.ll
new file mode 100644
index 0000000000000..e72368d4dd503
--- /dev/null
+++ b/llvm/test/Analysis/CostModel/AMDGPU/load-to-trunc.ll
@@ -0,0 +1,27 @@
+; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py
+; Check memory cost model action for a load of an unusually sized integer
+; follow by and a trunc to a register sized integer gives a cost of 1 rather
+; than the expanded cost if it is not.
+
+; RUN: opt -cost-model -cost-kind=code-size -analyze -mtriple=amdgcn-unknown-amdhsa < %s | FileCheck %s --check-prefix=CHECK
+
+; Check that cost is 1 for unusual load to register sized load.
+define i32 @loadUnusualIntegerWithTrunc(i128* %ptr) {
+; CHECK-LABEL: 'loadUnusualIntegerWithTrunc'
+; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %out = load i128, i128* %ptr, align 4
+; CHECK-NEXT: Cost Model: Found an estimated cost of 0 for instruction: %trunc = trunc i128 %out to i32
+; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret i32 %trunc
+;
+ %out = load i128, i128* %ptr
+ %trunc = trunc i128 %out to i32
+ ret i32 %trunc
+}
+
+define i128 @loadUnusualInteger(i128* %ptr) {
+; CHECK-LABEL: 'loadUnusualInteger'
+; CHECK-NEXT: Cost Model: Found an estimated cost of 2 for instruction: %out = load i128, i128* %ptr, align 4
+; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret i128 %out
+;
+ %out = load i128, i128* %ptr
+ ret i128 %out
+}
diff --git a/llvm/test/Analysis/CostModel/ARM/load-to-trunc.ll b/llvm/test/Analysis/CostModel/ARM/load-to-trunc.ll
new file mode 100644
index 0000000000000..7d434f7d90429
--- /dev/null
+++ b/llvm/test/Analysis/CostModel/ARM/load-to-trunc.ll
@@ -0,0 +1,28 @@
+; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py
+; Check memory cost model action for a load of an unusually sized integer
+; follow by and a trunc to a register sized integer gives a cost of 1 rather
+; than the expanded cost if it is not. Currently, this target does not have
+; that expansion.
+
+; RUN: opt -cost-model -cost-kind=code-size -analyze -mtriple=armv8r-none-eabi < %s | FileCheck %s --check-prefix=CHECK
+
+; Check that cost is 1 for unusual load to register sized load.
+define i32 @loadUnusualIntegerWithTrunc(i128* %ptr) {
+; CHECK-LABEL: 'loadUnusualIntegerWithTrunc'
+; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %out = load i128, i128* %ptr, align 4
+; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %trunc = trunc i128 %out to i32
+; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret i32 %trunc
+;
+ %out = load i128, i128* %ptr
+ %trunc = trunc i128 %out to i32
+ ret i32 %trunc
+}
+
+define i128 @loadUnusualInteger(i128* %ptr) {
+; CHECK-LABEL: 'loadUnusualInteger'
+; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %out = load i128, i128* %ptr, align 4
+; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret i128 %out
+;
+ %out = load i128, i128* %ptr
+ ret i128 %out
+}
diff --git a/llvm/test/Analysis/CostModel/PowerPC/load-to-trunc.ll b/llvm/test/Analysis/CostModel/PowerPC/load-to-trunc.ll
new file mode 100644
index 0000000000000..d769124386ce7
--- /dev/null
+++ b/llvm/test/Analysis/CostModel/PowerPC/load-to-trunc.ll
@@ -0,0 +1,26 @@
+; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py
+; Check memory cost model action for a load of an unusually sized integer
+; follow by and a trunc to a register sized integer gives a cost of 1 rather
+; than the expanded cost if it is not.
+; RUN: opt -cost-model -cost-kind=code-size -analyze -mtriple=powerpc64-unknown-linux-gnu < %s | FileCheck %s --check-prefix=CHECK
+
+; Check that cost is 1 for unusual load to register sized load.
+define i32 @loadUnusualIntegerWithTrunc(i128* %ptr) {
+; CHECK-LABEL: 'loadUnusualIntegerWithTrunc'
+; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %out = load i128, i128* %ptr, align 4
+; CHECK-NEXT: Cost Model: Found an estimated cost of 0 for instruction: %trunc = trunc i128 %out to i32
+; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret i32 %trunc
+;
+ %out = load i128, i128* %ptr
+ %trunc = trunc i128 %out to i32
+ ret i32 %trunc
+}
+
+define i128 @loadUnusualInteger(i128* %ptr) {
+; CHECK-LABEL: 'loadUnusualInteger'
+; CHECK-NEXT: Cost Model: Found an estimated cost of 2 for instruction: %out = load i128, i128* %ptr, align 4
+; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret i128 %out
+;
+ %out = load i128, i128* %ptr
+ ret i128 %out
+}
diff --git a/llvm/test/Analysis/CostModel/RISCV/load-to-trunc.ll b/llvm/test/Analysis/CostModel/RISCV/load-to-trunc.ll
new file mode 100644
index 0000000000000..b742cb38c6690
--- /dev/null
+++ b/llvm/test/Analysis/CostModel/RISCV/load-to-trunc.ll
@@ -0,0 +1,27 @@
+; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py
+; Check memory cost model action for a load of an unusually sized integer
+; follow by and a trunc to a register sized integer gives a cost of 1 rather
+; than the expanded cost if it is not.
+
+; RUN: opt -cost-model -cost-kind=code-size -analyze -mtriple=riscv64 < %s | FileCheck %s --check-prefix=CHECK
+
+; Check that cost is 1 for unusual load to register sized load.
+define i32 @loadUnusualIntegerWithTrunc(i128* %ptr) {
+; CHECK-LABEL: 'loadUnusualIntegerWithTrunc'
+; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %out = load i128, i128* %ptr, align 4
+; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %trunc = trunc i128 %out to i32
+; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret i32 %trunc
+;
+ %out = load i128, i128* %ptr
+ %trunc = trunc i128 %out to i32
+ ret i32 %trunc
+}
+
+define i128 @loadUnusualInteger(i128* %ptr) {
+; CHECK-LABEL: 'loadUnusualInteger'
+; CHECK-NEXT: Cost Model: Found an estimated cost of 2 for instruction: %out = load i128, i128* %ptr, align 4
+; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret i128 %out
+;
+ %out = load i128, i128* %ptr
+ ret i128 %out
+}
diff --git a/llvm/test/Analysis/CostModel/SystemZ/load-to-trunc.ll b/llvm/test/Analysis/CostModel/SystemZ/load-to-trunc.ll
new file mode 100644
index 0000000000000..b192b63181a0e
--- /dev/null
+++ b/llvm/test/Analysis/CostModel/SystemZ/load-to-trunc.ll
@@ -0,0 +1,27 @@
+; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py
+; Check memory cost model action for a load of an unusually sized integer
+; follow by and a trunc to a register sized integer gives a cost of 1 rather
+; than the expanded cost if it is not. This target does not currently perform
+; the expansion in the cost modelling.
+; RUN: opt -cost-model -cost-kind=code-size -analyze -mtriple=systemz-unknown < %s | FileCheck %s --check-prefix=CHECK
+
+; Check that cost is 1 for unusual load to register sized load.
+define i32 @loadUnusualIntegerWithTrunc(i128* %ptr) {
+; CHECK-LABEL: 'loadUnusualIntegerWithTrunc'
+; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %out = load i128, i128* %ptr, align 4
+; CHECK-NEXT: Cost Model: Found an estimated cost of 0 for instruction: %trunc = trunc i128 %out to i32
+; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret i32 %trunc
+;
+ %out = load i128, i128* %ptr
+ %trunc = trunc i128 %out to i32
+ ret i32 %trunc
+}
+
+define i128 @loadUnusualInteger(i128* %ptr) {
+; CHECK-LABEL: 'loadUnusualInteger'
+; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %out = load i128, i128* %ptr, align 4
+; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret i128 %out
+;
+ %out = load i128, i128* %ptr
+ ret i128 %out
+}
diff --git a/llvm/test/Analysis/CostModel/X86/load-to-trunc.ll b/llvm/test/Analysis/CostModel/X86/load-to-trunc.ll
new file mode 100644
index 0000000000000..4b8d2a1621657
--- /dev/null
+++ b/llvm/test/Analysis/CostModel/X86/load-to-trunc.ll
@@ -0,0 +1,28 @@
+; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py
+; Check memory cost model action for a load of an unusually sized integer
+; follow by and a trunc to a register sized integer gives a cost of 1 rather
+; than the expanded cost. Currently the x86 code size cost model does not use
+; the expanded cost and only assigns a cost of 1 to each load.
+
+; RUN: opt -cost-model -cost-kind=code-size -analyze -mtriple=x86_64--linux-gnu < %s | FileCheck %s --check-prefix=CHECK
+
+; Check that cost is 1 for unusual load to register sized load.
+define i32 @loadUnusualIntegerWithTrunc(i128* %ptr) {
+; CHECK-LABEL: 'loadUnusualIntegerWithTrunc'
+; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %out = load i128, i128* %ptr, align 4
+; CHECK-NEXT: Cost Model: Found an estimated cost of 0 for instruction: %trunc = trunc i128 %out to i32
+; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret i32 %trunc
+;
+ %out = load i128, i128* %ptr
+ %trunc = trunc i128 %out to i32
+ ret i32 %trunc
+}
+
+define i128 @loadUnusualInteger(i128* %ptr) {
+; CHECK-LABEL: 'loadUnusualInteger'
+; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %out = load i128, i128* %ptr, align 4
+; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret i128 %out
+;
+ %out = load i128, i128* %ptr
+ ret i128 %out
+}
More information about the llvm-commits
mailing list