Index: include/llvm/IR/Function.h =================================================================== --- include/llvm/IR/Function.h +++ include/llvm/IR/Function.h @@ -149,6 +149,10 @@ /// from Value::setName() whenever the name of this function changes. void recalculateIntrinsicID(); + /// Returns the intrinsic ID from its name, or Intrinsic::not_intrinsic if the + /// name does not match any intrinsic. + static Intrinsic::ID lookupIntrinsicID(StringRef ValName); + /// getCallingConv()/setCallingConv(CC) - These method get and set the /// calling convention of this function. The enum values for the known /// calling conventions are defined in CallingConv.h. Index: lib/IR/Function.cpp =================================================================== --- lib/IR/Function.cpp +++ lib/IR/Function.cpp @@ -416,9 +416,7 @@ /// \brief This does the actual lookup of an intrinsic ID which /// matches the given function name. -static Intrinsic::ID lookupIntrinsicID(const ValueName *ValName) { - StringRef Name = ValName->getKey(); - +Intrinsic::ID Function::lookupIntrinsicID(StringRef Name) { ArrayRef NameTable(&IntrinsicNameTable[1], std::end(IntrinsicNameTable)); int Idx = Intrinsic::lookupLLVMIntrinsicByName(NameTable, Name); @@ -438,7 +436,7 @@ IntID = Intrinsic::not_intrinsic; return; } - IntID = lookupIntrinsicID(ValName); + IntID = lookupIntrinsicID(ValName->getKey()); } /// Returns a stable mangling for the type specified for use in the name Index: lib/Transforms/Scalar/LoopIdiomRecognize.cpp =================================================================== --- lib/Transforms/Scalar/LoopIdiomRecognize.cpp +++ lib/Transforms/Scalar/LoopIdiomRecognize.cpp @@ -50,6 +50,7 @@ #include "llvm/IR/Dominators.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/IntrinsicInst.h" +#include "llvm/IR/Intrinsics.h" #include "llvm/IR/Module.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" @@ -769,6 +770,10 @@ Value *MSP = M->getOrInsertFunction("memset_pattern16", Builder.getVoidTy(), Int8PtrTy, Int8PtrTy, IntPtr, (void *)nullptr); + // memset_pattern is not an intrinsic, so it won't automatically gets the + // right set of attributes. Let's manually pulled the same ones as memset + cast(MSP)->setAttributes(Intrinsic::getAttributes( + M->getContext(), Function::lookupIntrinsicID("llvm.memset."))); // Otherwise we should form a memset_pattern16. PatternValue is known to be // an constant array of 16-bytes. Plop the value into a mergable global. Index: test/Transforms/LoopIdiom/basic.ll =================================================================== --- test/Transforms/LoopIdiom/basic.ll +++ test/Transforms/LoopIdiom/basic.ll @@ -564,3 +564,8 @@ ; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* %X, i8 0, i64 10000, i32 1, i1 false) ; CHECK: ret void } + + +; Validate that "memset_pattern" has inherited attributed from memset +; CHECK-LABEL: declare void @memset_pattern16(i8* nocapture, i8*, i64) # +