Index: llvm/trunk/include/llvm/Transforms/Utils/Local.h =================================================================== --- llvm/trunk/include/llvm/Transforms/Utils/Local.h +++ llvm/trunk/include/llvm/Transforms/Utils/Local.h @@ -393,6 +393,10 @@ /// Unknown metadata is removed. void combineMetadataForCSE(Instruction *K, const Instruction *J); +/// Patch the replacement so that it is not more restrictive than the value +/// being replaced. +void patchReplacementInstruction(Instruction *I, Value *Repl); + // Replace each use of 'From' with 'To', if that use does not belong to basic // block where 'From' is defined. Returns the number of replacements made. unsigned replaceNonLocalUsesWith(Instruction *From, Value *To); Index: llvm/trunk/lib/Transforms/Scalar/GVN.cpp =================================================================== --- llvm/trunk/lib/Transforms/Scalar/GVN.cpp +++ llvm/trunk/lib/Transforms/Scalar/GVN.cpp @@ -1444,37 +1444,6 @@ return Changed; } -static void patchReplacementInstruction(Instruction *I, Value *Repl) { - auto *ReplInst = dyn_cast(Repl); - if (!ReplInst) - return; - - // Patch the replacement so that it is not more restrictive than the value - // being replaced. - // Note that if 'I' is a load being replaced by some operation, - // for example, by an arithmetic operation, then andIRFlags() - // would just erase all math flags from the original arithmetic - // operation, which is clearly not wanted and not needed. - if (!isa(I)) - ReplInst->andIRFlags(I); - - // FIXME: If both the original and replacement value are part of the - // same control-flow region (meaning that the execution of one - // guarantees the execution of the other), then we can combine the - // noalias scopes here and do better than the general conservative - // answer used in combineMetadata(). - - // In general, GVN unifies expressions over different control-flow - // regions, and so we need a conservative combination of the noalias - // scopes. - static const unsigned KnownIDs[] = { - LLVMContext::MD_tbaa, LLVMContext::MD_alias_scope, - LLVMContext::MD_noalias, LLVMContext::MD_range, - LLVMContext::MD_fpmath, LLVMContext::MD_invariant_load, - LLVMContext::MD_invariant_group}; - combineMetadata(ReplInst, I, KnownIDs); -} - static void patchAndReplaceAllUsesWith(Instruction *I, Value *Repl) { patchReplacementInstruction(I, Repl); I->replaceAllUsesWith(Repl); Index: llvm/trunk/lib/Transforms/Scalar/NewGVN.cpp =================================================================== --- llvm/trunk/lib/Transforms/Scalar/NewGVN.cpp +++ llvm/trunk/lib/Transforms/Scalar/NewGVN.cpp @@ -3697,37 +3697,6 @@ } } -static void patchReplacementInstruction(Instruction *I, Value *Repl) { - auto *ReplInst = dyn_cast(Repl); - if (!ReplInst) - return; - - // Patch the replacement so that it is not more restrictive than the value - // being replaced. - // Note that if 'I' is a load being replaced by some operation, - // for example, by an arithmetic operation, then andIRFlags() - // would just erase all math flags from the original arithmetic - // operation, which is clearly not wanted and not needed. - if (!isa(I)) - ReplInst->andIRFlags(I); - - // FIXME: If both the original and replacement value are part of the - // same control-flow region (meaning that the execution of one - // guarantees the execution of the other), then we can combine the - // noalias scopes here and do better than the general conservative - // answer used in combineMetadata(). - - // In general, GVN unifies expressions over different control-flow - // regions, and so we need a conservative combination of the noalias - // scopes. - static const unsigned KnownIDs[] = { - LLVMContext::MD_tbaa, LLVMContext::MD_alias_scope, - LLVMContext::MD_noalias, LLVMContext::MD_range, - LLVMContext::MD_fpmath, LLVMContext::MD_invariant_load, - LLVMContext::MD_invariant_group}; - combineMetadata(ReplInst, I, KnownIDs); -} - static void patchAndReplaceAllUsesWith(Instruction *I, Value *Repl) { patchReplacementInstruction(I, Repl); I->replaceAllUsesWith(Repl); Index: llvm/trunk/lib/Transforms/Utils/Local.cpp =================================================================== --- llvm/trunk/lib/Transforms/Utils/Local.cpp +++ llvm/trunk/lib/Transforms/Utils/Local.cpp @@ -2354,6 +2354,37 @@ combineMetadata(K, J, KnownIDs); } +void llvm::patchReplacementInstruction(Instruction *I, Value *Repl) { + auto *ReplInst = dyn_cast(Repl); + if (!ReplInst) + return; + + // Patch the replacement so that it is not more restrictive than the value + // being replaced. + // Note that if 'I' is a load being replaced by some operation, + // for example, by an arithmetic operation, then andIRFlags() + // would just erase all math flags from the original arithmetic + // operation, which is clearly not wanted and not needed. + if (!isa(I)) + ReplInst->andIRFlags(I); + + // FIXME: If both the original and replacement value are part of the + // same control-flow region (meaning that the execution of one + // guarantees the execution of the other), then we can combine the + // noalias scopes here and do better than the general conservative + // answer used in combineMetadata(). + + // In general, GVN unifies expressions over different control-flow + // regions, and so we need a conservative combination of the noalias + // scopes. + static const unsigned KnownIDs[] = { + LLVMContext::MD_tbaa, LLVMContext::MD_alias_scope, + LLVMContext::MD_noalias, LLVMContext::MD_range, + LLVMContext::MD_fpmath, LLVMContext::MD_invariant_load, + LLVMContext::MD_invariant_group}; + combineMetadata(ReplInst, I, KnownIDs); +} + template static unsigned replaceDominatedUsesWith(Value *From, Value *To, const RootType &Root,