diff --git a/lib/Target/ARM64/ARM64TargetTransformInfo.cpp b/lib/Target/ARM64/ARM64TargetTransformInfo.cpp index f12d1be81a1..cc8cc806ec7 100644 --- a/lib/Target/ARM64/ARM64TargetTransformInfo.cpp +++ b/lib/Target/ARM64/ARM64TargetTransformInfo.cpp @@ -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: diff --git a/test/Transforms/ConstantHoisting/ARM64/large-immediate.ll b/test/Transforms/ConstantHoisting/ARM64/large-immediate.ll index 0965a45ea6e..92ad6ee70de 100644 --- a/test/Transforms/ConstantHoisting/ARM64/large-immediate.ll +++ b/test/Transforms/ConstantHoisting/ARM64/large-immediate.ll @@ -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 +}