[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