OSDN Git Service

[AArch64] Small fix for getIntImmCost
authorAdhemerval Zanella <adhemerval.zanella@linaro.org>
Mon, 18 Mar 2019 18:50:58 +0000 (18:50 +0000)
committerAdhemerval Zanella <adhemerval.zanella@linaro.org>
Mon, 18 Mar 2019 18:50:58 +0000 (18:50 +0000)
It uses the generic AArch64_IMM::expandMOVImm to get the correct
number of instruction used in immediate materialization.

Reviewers: efriedma

Differential Revision: https://reviews.llvm.org/D58461

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@356391 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/AArch64/AArch64TargetTransformInfo.cpp
test/CodeGen/AArch64/immcost.ll [new file with mode: 0644]

index 50624a8..77cc6cf 100644 (file)
@@ -6,6 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "AArch64ExpandImm.h"
 #include "AArch64TargetTransformInfo.h"
 #include "MCTargetDesc/AArch64AddressingModes.h"
 #include "llvm/Analysis/LoopInfo.h"
@@ -49,8 +50,9 @@ int AArch64TTIImpl::getIntImmCost(int64_t Val) {
     Val = ~Val;
 
   // Calculate how many moves we will need to materialize this constant.
-  unsigned LZ = countLeadingZeros((uint64_t)Val);
-  return (64 - LZ + 15) / 16;
+  SmallVector<AArch64_IMM::ImmInsnModel, 4> Insn;
+  AArch64_IMM::expandMOVImm(Val, 64, Insn);
+  return Insn.size();
 }
 
 /// Calculate the cost of materializing the given constant.
diff --git a/test/CodeGen/AArch64/immcost.ll b/test/CodeGen/AArch64/immcost.ll
new file mode 100644 (file)
index 0000000..811fc72
--- /dev/null
@@ -0,0 +1,106 @@
+; RUN: llc -mtriple=aarch64-none-linux-gnu %s -o - -O1 -debug-only=consthoist 2>&1 | FileCheck %s
+; REQUIRES: asserts
+
+declare void @g(i64)
+
+; Single ORR.
+; CHECK:     Function: f1
+; CHECK-NOT: Collect constant
+define void @f1(i1 %cond) {
+entry:
+  call void @g(i64 -3)
+  br i1 %cond, label %true, label %ret
+
+true:
+  call void @g(i64 -3)
+  br label %ret
+
+ret:
+  ret void
+}
+
+; Constant is 0xBEEF000000000000, single MOVZ with shift.
+; CHECK:     Function: f2
+; CHECK-NOT: Collect constant
+define void @f2(i1 %cond, i64 %p, i64 %q) {
+entry:
+  %a = and i64 %p, 13758215386640154624
+  call void @g(i64 %a)
+  br i1 %cond, label %true, label %ret
+
+true:
+  %b = and i64 %q, 13758215386640154624
+  call void @g(i64 %b)
+  br label %ret
+
+ret:
+  ret void
+}
+
+; CHECK:     Function: f3
+; CHECK:     Collect constant i64 4294967103 from   %a = and i64 %p, 4294967103 with cost 2
+define void @f3(i1 %cond, i64 %p, i64 %q) {
+entry:
+  %a = and i64 %p, 4294967103
+  call void @g(i64 %a)
+  br i1 %cond, label %true, label %ret
+
+true:
+  %b = and i64 %q, 4294967103
+  call void @g(i64 %b)
+  br label %ret
+
+ret:
+  ret void
+}
+
+; CHECK:     Function: f4
+; Collect constant i64 -4688528683866062848 from   %a = and i64 %p, -4688528683866062848 with cost 2
+define void @f4(i1 %cond, i64 %p, i64 %q) {
+entry:
+  %a = and i64 %p, 13758215389843488768
+  call void @g(i64 %a)
+  br i1 %cond, label %true, label %ret
+
+true:
+  %b = and i64 %q, 13758215389843488768
+  call void @g(i64 %b)
+  br label %ret
+
+ret:
+  ret void
+}
+
+; CHECK:     Function: f5
+; Collect constant i64 88994925642865 from   %a = and i64 %p, 88994925642865 with cost 3
+define void @f5(i1 %cond, i64 %p, i64 %q) {
+entry:
+  %a = and i64 %p, 88994925642865
+  call void @g(i64 %a)
+  br i1 %cond, label %true, label %ret
+
+true:
+  %b = and i64 %q, 88994925642865
+  call void @g(i64 %b)
+  br label %ret
+
+ret:
+  ret void
+}
+
+; CHECK:     Function: f6
+; Collect constant i64 -4688439692143754127 from   %b = and i64 %q, -4688439692143754127 with cost 4
+define void @f6(i1 %cond, i64 %p, i64 %q) {
+entry:
+  %a = and i64 %p, 13758304381565797489
+  call void @g(i64 %a)
+  br i1 %cond, label %true, label %ret
+
+true:
+  %b = and i64 %q, 13758304381565797489
+  call void @g(i64 %b)
+  br label %ret
+
+ret:
+  ret void
+}