diff --git a/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.cpp b/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.cpp --- a/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.cpp +++ b/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.cpp @@ -71,7 +71,13 @@ case Instruction::Add: case Instruction::Or: case Instruction::Xor: + Takes12BitImm = true; + break; case Instruction::Mul: + // Negated power of 2 is a shift and a negate. + if (Imm.isNegatedPowerOf2()) + return TTI::TCC_Free; + // FIXME: There is no MULI instruction. Takes12BitImm = true; break; case Instruction::Sub: diff --git a/llvm/test/Transforms/ConstantHoisting/RISCV/immediates.ll b/llvm/test/Transforms/ConstantHoisting/RISCV/immediates.ll --- a/llvm/test/Transforms/ConstantHoisting/RISCV/immediates.ll +++ b/llvm/test/Transforms/ConstantHoisting/RISCV/immediates.ll @@ -72,3 +72,12 @@ %2 = and i64 %1, 4294967295 ret i64 %2 } + +; Check that we don't hoist mul with negated power of 2. +define i64 @test9(i64 %a) nounwind { +; CHECK-LABEL: test9 +; CHECK: mul i64 %a, -4294967296 + %1 = mul i64 %a, -4294967296 + %2 = mul i64 %1, -4294967296 + ret i64 %2 +}