diff --git a/llvm/lib/Transforms/Scalar/ConstantHoisting.cpp b/llvm/lib/Transforms/Scalar/ConstantHoisting.cpp --- a/llvm/lib/Transforms/Scalar/ConstantHoisting.cpp +++ b/llvm/lib/Transforms/Scalar/ConstantHoisting.cpp @@ -491,7 +491,7 @@ // `TargetTransformInfo::getIntImmCost`) for instructions which only take // constant variables is lower than `TargetTransformInfo::TCC_Basic`. So // it's safe for us to collect constant candidates from all IntrinsicInsts. - if (canReplaceOperandWithVariable(Inst, Idx) || isa(Inst)) { + if (canReplaceOperandWithVariable(Inst, Idx)) { collectConstantCandidates(ConstCandMap, Inst, Idx); } } // end of for all operands diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp --- a/llvm/lib/Transforms/Utils/Local.cpp +++ b/llvm/lib/Transforms/Utils/Local.cpp @@ -2917,21 +2917,27 @@ default: return true; case Instruction::Call: - case Instruction::Invoke: + case Instruction::Invoke: { // Can't handle inline asm. Skip it. if (isa(ImmutableCallSite(I).getCalledValue())) return false; - // Many arithmetic intrinsics have no issue taking a - // variable, however it's hard to distingish these from - // specials such as @llvm.frameaddress that require a constant. - if (isa(I)) - return false; + + ImmutableCallSite CS(I); + + if (OpIdx < CS.getNumArgOperands()) { + // Intrinsics and calls that require a constant argument have that + // parameter annotated with ImmArg. + if (CS.paramHasAttr(OpIdx, Attribute::ImmArg)) + return false; + } // Constant bundle operands may need to retain their constant-ness for // correctness. - if (ImmutableCallSite(I).isBundleOperand(OpIdx)) + if (CS.isBundleOperand(OpIdx)) return false; + return true; + } case Instruction::ShuffleVector: // Shufflevector masks are constant. return OpIdx != 2;