diff --git a/lib/Target/ARM64/ARM64TargetTransformInfo.cpp b/lib/Target/ARM64/ARM64TargetTransformInfo.cpp index cc8cc806ec7..372900e99fe 100644 --- a/lib/Target/ARM64/ARM64TargetTransformInfo.cpp +++ b/lib/Target/ARM64/ARM64TargetTransformInfo.cpp @@ -203,15 +203,19 @@ unsigned ARM64TTI::getIntImmCost(unsigned Opcode, unsigned Idx, case Instruction::SDiv: case Instruction::URem: case Instruction::SRem: - case Instruction::Shl: - case Instruction::LShr: - case Instruction::AShr: case Instruction::And: case Instruction::Or: case Instruction::Xor: case Instruction::ICmp: ImmIdx = 1; break; + // Always return TCC_Free for the shift value of a shift instruction. + case Instruction::Shl: + case Instruction::LShr: + case Instruction::AShr: + if (Idx == 1) + return TCC_Free; + break; case Instruction::Trunc: case Instruction::ZExt: case Instruction::SExt: diff --git a/test/Transforms/ConstantHoisting/ARM64/large-immediate.ll b/test/Transforms/ConstantHoisting/ARM64/large-immediate.ll index 92ad6ee70de..575be791d9b 100644 --- a/test/Transforms/ConstantHoisting/ARM64/large-immediate.ll +++ b/test/Transforms/ConstantHoisting/ARM64/large-immediate.ll @@ -16,3 +16,12 @@ define i512 @test2(i512 %a) nounwind { %2 = or i512 %1, 7 ret i512 %2 } + +; Check that we don't hoist the shift value of a shift instruction. +define i512 @test3(i512 %a) nounwind { +; CHECK-LABEL: test3 +; CHECK-NOT: %const = bitcast i512 504 to i512 + %1 = shl i512 %a, 504 + %2 = ashr i512 %1, 504 + ret i512 %2 +}