[ARM64] Fix the cost model for cheap large constants.
authorJuergen Ributzka <juergen@apple.com>
Sat, 12 Apr 2014 02:36:28 +0000 (02:36 +0000)
committerJuergen Ributzka <juergen@apple.com>
Sat, 12 Apr 2014 02:36:28 +0000 (02:36 +0000)
Originally the cost model would give up for large constants and just return the
maximum cost. This is not what we want for constant hoisting, because some of
these constants are large in bitwidth, but are still cheap to materialize.

This commit fixes the cost model to either return TCC_Free if the cost cannot be
determined, or accurately calculate the cost even for large constants
(bitwidth > 128).

This fixes <rdar://problem/16591573>.

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

lib/Target/ARM64/ARM64TargetTransformInfo.cpp
test/Transforms/ConstantHoisting/ARM64/large-immediate.ll

index f12d1be81a16c9855e96cf110f02e5d5f69fee7d..cc8cc806ec7045dda11c46328aeddd1092d28001 100644 (file)
@@ -154,7 +154,7 @@ unsigned ARM64TTI::getIntImmCost(const APInt &Imm, Type *Ty) const {
   assert(Ty->isIntegerTy());
 
   unsigned BitSize = Ty->getPrimitiveSizeInBits();
-  if (BitSize == 0 || BitSize > 128)
+  if (BitSize == 0)
     return ~0U;
 
   // Sign-extend all constants to a multiple of 64-bit.
@@ -179,8 +179,10 @@ unsigned ARM64TTI::getIntImmCost(unsigned Opcode, unsigned Idx,
   assert(Ty->isIntegerTy());
 
   unsigned BitSize = Ty->getPrimitiveSizeInBits();
-  if (BitSize == 0 || BitSize > 128)
-    return ~0U;
+  // There is no cost model for constants with a bit size of 0. Return TCC_Free
+  // here, so that constant hoisting will ignore this constant.
+  if (BitSize == 0)
+    return TCC_Free;
 
   unsigned ImmIdx = ~0U;
   switch (Opcode) {
@@ -238,8 +240,10 @@ unsigned ARM64TTI::getIntImmCost(Intrinsic::ID IID, unsigned Idx,
   assert(Ty->isIntegerTy());
 
   unsigned BitSize = Ty->getPrimitiveSizeInBits();
-  if (BitSize == 0 || BitSize > 128)
-    return ~0U;
+  // There is no cost model for constants with a bit size of 0. Return TCC_Free
+  // here, so that constant hoisting will ignore this constant.
+  if (BitSize == 0)
+    return TCC_Free;
 
   switch (IID) {
   default:
index 0965a45ea6ed278215c0c86b0d20a99124b998c1..92ad6ee70de78374dcf3626c73fde76013827f77 100644 (file)
@@ -8,3 +8,11 @@ define i128 @test1(i128 %a) nounwind {
   ret i128 %2
 }
 
+; Check that we don't hoist large, but cheap constants
+define i512 @test2(i512 %a) nounwind {
+; CHECK-LABEL: test2
+; CHECK-NOT: %const = bitcast i512 7 to i512
+  %1 = and i512 %a, 7
+  %2 = or i512 %1, 7
+  ret i512 %2
+}